Tree Random Hierarchy with KnockoutJS

A demonstration of the Ignite UI Tree hierarchy capabilities through free adding of nodes at any place to the underlying observable source.

by damyanpetev

HTML

<script src="http://cdn-na.infragistics.com/jquery/20131/latest/js/infragistics.loader.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js"></script>
<script src="http://www.infragistics.com/SamplesBrowser/SamplesCommon/jQuery/Common/Scripts/external/knockout.mapping-latest.js"></script>
 <div id="tree" data-bind="igTree: {
            singleBranchExpand: true,
            dataSourceType: 'json',
            dataSource: data,
            bindings: {
                textKey: 'Text',
                childDataProperty: 'Nodes'
            }
        }"></div>
<button id="addNode">Add Node</button>

JavaScript

data = {"data": [{
    "Text": "Food",
        "Nodes": [{
        "Text": "Sandwiches",
            "Nodes": [{
            "Text": "Ham & Cheese"
        }, {
            "Text": "Tuna"
        }, {
            "Text": "Turkey & Cheese"
        }]
    }, {
        "Text": "Fish"
    }, {
        "Text": "Hamburgers"
    }, {
        "Text": "Sishi"
    }, {
        "Text": "Steaks"
    }]
}, {
    "Text": "Beverages",
        "Nodes": [{
        "Text": "Coke"
    }, {
        "Text": "Pepsi"
    }, {
        "Text": "Mountain Dew"
    }, {
        "Text": "Lemonade"
    }]
}, {
    "Text": "Tech",
        "Nodes": [{
        "Text": "Laptops"
    }, {
        "Text": "Desktops"
    }, {
        "Text": "Tablets"
    }, {
        "Text": "Smartphones"
    }, {
        "Text": "Mainframes"
    }]
}, {
    "Text": "Literature",
        "Nodes": [{
        "Text": "Dostoevsky"
    }, {
        "Text": "Vazov"
    }, {
        "Text": "Tolstoy"
    }, {
        "Text": "Goethe"
    }, {
        "Text": "Steinbeck"
    }]
}, {
    "Text": "Accessories",
        "Nodes": [{
        "Text": "Mouse"
    }, {
        "Text": "Keyboard"
    }, {
        "Text": "Microphone"
    }, {
        "Text": "Camera"
    }, {
        "Text": "Mousepad"
    }]
}]};

viewModel = ko.mapping.fromJS(data);

$.ig.loader({
    scriptPath: 'http://cdn-na.infragistics.com/jquery/20131/latest/js/',
    cssPath: 'http://cdn-na.infragistics.com/jquery/20131/latest/css/',
    resources: 'igTree, extensions/infragistics.ui.tree.knockout-extensions.js',
    ready: function () {
        ko.applyBindings(viewModel);
    }
});


$("#addNode").click(function (event) {
    var tree = $("#tree").data('igTree');
    var selectedNodePath = tree.selectedNode().path.split(tree.options.pathSeparator);
    var target = viewModel.data()[selectedNodePath[0]];
    for(var i = 1; i<selectedNodePath.length; i++){
        if(!target.Nodes()[selectedNodePath[i]].Nodes){
           ...