1
votes

I have this treeview wich can have a variable number of children (some nodes can have up to 3 generations of children, some may have only one etc)

What I'm trying to do is expand a certain node when the treeview is loaded. And I have 2 problems: 1) I can't find an event/callback so that I know when the treeview is ready 2) The expand function doesn't always work ( I'll explain )

This is my treeview:

function InitializeTreeview() {

var Children_Merchants = {
    transport: {
        read: {
            url: function (options) {
                return kendo.format(websiteRootUrl + '/Merchants/Merchants/?hasParents={0}',   hasParent);
            }
        }
    },
    schema: {
        model: {
             model: {
            id: "ID",
            hasChildren: true,
            children: Children_Merchants
        }
        }
    }
};

var Brandowners = new kendo.data.HierarchicalDataSource({
    transport: {
        read: {
            url: kendo.format(websiteRootUrl + '/Merchants/GetBrandowners?databaseID={0}',       selectedDatabaseID)
      }
    },
    //change: ExpandNode, - if I call expand node like this, it works.
    schema: {
        model: {
            id: "ID",
            hasChildren: true,
            children: Children_Merchants
        }
    }
});


$('#treeview').kendoTreeView({
    dataSource: Brandowners,
    animation: {
        collapse: {
            duration: 200,
            effects: "fadeOut"
        },
        expand: {
            duration: 200,
            effects: "fadeIn"
        }

    },
    dataTextField: "Name",
    complete: function () {  alert('ok'); },
    //dataBound    : ExpandNode,
    select: OnSelect,
    expand: CheckIfHasParent
}).data('kendoTreeView');
}

function ExpandNode() {
    var treeview;
    treeview = $("#treeview").data("kendoTreeView");
    var nodeToExpand = treeview.findByText('Adam'); //dummy txt, will have from parameter
    treeview.expand(nodeToExpand);
}

The databind works ok, my controllers get called, everything's fine. So what I tried is hook up the ExpandNode function to a click of a button. The function gets called but nothing happens. BUT if I hook it up to the change event of the parents datasource, it works. Another interesting thing is that the select works so if I replace treeview.expand(...) with treeview.select(...), it works on the click.

So my questions are:

1) What event should I use for loadEnd ( or smth like that ) - so I won't have to bind the function to button click (it's still ok but I preffer on load ended) - P.S. I tried all the ones I found on the kendo forums,like: change, requestEnd, success, dataBound and they don't work. I tried sending the JSON with the property "expanded" set to TRUE, for the node in question, but that only modifies the arrow to show like it's opened, but it doesn't call the controller and load the children.

2) Do you know why ExpandNode works only when binded to the change event? - the most important question to me.

3) If you have suggestions, or have I done something wrong in the initialiation of the treeview, please tell me.

4
I tried that already, it only changes the arrow to expanded modeVlad
Are you doing load on demand or loading all the tree in a single transfer?OnaBai
I tried setting loadOnDemmand to false and send the expand = true. and then BOOM. some 2-3 nodes got expanded with children and all. but I have a total of 100+ parents + the generations, it ads up to about 40000 nodes. So it crashed. I guess that would be a solution, but it's not good for meVlad
Taking a deeper look into your code... Why Children_Merchants is not a HierarchicalDataSource?OnaBai
I had an example in the same project, so I looked there for the datasource and treeview init. Honestly, I don't really get it how it does it. it just goes recursevly. - I was amazed when found out that I have more than 2 levels :) in the meanwhile I see that: if I expand the 'Adam' node - targeted in the ExpandNode(), close it, and then click on the button, it expands with the children. So I guess the children have to be loaded by the time "teeview.expand(...)" gets executed, would you agree?Vlad

4 Answers

3
votes

I've copied your code with some free interpretations and the answer your questions is:

  1. What event should I use for loadEnd => dataBound
  2. Do you know why ExpandNode works only when binded to the change event? => No, it works without binding it to change event. If it does not then there is something else in your code.
  3. Suggestions => There is some information missing about your code that might make the difference with what I've implemented.
  4. What is CheckIfHasParent? => I have implemented it as a function that actually does nothing.
  5. What is hasParent? => I've ignored it.

The code as I write it:

