Remember state with YUI TreeView

July 17th, 2008

YUI Tree

I’ve got a YUI tree which loads the leaves dynamically with Ajax calls. But I want to open up the tree to a specific leaf – on the third level down – after the page loads – as the server is delivering content specific to that node.

How to do? It’s like saving state after a roundtrip to the server. (the hierarchy is team->role->position)

The server tells the team node to expand which in turn tells the role node to unsubscribe and expand itself. In effect the tree opens to the third leaf.

during page load
   after drawing the tree with teams nodes
   get the specific team node
   subscribe to 'expandcomplete' with this function
          unsubscribe from the expansion event
          expand the specific role node
   now expand the team node

var teamnode = tree.getNodeByProperty("tmn_id","#getPosIds.tmn_id#");
tree.subscribe("expandComplete", function(node) {
	var rolenode = this.getNodeByProperty("pos_id","#getPosIds.pos_id#");
	tree.unsubscribe("expandComplete");
	rolenode.expand();
});
teamnode.expand();

Another suggested solution is to save state with a cookie, but i didn’t try that one.

I’ve gone a little Ajax crazy; every solution looks like ajax at the moment, and this is just with the YAHOO! library. I know there are others, potentially better ones out there (extjs.com?) but I’ve not evaluated them.

  1. Das
    December 9th, 2008 at 02:24 | #1

    John,

    Did you get this working? I am also trying to do the same thing. Could you please send me your code?

  2. December 10th, 2008 at 11:49 | #2

    Hi Das,

    Yes got it working.

    Sadly I don’t have a copy of the whole thing as it stayed at the company it was for and I managed to screw up the virtual server that i reserved as my backup. Whatsmore this piece will be deployed behind authentication. Sorry. Yes the fragment is specific to my problem and a hasty post.

    Some notes in looking at it now…

    1) “during page load” in the psuedocode

    Not shown in the fragment. I used the yui loader and had this fragment invoked when the yui considered the page loaded

    2) “get the specific team node”

    Refers to the first line – var teamnode. However I’ve not shown the construction of the tree in this fragment which is a bit poor of me.

    During tree construction the top level nodes were keyed with “tmn_id” and the middle level keyed “pos_id” which is obviously significant as these are the keys ‘getNodeByProperty’ uses to find the node. Hopefully how I did that is obvious when you examine the API to construct nodes.

    3) #variable_name#

    The server-side was Coldfusion and this is how coldfusion injects variables into markup. So “getPosIds” refers to a server-side variable containing a query resultset. Thus “#getPosIds.tmd_id#” is substituted with the contents of the first “tmn_id” field from the first row. An integer. eg “44″.

    So the client would actually be sent…

    var teamnode = tree.getNodeByProperty(“tmn_id”,”44″);

    4) the how

    I’ve done it by creating a routine to expand the innermost node. Then I’ve attached that routine to an event which is fired after the top-level node is expanded. Thus, by expanding the top level node, the child node gets opened as well. There’s a little gotcha in that you want the routine to self-destruct on first use – hence the unsubscribe.

    Maybe that helps. I think the secret lies in understanding how it was done rather than trying to copy the code fragment.

    John

  3. Scott
    January 9th, 2009 at 03:53 | #3

    Hi John,
    Do you have any idea how to get a node in a treeview that currently has focus? I’ve scoured the docs but I can’t find any way to do this. If you have any thoughts they would be gratefully received.

  4. March 23rd, 2009 at 18:01 | #4

    Hi John Mee

    I am wondering if you can remember if the whole code below was inside a loop which iterated the first children of the tree.getRoot() ?

    	for(var i=0; i < root.children.length; i++){
    		var node = root.children[i];
    		var pozid = node.data.pozid;
    		if (the node should be expanded){
    			(your code)*
    		}
    	}
    

    • March 28th, 2009 at 12:29 | #5

      Petronel:

      No. There were no loops.

      When the client-side code was generated at the server-side I embedded an identifier into each node (“pos_id”). When the code runs on the client it gets the node it wants by calling the “getNodeByProperty” function with my identifier “pos_id” and a value for it.

  1. No trackbacks yet.