Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find a nested node in a Kendo tree view where data is 'lazely' served through a web-api

Tags:

kendo-ui

I know the exact route to find a nested node in a Kendo tree view. So I wish to expand all nodes along this route to go and get there. I know how to find a node and make Kendo expand that node.

My Treeview uses a web-api for its data and all works well. The schema is defined as follows:

            schema: {
                model: {
                    id: "CodeList",
                    hasChildren: "HasKids"
                }
            }

What I want to achieve is for the tree to expand automatically to a nested level. Say I know the path to get to a node is 'Level1CodeA|Level2CodeA|Level3CodeA' so first I wish to find the code 'Level1CodeA' which I can do.
I then wish to expand this node (internally it retrieves the data under this node and it expands ok) after which I want to find 'Level2CodeA', repeat the process so also find and then select Level3CodeA.

How would I go about this? I was looking for an 'AfterExpanded' event that I could use to start the next search and expand operation but I can't find any event I can use. I tried the 'change' event on my datasource but this is fired many times and I can't seem to narrow it down to the correct item..

Many thanks.

EDIT: more code

<script id="treeII-template" type="text/kendo-ui-template">
    <img id="explorerItemImg" src="#: item.Image #" />
    <span id="explorerItemCode">#: item.Code #</span> - 
    <span id="explorerItemFullName">#: item.FullName #</span>
    # if (item.Level < (item.Levels - 1)) { #
        [<span id="explorerItemLCount">#: item.LCount #</span>]
    # } #
    # if (item.HasKids) { #
        [<span id="explorerItemPCount">#: item.PCount #</span>]
    # } #

</script>

The code to create the HierarchicalDataSource and assigning this to the treeview:

    // -----------------
    // set the datasource for the bottom explorer...
    // -----------------
    var loadDataForExplorerGroup = function (context, groupid, groupsequence) {

        // hang on to this context/groupid
        sessionStorage.setItem(context + "_explorer_groupId", groupid);
        sessionStorage.setItem(context + "_explorer_groupSequence", groupsequence);

        // define the datasource and attach it to the explorer-tree
        explorerGroupData = new kendo.data.HierarchicalDataSource({
            transport: {
                read: {
                    url: "/api/explorerapi/GetExplorerData?",
                    data: {
                        context: "portfolio",
                        groupid: groupid,
                        groupsequence: groupsequence,
                        userid: sessionStorage.getItem("symUserID")
                    }
                }
            },
            schema: {
                model: {
                    id: "CodeList",
                    hasChildren: "HasKids"
                }
            }
        });

        // simply assign the data source again to the tree
        $("#idExplBottomTree").data("kendoTreeView").setDataSource(explorerGroupData);

    };
like image 253
Marcel Avatar asked Jan 17 '13 13:01

Marcel


1 Answers

That AfterExpanded event might be dataBound. What I would propose is given the following TreeView definition:

var tree = $("#treeview").kendoTreeView({
    dataSource   : data,
    dataTextField: "text",
    dataBound    : function (e) {
        treeNavigateNext();
    }
}).data("kendoTreeView");

I've added dataBound handler that invokes treeNavigate defined as:

function treeNavigateNext() {
    if (search.length > 0) {
        var first = tree.findByText(search[0]);
        if (first) {
            search.shift();
            tree.expand(first);
        }
    }
}

Where search is an array containing dataTextField of each node that we want to navigate.

Example:

search = [];
search.push("t_3");
search.push("t_32");
search.push("t_321");
search.push("t_3214");

Defines that we want to expand a node which text is t_3, then t_32, next t_321 and finally t_3214.

So treeNavigateNext checks that there is still something pending (search.length > 0) and if so, find the element by its text (var first = tree.findByText(search[0]);), removes the element from search (search.shift();) and finally expand the node (tree.expand(first)). This causes the next level to be loaded and when received dataBound event is triggered and I will go to the next level.

See it running here

EDIT: If instead of searching by text you prefer to navigate by id then add to search array the id of the different nodes and use the following treeNavigateNext function instead:

function treeNavigateNext() {
    if (search.length > 0) {
        var first = tree.dataSource.get(search[0]);
        if (first) {
            search.shift();
            var elem = tree.findByUid(first.uid);
            tree.expand(elem);
        } 
    }
}

New running example here

like image 72
OnaBai Avatar answered Oct 23 '22 11:10

OnaBai