$(document).ready(function () {
        function InitializeTreeview() {
            var Children_Merchants = {
                transport: {
                    read: function (op) {
                        var id = op.data.ID;
                        var data = [];
                        for (var i = 0; i < 10; i++) {
                            var aux = id * 100 + i;
                            data.push({ Name: "Name-" + aux, ID: aux});
                        }
                        op.success(data);
                    }
                },
                schema   : {
                    model: {
                        model: {
                            id         : "ID",
                            hasChildren: true,
                            children   : Children_Merchants
                        }
                    }
                }
            };
    
            var Brandowners = new kendo.data.HierarchicalDataSource({
                transport: {
                    read: function (op) {
                        op.success([
                            {"Name": "Adam", "ID": 1},
                            {"Name": "Benjamin", "ID": 2},
                            {"Name": "Caleb", "ID": 3},
                            {"Name": "Daniel", "ID": 4},
                            {"Name": "Ephraim", "ID": 5},
                            {"Name": "Frank", "ID": 6},
                            {"Name": "Gideon", "ID": 7}
                        ])
                    }
                },
                //change: ExpandNode, - if I call expand node like this, it works.
                schema   : {
                    model: {
                        id         : "ID",
                        hasChildren: true,
                        children   : Children_Merchants
                    }
                }
            });
    
            $('#treeview').kendoTreeView({
                dataSource   : Brandowners,
                animation    : {
                    collapse: {
                        duration: 200,
                        effects : "fadeOut"
                    },
                    expand  : {
                        duration: 200,
                        effects : "fadeIn"
                    }
    
                },
                dataTextField: "Name",
                dataBound    : ExpandNode,
                expand       : CheckIfHasParent
            }).data('kendoTreeView');
        }
    
        function ExpandNode() {
            var treeview;
            treeview = $("#treeview").data("kendoTreeView");
            var nodeToExpand = treeview.findByText('Adam'); //dummy txt, will have from parameter
            treeview.expand(nodeToExpand);
        }
    
        function CheckIfHasParent(e) {
        }
    
        InitializeTreeview();
    
 });

and you can play with it here : http://jsfiddle.net/OnaBai/dSt2h/

1
votes
$("#treeview").kendoTreeView({
    animation: {
        expand: true
    },

    dataSource: dataSource,
    dataBound: function (e) {                   
        var tv = $("#treeview").data("kendoTreeView");
        if (tv != null) {
            tv.expand(".k-item");
        }
    },

    dataTextField: "test",
    dataValueField: "id"                
});
1
votes

For anyone who may be interested:

   function ExpandNode() {
    
   var treeview;
   var node1;

   treeview = $("#treeview").data("kendoTreeView");
   var node2;
   var myURL = kendo.format(websiteRootUrl + '/Merchants/GetPathForSelectedNode?databaseID={0}&merchantID={1}&brandownerID={2}', selectedDatabaseID,MerID,BowID);
       
   node1 = treeview.dataSource.get(BowID);
   node = treeview.findByUid(node1.uid);
   var uid = node1.uid;
   node.find('span:first-child').trigger('click'); //expand 1st level

   $.ajax( {
                            url: myURL,
                            dataType: "json",
                            contentType: 'application/json; charset=utf-8',
                            success: function(result)
                                {
                                   
                                   var length = result.length;
                                 
                                   var lastVal = 1;
                                   for (var i = 1; i < length-1; i++) {
                                        $("#treeview li[data-uid=\'" + uid + "\'] ul.k-group").waitUntilExists (function
                                        () {
                                               i = lastVal; // have to reinitialize i because waitUntilExist's callback will find the i incermented, over the needed value
                                               lastVal++;
                                               node2 = node1.children.get(result[i]);
                                               node = treeview.findByUid(node2.uid);
                                               uid = node2.uid;
                                               node1 = node2;
                                               if(lastVal <= length-1)
                                                    node.find('span:first-child').trigger('click'); // keep expanding
                                               else
                                               {
                                                    treeview.select(node); // just select last node
                                                    currentSelectedNode = node;
                                                }
                                            
                                        });
                                   }
                                   if(length == 2) //select 1st child
                                   {
                                        $("#treeview li[data-uid=\'" + uid + "\'] ul.k-group").waitUntilExists (function
                                        () {
                                               node2 = node1.children.get(result[i]);
                                               node = treeview.findByUid(node2.uid);
                                               uid = node2.uid;
                                               node1 = node2;
                                               treeview.select(node); // just select last node
                                               currentSelectedNode = node;
                                        });
                                   }
                                }
                          });

}

This is my method. The for loop starts at 1 because the 1st element in my array is the 1st node ID - wich I've already expanded. the .waitUntilExists is Ryan Lester's method (I put a link in the comments above). Many thanks to my colleague, to you OnaBai and, of courese, to Ryan Lester. I hope this helps someone. Cheers

0
votes

ypu can easily find the treeview is ready for expand by following code which are expanding all the treeview nodes you can also find it by checking perticular id or text hopw, following example will help you

Ex:

$("#treeview").kendoTreeView({
                animation: {
                    expand: true
                },

                dataSource: dataSource,
                dataBound: function (e) {                   
                    var tv = $("#treeview").data("kendoTreeView");
                    if (tv != null) {
                        tv.expand(".k-item");
                    }
                },

                dataTextField: "test",
                dataValueField: "id"                
            });