1

I have a tree made with jstree which loads partially and loads on via json_data plugin as you expand nodes. Here's the crux of the code:

$("#TreeViewDiv")   
.jstree(
{
    json_data:
    {
        ajax:
        {
            url: "/Website/GetNodes",
            data: function (node) {
                //do some stuff to compile data for backend here

                return {
                    //insert data for backend here
                };
            },
            error: function () {
                $("#TreeViewDiv").html("Error initializing tree");
            }
        }
    },

    plugins: ["json_data", "ui"]
});

I then want to expand some of the nodes and select a leaf node, depending on which user is accessing the site. I do this in a loop as follows:

var nodeValues = [Parent, firstChild, leaf];

        for (var j = 0; j < nodeValues .length-1; j++) {        
            $("#TreeViewDiv").jstree("open_node", $("input[value='" + nodeValues [j] + "']"));
        }

Opening the Parent node works fine and the firstChild is exposed when the tree is shown but the firstChild node is not open. If I kick off the loop again, the firstchild opens successfully to show the leaf node.

My guess is that the request hasn't completed and the firstChild tree node doesn't exist when the above loop tries to open it. Is there a way to wait for the nodes to load before trying to open the next node? Thank you!

VARAK
  • 835
  • 10
  • 27

1 Answers1

3

Ok, so I figured it out eventually. Here's a way to do it with deferreds. There's probably a neater way but my head hurts after a day of playing with this so refactoring will have to wait :)

var deffereds = $.Deferred(function (def) { def.resolve(); });

var nodeValues = [Parent, firstChild, leaf];

for (var j = 0; j < nodeValues .length-1; j++) {  
deffereds = (function(name, deferreds) {
                return deferreds.pipe(function () {
                    return $.Deferred(function(def) {
                                                    $("#TreeViewDiv").jstree("open_node", $("input[value='" + name + "']"), function () {
                            def.resolve();
                        });
                    });
                });
            })(nodeValues [j], deffereds);      
 }

This basically places the call to open_node in a deferred and uses the callback from the open_node functions to resolve the deferred thus ensuring that no node is opened before its parent has been opened.

VARAK
  • 835
  • 10
  • 27