0

I have a kendo Treeview bound to a remote hierarchical datasource(JSON file).

I want to add sprites next to each one of the nodes according to what the node is.If the node doesn't have children then I want it to have the "file" sprite,if the node has children I want it to have the "folder" sprite.(The sprites are provided from kendo,the ones that are on the demos)

I'm a bit confused with the way templates work,can I alter the sprite for each of the nodes dynamically with the template?Any good example and a bit of explanation to get me going would help a lot.

Thx

CipherDarkness
  • 214
  • 1
  • 8
  • 18
  • If it's just for displaying the icon, don't be enough using `spriteCssClass`. Example of node: `{ text:"node1.3", spriteCssClass:"k-icon k-i-pencil" }`. Why do you need templates? – OnaBai Nov 29 '12 at 16:22
  • I need them because I want the new nodes to have the appropriate sprites too.I want this to be done automatically so I won't have to check and add the `spriteCssClass` on every node on the datasource every time.. – CipherDarkness Nov 30 '12 at 09:03

2 Answers2

1

In the following code what I do is define a template that checks if the node being rendered has items (subnodes) or not. If it has, it displays an icon from default sprite file (k-i-plus) otherwise it shows a different icon (k-i-refresh).

function loadMore() {
    var uuid = $(this).data("uid");
    var node = tree.findByUid(uuid);
    tree.insertBefore(content, node);
    tree.remove(node);
    tree.expand(".k-item");
    addLoadMore(".k-i-refresh");
}

function addLoadMore(clss) {
    $(clss, tree.element).closest(".k-item").on("click", loadMore);
}

var content = [
    {
        text :"node1",
        items:[
            { text:"node1.1" },
            { text:"node1.2" },
            { text   :"node1.3",
                items:[
                    { text:"node1.3.1" },
                    { text:"node1.3.2" },
                    { text:"node1.3.3" },
                    { text:"node1.3.4" }
                ] },
            { text:"node1.4" }
        ]
    }
];

var tree = $("#tree").kendoTreeView({
    dataSource:content,
    template  :"<span class='k-icon #= item.items ? 'k-i-plus' : 'k-i-refresh' #'></span>#= item.text #"
}).data("kendoTreeView");
tree.expand(".k-item");
addLoadMore(".k-i-refresh");

What you would need to do if replace k-i-plus by the CSS class name that defines the folder and change k-i-refresh by the CSS class name for the file.

If you need information on writing template there is a pretty good documentation in here.

OnaBai
  • 40,767
  • 6
  • 96
  • 125
  • Ok so I altered it a bit because as we've seen before kendo adds the `items` field in every node automatically.But ok I've got it to work,problem is that if I add a node it has the file image as it should,if I add a child to that node,the file image doesn't become folder image automatically!Is there a way to run the template continiously and not only on the treeview init?? – CipherDarkness Nov 30 '12 at 09:24
  • Strictly speaking, it is not when you initialize the `treeview` but when you add nodes. So, I've modified the code above to dynamically add nodes to the nodes that have `k-i-refresh` icon but it's implemented with an `insertBefore` plus a `remove` instead of an `append`. – OnaBai Nov 30 '12 at 10:35
  • Seems like I don't have to add another function,all I had to do was add `treeview.dataSource.sync()` on the appendNode and the the removeNode functions and the sprites are updated automatically according to the condition of the node!Thx a lot once more for your help! :) – CipherDarkness Nov 30 '12 at 11:16
  • Hmmm `.sync()` doesn't work right with the dataSource and lags the rest of the functions..I figured that if I change the `text` value of the node,the sprite gets refreshed!Is there a way I can manually "re-run" the template on every append,remove,drag? Because I doesn't seem to "run" when I append a child for example and you say that it should right? – CipherDarkness Nov 30 '12 at 14:34
  • When I said that it is also when you add nodes I meant for the nodes that you have added but not for the parent. The idea is that the template is run **only** when the node is rendered for the first time. That's why I cannot append but I generate a copy of the node on which I want to append, then add the subnodes to this copy, then call `insertBefore` to insert the copy and finally remove the old copy. – OnaBai Nov 30 '12 at 16:01
  • By the way, the function `text` for changing the text of a node does not re-draw the icon (not even without using templates) -it's a (non-documented) _feature_. – OnaBai Nov 30 '12 at 16:07
  • Yet if I change the text with `treeview.dataItem(...).set("text",newText)` the sprite is updated on that node accordingly.If there is no other way to trigger the template on every append and remove,then I guess changing the text and then reverting it back is kinda faster than creating a new node and then deleting it on every append,every remove and every dragend.. – CipherDarkness Dec 03 '12 at 08:58
  • I tried `var templ = kendo.template("#=pos.text #");` and in the removeNode I put `var pos = treeview.dataItem(treeview.select()).parentNode();` `templ(pos);` yet I get `pos is undefined in the jquery.min.js...` The documentation stated I could run a template on demand like this,what am I missing? – CipherDarkness Dec 03 '12 at 09:27
0

I know I am 3+ years late for this. But in case anyone run into this same question. Here is how I achieved it:

    schema: {
        model: {
            children: "folder",
            hasChildren: function (node) {
                var hasChildren =  (node.folder && node.folder.length > 0);
                if (hasChildren === true) {
                    node.spriteCssClass = "folder";
                } else {
                    node.spriteCssClass = "html";
                }
                return hasChildren;
            }
        }
    }