There are many new AJAX functionalities included with CF8 and I am going to start to share some small things I have found useful. I will title these blog entries so they all start with "CF8 AJAX Features".
This first example shows a page that is using cflayout area "left" to display an html cftree that contains a hierarchical structure of categories (this could also apply to a page/sub page navigation system if you wanted to use cftree for that) and a cflayoutarea "center" that displays the child categories of the selected tree node.
For this example I have hard coded the category query so that you can see how it works without the need for a database table.
The challenge comes when you want to make it so that users can click on a link on the center cflayoutarea and have the selected tree node in the cftree change automatically to the new page.
Figuring this out took a decent amount of research into the YUI TreeView object and then some real digging into how the folks at Adobe implemented it.
From Adobe documentation I found there was a ColdFusion.Tree.getTreeObject() function I could use to the access tree object, and then they kindly directed me to the Yahoo documentation to figure the rest out myself.
After reading the DOM for the TreeView object (http://developer.yahoo.com/yui/docs/YAHOO.widget.TreeView.html) I found the function getNodeByProperty() which I was certain was what I needed to dynamically find the correct tree node from the body page based on the category_id column in my query. However, I had no idea what ColdFusion named the property when it created the tree object. I had started with the obvious and tried getNodeByProperty('value',catID) but unfortunately they did not chose to make it that easy for me. so I found some javascript online that recursively dumped each property in a javascript object and pops it up in an alert page and used that to figure out that the "value" attribute in my cftreeitem tags was put into the "id" property in the Yahoo node objects. After I figured that out, it all came together like an "A-Team" plan.
Here is an example of how to do it:
Save this code as myLayout.cfm
<!--- I am building a query here but normally this would be a query against a categories table --->
<cfset getcategories = querynew("category_id,Name,ParentID")>
<cfset queryaddrow(getcategories)>
<cfset querysetcell(getcategories,"category_id","1")>
<cfset querysetcell(getcategories,"Name","Category1")>
<cfset querysetcell(getcategories,"ParentID","0")>
<cfset queryaddrow(getcategories)>
<cfset querysetcell(getcategories,"category_id","2")>
<cfset querysetcell(getcategories,"Name","Category2")>
<cfset querysetcell(getcategories,"ParentID","1")>
<cfset queryaddrow(getcategories)>
<cfset querysetcell(getcategories,"category_id","3")>
<cfset querysetcell(getcategories,"Name","Category3")>
<cfset querysetcell(getcategories,"ParentID","1")>
<cfset queryaddrow(getcategories)>
<cfset querysetcell(getcategories,"category_id","4")>
<cfset querysetcell(getcategories,"Name","Category4")>
<cfset querysetcell(getcategories,"ParentID","0")>
<!--- Here is where all the magic happens the trick was figuring out that the
"value" attribute in the cftreeitem tag corresponds to the "id" property in the
YAHOO.widget.TreeView.getNodeByProperty() function. That took some digging
but I found it.
--->
<script language="JavaScript">
function catTreeNodeSelection(catID){
tree = ColdFusion.Tree.getTreeObject("categorytree");
me = tree.getNodeByProperty('id',catID);
me.parent.expand();
me.tree.fireEvent("labelClick", me);
}
</script>
<!--- cfajaximport is needed so the cftree will work withing the layoutarea --->
<cfajaximport tags="cftree">
<cflayout type="Border" name="toplevellayout" style="margin:0px;height:400px;">
<cflayoutarea
position="left"
name="treepanel"
title="Document Categories"
size="250"
style="padding-top:3px;"
overflow="auto"
collapsible="false"
splitter="true"
minsize="200">
<cfform>
<cftree name = "categorytree" font = "Arial Narrow" italic="yes" completepath="no" format="html">
<cftreeitem value="0" display="Show All Documents" parent="categorytree" imgopen="folder">
<cfloop query="getcategories">
<cftreeitem
value="#getcategories.category_id#"
display="#getcategories.name#"
parent="#getcategories.ParentID#"
img="folder"
imgopen="folder"
expand="no">
</cfloop>
</cftree>
</cfform>
</cflayoutarea>
<cflayoutarea position="center" name="documentwindow" overflow="hidden">
<!--- I'm using a URL binding on this cfdiv and passing the selected category
tree node so that when a new node is selected the div content --->
<cfdiv bind="url:display.cfm?category_id={categorytree.node}"/>
</cflayoutarea>
</cflayout>
then save the following code as display.cfm:
<cfparam name="url.category_id" default="0">
<cfif url.category_id eq ""><cfset url.category_id = 0></cfif>
<!--- Again, I am building a query here but normally this would be a query against a categories table
and in reall life you would probably add a where clause on this page to only get the categories
where parentID = #url.categoryID# but my cfif later takes care of that for me and this is just
a demo so whatever. --->
<cfset getcategories = querynew("category_id,Name,ParentID")>
<cfset queryaddrow(getcategories)>
<cfset querysetcell(getcategories,"category_id","1")>
<cfset querysetcell(getcategories,"Name","Category1")>
<cfset querysetcell(getcategories,"ParentID","0")>
<cfset queryaddrow(getcategories)>
<cfset querysetcell(getcategories,"category_id","2")>
<cfset querysetcell(getcategories,"Name","Category2")>
<cfset querysetcell(getcategories,"ParentID","1")>
<cfset queryaddrow(getcategories)>
<cfset querysetcell(getcategories,"category_id","3")>
<cfset querysetcell(getcategories,"Name","Category3")>
<cfset querysetcell(getcategories,"ParentID","1")>
<cfset queryaddrow(getcategories)>
<cfset querysetcell(getcategories,"category_id","4")>
<cfset querysetcell(getcategories,"Name","Category4")>
<cfset querysetcell(getcategories,"ParentID","0")>
<cfoutput>
<b>Your are viewing Category #url.category_id#</b><br>
Below are the child categories(if any):<br>
<table>
<cfloop query="getcategories">
<cfif getcategories.parentID eq url.category_id>
<tr>
<td><img src="/CFIDE/scripts/ajax/resources/cf/images/FolderClose.gif" alt="" width="24" height="24" border="0"></td>
<!--- Here is where I call the function that is in the main layout page. --->
<td><a href="javascript:catTreeNodeSelection('#getcategories.category_id#')">#getcategories.Name#</a></td>
</tr>
</cfif>
</cfloop>
</table>
</cfoutput>
- Dave