ExtJS Treepanel all nodes loaded event


In ExtJS (any version), in Ext.tree.TreePanel, when we load the tree, there in no event to check if all my tree-nodes are completely loaded (or not in store but actually all nodeui's are loaded into the dom or not), i.e. doing something after full or part of tree gets loaded, I wanted this functionality sometime back, so we did this.

Though there is a callback function on expand and collapse method calls on TreeNode, but they only check if the immediate child of this node are expanded and loaded in dom and not the whole lower tree nodes.

This is again, a subjective solution, it might not satisfy your need but you can give this a try.

In our case, we were expanding the Treepanel completely, when Treeloader loads its data, so my code looked like ...

new Ext.tree.TreePanel({
 id : 'MyGrid',
 autoScroll : Globals.Boolean.TRUE,
 animate : false, //DO NOT ENABLE IT TO TRUE, AS IT TAKES TIME TO LOAD NODES IN DOM-TREE
 border : true,
 enableDD : true,
 containerScroll : true,
 loader : new Ext.tree.TreeLoader({
  id : 'MyGridLoader',
  dataUrl : '/MyApp/LoadFolderTree.do',
  requestMethod : 'POST',
  clearOnLoad : true,
  preloadChildren : true,
  listeners : {
   load:function(loader,node,response){
     //Do something else...
     Ext.getCmp('MyGrid').getRootNode().expand(true);
     //Do something else...
   }
  }
 }),
 root : new Ext.tree.AsyncTreeNode({
  text : 'Root',
  draggable:false,
  expanded: true,
  qtip: 'Root node',
  id : 'Root',
  selected: true,
  listeners: {
   "allnodesloaded": function(root){
    //Do something like select favorite node, or previously selected node, etc. 
    //as now all nodes are rendered into dom as all nodes expand is complete
   }
  }
 }),
});




So there is this "allnodesloaded" event listener function which we have written.

There is one Ext.tree.TreeNode override -


Ext.override(Ext.tree.TreeNode,{
    expandChildNodes : function(deep,anim){
        var cs = this.childNodes,
            i,
            len = cs.length;
        for (i = 0; i < len; i++) {
         cs[i].expand(deep, anim);
        }
        Ext.defer(this.fireEvent, 1000, this, ["allnodesloaded",this]);
        //this.fireEvent("allnodesloaded",this);
    }
});


Basically, here we are just firing a custom event named "allnodesloaded" when expandChildNodes completes its execution.

Lets see, why we have overridden this method only and why in TreeNode class and not in TreePanel or TreeNodeUI or any other.

I will show you the flow... When we say root node "expanded:true" property or in TreeLoader on load event, deep-expand the root/any node, it will basically fire expand event of  Ext.tree.AsyncTreeNode (as I had used AsyncNode for my root node), which basically extends Ext.tree.TreeNode. So Asyncnode's expand method internally calls to expand method of its superclass i.e. TreeNode, if deepexpand is true then it will call its member function, expandChildNodes, which we have overrridden.

(Code snippets from extjs actual source-code)...


TreeNode's expand method implementation ... 
 then expandChildNodes method...
So once expandChildNodes completes its clear that all nodes of tree are rendered into dom.

Note - I came across this issue, if I enable anim:true for tree my event was getting fired earlier than actual dom-rendering of all nodes. So to mitigate that too, I deferred the event call by 1000 mili seconds, and removed anim attribute too... now for me its working fine.
In case you have many levels in treepanel, then anim:true will render nodes slowly, if you still need animation then increase event firing defer time as per your need.

Comments

Popular posts from this blog

How to install / Configure Mantis For Apache-PHP-PostgreSQL combination

Modified ExtJS LOVCombo (List of Values) ux plugin - with select all, deselect all, text filter, bubble up and bubble down of selection

TriggerField with two triggers, TwinTriggerField with tooltips