Javascript – Change jsTree node css class after json_data loads

javascriptjqueryjstree

i load my jsTree via json_data whenever the user clicks the [+] next to a folder. What i want to do is apply css classes to some of the nodes to highlight them for the user. Not talking about mouse-hover or the currently selected node here, but multiple nodes some human has to review later. The appropriate css class is already inside the JSON response from the server:

[
{"attr":{"id":"node_5","rel":"document","page_id":"4"},"data":"Test123","csscl":"ui-state-error","state":""},
{"attr":{"id":"node_6","rel":"folder","page_id":"6"},"data":"Services","csscl":"","state":"closed"}
]

my "Test123" node should get class "ui-state-error" later in the tree.
Here is my jsTree:

$(function () {
// Settings up the tree. note to self: dont use the cookie plugin here, this will always overwrite pre-selected nodes
$("#jstree").jstree({
    "plugins" : [ "themes", "json_data", "ui", "types", "hotkeys",],
    "json_data" : { 
        "ajax" : {
            "url" : "inc/tree_server.php",
            "data" : function (n) {
                return { 
                    "operation" : "get_children", 
                    "id" : n.attr ? n.attr("id").replace("node_","") : 1 
                };
            },
            success: function(n) {

                for (var i in n)
                {
                    jqid = "#"+n[i].attr["id"]+" a";
                    $(jqid).addClass(n[i].csscl);
                }                   
            }
        }
    },
    // the UI plugin
    "ui" : {
        // selected onload
        "initially_select" : [ "node_<?=$p->oTopic->iId;?>" ]
    },
    // the core plugin
    "core" : { 
        "initially_open" : [ <?=$p->oTopic->sJstreeOpenSeq;?> ],
        "animation" : 0
    }
})

This won't work. What i think happens is that "success: function(n)" is called after the tree is loaded, but before it is drawn or ready for JQuery to find the selected node and apply my class.
Anyone knows how to solve this, or maybe there is a better way to apply a css class to $("#node5 a") in that case…?

Best Answer

I think I found a workaround.

    success: function(n) {
        for (var i in n)
        {
            some_global_array_id.push(n[i].attr["id"]);
            some_global_array_data.push(n[i].csscl);
        }                   
    }

And then after loading and drawing you can call function like this:

$("#jstree").jstree({
       // ... code you posted
    }).bind("reopen.jstree", function (e, data) {
       for (var i in some_global_array_id) {
           $("#"+some_global_array_id[i]+" a").addClass(some_global_array_data[i]);
       }
    });