Saturday, September 21, 2013

Tree View using Knockout.JS

Recently I tried out various Javascript frameworks, among them Knockout.js. What I found most impressive was how easy it was to build a tree view using Knockout. All you have to do is create a template that calls itself for rendering the child nodes:
<script type="text/html" id="tree-node">
    <li>
        <i data-bind="css: {'icon-collapse-alt': expanded, 'icon-expand-alt': collapsed}, click: toggle"></i>
        <span data-bind="text: name, click: $root.selected"></span>

        <div data-bind="if: expanded">
            <ul data-bind="template: {name: 'tree-node', foreach: children}"></ul>
        </div>
    </li>
</script>
Then you place the tree view in your HTML like this:
<ul data-bind="template: {name: 'tree-node', data: root}"></ul>
And of course you need a view model for the tree:

  function TreeNode(values) {
      var self = this;
      ko.mapping.fromJS(values, { children: { create: createNode }}, this);
      this.expanded = ko.observable(false);
      this.collapsed = ko.computed(function() {
      return !self.expanded();
    })
  }
  
  TreeNode.prototype.toggle = function () {
      this.expanded(!this.expanded());
  };
  
  function createNode(options) {
      return new TreeNode(options.data);
  }
  
  var root = new TreeNode({ id: "1", name: "Root", children: [
      { id: "1.1", name: "Node 1", children: [
          {id: "1.1.1", name: "Node 1.1", children: []},
          {id: "1.1.2", name: "Node 1.2", children: []}
      ]},
      { id: "1.2", name: "Node 2", children: []}
  ]});
  
  var viewModel = {
      root: root,
      selected: ko.observable()
  };
  
  ko.applyBindings(viewModel, $('html')[0]);
You can try this example live in this Plunkr.

3 comments:

  1. Hi there,

    nice solution,

    is it possible to get all the parent nodes id of the "selected" node?

    ReplyDelete
    Replies
    1. btw if someone wants answer to my above question, they can refer this link
      http://stackoverflow.com/questions/23739820/knockout-js-find-all-the-parent-nodes-id-from-a-item-selected-in-tree-view

      Delete
  2. How would I be able to add a selected class to (only) the node that was last clicked?

    ReplyDelete