Load on demand treeview and trying to open a path to a node

11 posts, 2 answers
  1. Ed
    Ed avatar
    78 posts
    Member since:
    Sep 2013

    Posted 04 Nov 2013 Link to this post

    I've got a tree view with potentially thousands of nodes that may be up to 20 levels deep.  I am doing load on demand as well.  This is all working great so far.

    I'm now working on a feature where the user would search for a node given the description and get back the path to the selected node from the root (an array of Id values).  The first two nodes (root and second level) are guaranteed to be there since I always start out with the root open.  It's when I search for and try to navigate to a node at level 3 or below that I am starting to have my main issues.

    Here is the "success" function from the AJAX method used to get the "path from the root to the selected node"

    function (result) { // success
        if (result.length > 0) {
            // add the leaf node since it is not included in the "path to the node"
            var nplus1 = result[result.length - 1].HierLevel + 1;
            var leafNode = { OrgId: parseFloat(id), HierLevel: nplus1 };
            result.push(leafNode);
            // get the tree view
            var treeview = $('#treeview').data('kendoTreeView');
            // collapse all nodes
            treeview.collapse(".k-item");
            // get the data source
            var dataSource = treeview.dataSource;
            $.each(result, function (idx, val) {
                var dataItem = dataSource.get(val.OrgId); // find item with OrgId value
                var node = treeview.findByUid(dataItem.uid); // find treeview item by uid
                treeview.expand(node);
                if (val.HierLevel === nplus1) {
                    treeview.select(node);
                }
            });
        }
    }

    I realize there are some issues here - such as how to deal with the async nature of loading the next node (expanding level 2+) on demand but still continuing to iterate thru the array of "path to node" items.  In the example above, when I get (dataSource.get) the 3rd level item (that doesn't exist in the datasource), an error "Uncaught TypeError: Cannot read property 'length' of undefined" in kendo.all.min.js, line 11 (Kendo UI Complete v2013.2.918)

    Also, the expand and select aren't working, but one thing at a time.

    Any pointers in the right direction are appreciated.

    Thanks,
    --Ed

  2. Answer
    Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2079 posts
    Member since:
    Sep 2012

    Posted 04 Nov 2013 Link to this post

    Hello Ed,

    The problem occurs because the nodes that are being opened are not fetched, and the loop does not wait for them to be fetched. In order to fetch the items sequentially, you need to wait for each AJAX request to finish, as shown in this jsBin.

    Regards,
    Alex Gyoshev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!

  3. Ed
    Ed avatar
    78 posts
    Member since:
    Sep 2013

    Posted 04 Nov 2013 Link to this post

    Hi Alex,
    Your solution is great but still there are a couple gotchas.

    1. If I have the root nodes open (open them via the mouse and therefore the data is loaded from the datasource), then click the button, nothing happens.  I'm assuming that is because we are not loading from the remote datasource since the data is already in the local datasource.  How can I tell if a node is already in the local datasource?
    2. The tree should be single select, but when we select programmatically, it does not de-select a node that was previously selected.  The result is two nodes that are selected.
    Thanks,
    --Ed

  4. Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2079 posts
    Member since:
    Sep 2012

    Posted 05 Nov 2013 Link to this post

    Hello Ed,

    Indeed. You can check whether an item is loaded or expanded through its loaded() method and expanded field. For the second problem, use the treeview select method. Here's the updated jsBin. On a side note, we decided to add the logic for expanding items (sans the selection) as a method for the Q3 release.

    Regards,
    Alex Gyoshev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!

  5. Ed
    Ed avatar
    78 posts
    Member since:
    Sep 2013

    Posted 05 Nov 2013 Link to this post

    Hi Alex,
    Your jsBin, as always, works great.  I do have additional issues.

    1. I would like to collapse all nodes before I open the path to the selected node.  I have tried to use treeview.collapse(".k-item");, but that seems to interfere with the openPath - perhaps a timing issue?  Does that sound right?  Or should I use a different approach to collapsing all nodes prior to openPath?
    2. How do I scroll to the selected item in the tree?  Is there a built-in mechanism in Kendo or do I need to use something like jQuery scrollTo?
    3. My select event handler wasn't being triggered, so I added treeview.trigger("select"); after the treeview.select() which resolved that problem.  Might be useful to add to the jsBin just to make it a more complete solution ;)
    Thanks again,
    --Ed

  6. Answer
    Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2079 posts
    Member since:
    Sep 2012

    Posted 06 Nov 2013 Link to this post

    Hello Ed,

    1. The problem with the collapse is caused by the animation (nodes get expanded before their close animation finishes. To resolve this, suppress the animation with animation: false.
    2. I'm afraid that Kendo UI does not offer such functionality at this time. We are considering to introduce such a method in the future; at present, you can use the scrollTo plug-in.
    3. Indeed, this might be useful for people finding this thread, and here's the updated jsBin. Client-side methods do not trigger events by design, for all widgets (with one notable exception, the window).
    Regards,
    Alex Gyoshev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!

  7. Ed
    Ed avatar
    78 posts
    Member since:
    Sep 2013

    Posted 06 Nov 2013 Link to this post

    Hi Alex,
    I really do like the animation of the tree and would like to retain that functionality, except in this one instance.  Is there a way to turn off animation, collapse all nodes, then turn the animation back on without initializing the tree all over again?  If that's the case, I'll just go with disabling collapse animation and leave the others as default.
    I looked at the docs and it looks like those options are only available at treeview init time
    Thanks,
    --Ed

  8. Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2079 posts
    Member since:
    Sep 2012

    Posted 07 Nov 2013 Link to this post

    Hello Ed,

    Preserving the animation would be a desirable, yes. You can disable it by setting animation: false through the setOptions method and re-enable it by supplying the default animation to the same method:

          var treeview = $('#tree').data('kendoTreeView');
          treeview.setOptions({ animation: false });
          treeview.collapse(".k-item");
          openPath(treeview, [ 1, 3, 5, 8]); 
          treeview.setOptions({ animation: kendo.ui.TreeView.fn.options.animation });

    Updated jsBin.

    Regards,
    Alex Gyoshev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!

  9. Allan
    Allan avatar
    4 posts
    Member since:
    Feb 2014

    Posted 29 Apr Link to this post

    I am trying to adapt this code to run when the page loads, rather than on a button click, but I'm getting some odd results.  Currently, I'm calling the openPath function like this:

    $(window).load(function () {
        var treeview= $("#tree").data("kendoTreeView");
        treeview.setOptions({ animation: false });
        treeview.collapse(".k-item");
        openPath(treeview, [1, 3, 5, 8]);
        treeview.setOptions({ animation: kendo.ui.TreeView.fn.options.animation });
    });

    The first time the page loads, the TreeView is not expanded.  However, if I refresh the browser, it expands just fine.  I get the exact same behavior if I use the new built-in method you mentioned as well (treeview.expandPath([1, 3, 5, 8]);).

    I'm assuming I should call the function another way, but I can't figure it out.

    Thanks!
        

  10. Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2079 posts
    Member since:
    Sep 2012

    Posted 30 Apr Link to this post

    Hello Allan,

    The openPath / expandPath methods require that you have loaded at least one level of the TreeView. If the root level isn't loaded, they do not function, and need to wait until the TreeView has loaded its data. Here is an updated jsBin that shows how to do that.

    Regards,
    Alex Gyoshev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     

  11. Allan
    Allan avatar
    4 posts
    Member since:
    Feb 2014

    Posted 30 Apr Link to this post

    That works perfectly with both openPath and expandPath.  I knew it was something simple I was missing.  Thanks!

Back to Top