Ask a Jedi: Using CFTREE for Navigation (2)

This post is more than 2 years old.

So last night, during my CF/AJAX presentation, I mentioned that I didn't think most folks made use of cftree, so this question is perfectly poised to prove me wrong. John asks:

I loved your example of binding a cfdiv to a cftree node. I would like to use this example but only have the cfdiv bind when a child node is clicked on. I have a simple parent-child tree structure with only one level. Do you have any ideas?

I always have ideas, but I assume you want a good idea, and those are a bit more rare. The original blog entry had a cfdiv that was bound to the tree. As soon as you clicked any leaf, the div was updated. In order to stop navigating on certain types of nodes, we need to change things up a bit. First, let's add a cfajaxproxy tag. This will give us more control over the binding: <cfajaxproxy bind="javascript:doNav({mytree.node})">

This line says - "When the tree's selected node changes, run a JavaScript function doNav and pass the node value." My JavaScript is rather simple:

<script> function doNav(n) { if(n != 'root') ColdFusion.navigate('dyn.cfm?value='+n,'content'); } </script>

My original tree (the full code will be below) used root for the top level leaf. So basically I just said, if the node was root, then don't do anything, otherwise, update the div. Here is the complete file:

<cfajaxproxy bind="javascript:doNav({mytree.node})">

<script> function doNav(n) { if(n != 'root') ColdFusion.navigate('dyn.cfm?value='+n,'content'); } </script>

<cfform name="form"> <cftree format="html" name="mytree"> <cftreeitem display="Navigation" value="root"> <cftreeitem display="Page A" parent="root" value="a"> <cftreeitem display="Page B" parent="root" value="b"> </cftree> </cfform>

<cfdiv id="content" />

The issue with this is that it only supports one root node. If you had another root node (imagine two parent leafs, Products and Services), you would need to update your JavaScript to check for both values. You could perhaps get a bit fancy and name all your root nodes like so:

root_Products
root_Services

And then simply use JavaScript to see if the selected node begins with root_.

Anyway, I think this gives you the idea.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by todd sharp posted on 7/10/2008 at 6:15 PM

Another possiblity to handle multiple roots and to check depth is to pass the path instead of the node. Then you can split it with JS based on the delimiter (default is '\') and check the length of the array.

Comment 2 by Mark posted on 7/14/2008 at 2:58 PM

Surely people want a tree with drag and drop?

Comment 3 by Raymond Camden posted on 7/14/2008 at 3:23 PM

Why? If the tree is being used for navigation, then I don't see how drag and drop would be useful.

Comment 4 by TD posted on 1/14/2009 at 11:32 PM

Is there any way to do this with <cftree format="flash"? ...i want to use the flash format to keep the overall look-and-feel consistent. Thanks in advance!

Comment 5 by Chris Ulrich posted on 2/5/2009 at 7:45 PM

Great tip Ray - thanks. I adapted it to do something similar with tabbed layouts.

On the left side of the screen is the tree, on the right side is a tabbed layout. inside each layout is a uniquely named CFDIV, and the javascript is:

function doNav(n) {
if(n != 'root') {
ColdFusion.navigate('add.cfm?action=add&id='+n,'adddiv');
ColdFusion.navigate('add.cfm?action=edit&id='+n,'editdiv');
}
}

This forces both tabs to load, one with an add form (and the node ID as a hidden field) and the other tab with an edit form (again, with the NodeID as a hidden field).

Easy way to edit the tree.

Thanks!

Comment 6 by Chris Ulrich posted on 2/5/2009 at 7:46 PM

Correction:

This actually forces both CFDIVs to load, each of them being in a CFTAB. It doesn't reload the CFLAYOUTAREA ... it is reloading the CFDIV in the CFLAYOUTAREA

Thanks

Comment 7 by Alan posted on 5/16/2012 at 11:31 AM

i don't get it. Since CF is using EXT library, how come all functionality is not in. I have few cases i am using drag and drop other than navigation.

Comment 8 by Raymond Camden posted on 5/16/2012 at 2:39 PM

Simple - CF is providing a tag based API to Ext. It covers the features that Adobe assumed most developers would want. For things outside of that, an API is provided so that in JavaScript, you can get the core object and do what you will.