Using CFTREE for Navigation

A user on cf-talk today asked if it was possible to use ColdFusion 8's new HTML CFTREE as a navigation tool. Turns out it is rather simple, and like most things in ColdFusion, there are multiple solutions.

First off - when you use the HREF attribute of CFTREEITEM, you are allowed to use JavaScript. One simple solution would be to just do:

<cftreeitem display="products" href="javaScript:doProducts('...')">

You could use document.href.location to move the entire page, or use the new ColdFusion.navigate function to load a URL into a UI item like a CFDIV or CFWINDOW.

While that works ok for static, hard coded trees, it isn't a good solution for dynamic trees, and, it can be done simpler if you just bindings. Consider this example:

<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 bind="url:content.cfm?value={mytree.node}" />

I've built a simple tree with one main node and two child nodes. I then added a CFDIV that is bound to the tree. When binding to a tree, you can get two values: node and path. Node returns just the value for the selected item. Path returns the path of the node itself. Thanks to Todd Sharp for finding these values in the docs.

p.s. As a side question - who would like to see an API doc that covers stuff like this? I wasn't able to find it in the reference and it was hard to find in the developers guide. I'd like a guide that more clearly describes working with ColdFusion's new UI elements.

Archived Comments

Comment 1 by todd sharp posted on 7/31/2007 at 6:34 PM

Sounds like that would make a perfect Cheat Sheet!

Comment 2 by Dan Wilson posted on 7/31/2007 at 7:52 PM

I agree with Todd. A cheat sheet would be a great resource.

DW

Comment 3 by Lola LB posted on 7/31/2007 at 8:06 PM

I would. But, seriously, man, you need to Sleep. ;-)

Comment 4 by Steve Sequenzia posted on 7/31/2007 at 9:05 PM

Ray -

I asked the original question on CF-Talk. Thanks for your help, I really appreciate it.

I was actually trying to do it with the <cfdiv> and bind but I could not figure out the syntax for the node part.

I am still struggling with one part of it.

I want to load a new page in the "main" layout when each link in the tree is clicked. I made it work like this:

<cfform name="form">

<cftree format="html" name="mytree">

<cftreeitem display="Navigation" value="root">
<cftreeitem display="Page A" parent="root" value="pageA.cfm">
<cftreeitem display="Page B" parent="root" value="pageB.cfm">

</cftree>

</cfform>

<cfdiv bind="url:content.cfm?value={mytree.node}" />

and then on the content.cfm page I just have a simple <cfinclude template="#value#">.

This seems to work perfect when the links in the tree are clicked. Thing is, when the page initially loads it does not know the value of #value# and it errors out. That makes sense so I tried to add <cfparam name="value" default="page.cfm"> to the beginning of the page but that is not working.

For some reason the <cfparam> is not working with the bind to the cfdiv in the "main" layout when the ?value={mytree.node} is added. I even tried to just do a <cfoutput>#value#</cfoutput> without the include and it does not work. I thought it might have something to do with the naming so I tried changing the name in the <cfparam> to something else and that is also not working.

Any ideas?

Thanks again for your help. I am certain that you are very busy, so your help is very appreciated.

-Steve

Comment 5 by Raymond Camden posted on 7/31/2007 at 10:47 PM

You have two problems here.

First off - when the page loads, value does exist. If you use firebug you will see it gets passed as

value=

Now the value (the value of value ;) is blank, but it EXISTS! See the difference?

What you need is:

<cfif not isDefined("url.value") or not len(trim(url.value))>
<cfset value = "somedefault">
</cfif>

Your second problem is MUCH more serious. I HIGHLY urge you to change your application. Pardon the caps - but passing in a file to load via the query string is a very bad idea. What if I notice this and I change the value? What if I set url.value=content.cfm?

Comment 6 by Steve Sequenzia posted on 8/1/2007 at 7:41 PM

Point taken...

Thanks Ray, I will work on changing the structure of this application.

Thanks again.

Comment 7 by I Rz posted on 8/16/2007 at 6:27 PM

Works great. But if I include the files the content.cfm is not found. I tried all combos of url:dir/content.cfm, url:/dir/content.cfm, etc... What is the trick?
Thanks.

Comment 8 by I Rz posted on 8/16/2007 at 6:31 PM

for Steve Sequenzia, try below if I understood your problem correctly.
<cfdiv bind="url:content.cfm?value={mytree.node}" bindOnLoad = "false"/>

Comment 9 by Raymond Camden posted on 8/16/2007 at 9:53 PM

RZ - try using a full path from web root.

Comment 10 by hongsun posted on 3/31/2009 at 6:55 AM

I would like to use navigate function, but cannot make it work:

My code:
--------
<cfform action="">
<cfoutput>
<CFTREE name = "Tree" highlighthref="yes" format="flash" height="320" width="200" appendkey="false">

<CFTREEITEM value="4" display="Accounting" expand="yes" img="./Images/folder_home.png" imgopen="yes">
<CFTREEITEM value="41" display="Reports" expand="no" img="element" parent="4" href="javaScript:ColdFusion.navigate('#self##xfa.accountingReport#','center')"></a>
<CFTREEITEM value="42" display="CAN Management" expand="no" img="element" parent="4" href="javaScript:ColdFusion.navigate('#self##xfa.accountingManageCAN#','center')">

</CFTREE>
</cfoutput>
</cfform>

-----------------------------------------

Thanks

Comment 11 by Thomas posted on 5/11/2010 at 6:30 PM

Any ideas on how to do something similar with CF7?

Comment 12 by Raymond Camden posted on 5/11/2010 at 6:38 PM

It is a wrapper to a YUI library (as opposed to Ext I think). You can easily use them yourself.

Comment 13 by Thomas posted on 5/11/2010 at 6:57 PM

Also... I cannot seem to get javascript to work with the href.

I have a simple function:
function hello(){
alert('hello');
}

and call it like so:
href="javaScript:hello()"

With this, I get a syntax error

Comment 14 by Ranga posted on 7/8/2010 at 6:06 AM

In one of the requirements of a page in my website, I have to expand one of the cftreeitems. I was able to achieve using expand="yes". My problem is when a cftreeitem is set expand="yes" the folder is displaying a closed folder icon instead of an open folder icon.

Do you know how do I manipulate so that I get to show an open folder icon when an item is expanded on page load?

For e.g. assume that I have a cftree as following:

<cftree format="html" name="mytree">
<cftreeitem display="Navigation" value="root" expand="yes" img="folder" imgopen="folder">
<cftreeitem display="Page A" parent="root" value="pageA.cfm">
<cftreeitem display="Page B" parent="root" value="pageB.cfm">
</cftree>

Now on page load I need to do two things:
1. Highlight Page B
2. Show open folder icon for Navigation.

Thanks
Ranga

Comment 15 by Raymond Camden posted on 7/9/2010 at 3:19 PM

You can get the tree object (ColdFusion.Tree.getTreeObject) and see if there is a way via that.

Comment 16 by saiful posted on 7/28/2010 at 6:02 AM

hai ray,

thanks for your tutorial on cftree for navigation. it's really helpful link to my new project. i'm working on multiple layer cftree.