Article

Build a Dynamic Menu in ColdFusion

Page: 1 2 3

Sample 1

<body <CFIF IsDefined('URL.Div')>  
onload="ShowMenu('<CFOUTPUT>#URL.Div#</CFOUTPUT>')"</CFIF>>  
 
<CFINCLUDE TEMPLATE="modules/menu/create_menu.cfm">

We don’t call the custom tag in the standard <CF_> syntax; instead we call it using <CFINCLUDE>. The tag’s designed to call itself as it builds the tree, so we just need to include the code.

Now, back to the custom tag -- we’ll continue with the ColdFusion code. Section E establishes our variables and queries the database. You’ll notice the query is actually a query of a variable. You can execute this section in whichever way you are most comfortable. I chose to store my initial query as an APPLICATION scoped variable, as the menu data doesn’t change very frequently. Also, because the menu is located on each page of the site, I wanted to spare my database the extra traffic. The last query in Section E creates the application variable.

Section E

<CFPARAM DEFAULT="0" NAME="ATTRIBUTES.MenuID">  
<CFPARAM DEFAULT="" NAME="ATTRIBUTES.DivID">  
<CFPARAM DEFAULT="0" NAME="VARIABLES.LoopCount">  
<CFPARAM DEFAULT="0" NAME="VARIABLES.IncreNum">  
<CFLOCK SCOPE="APPLICATION" TIMEOUT="10" TYPE="READONLY">  
   <CFSET VARIABLES.qGrabMenu = APPLICATION.qGrabMenu>  
   <CFSET VARIABLES.DataSource = APPLICATION.DataSource>  
</CFLOCK>  
 
<CFQUERY DBTYPE="query" NAME="qGetMenuElement">  
   SELECT *    
   FROM VARIABLES.qGrabMenu  
   WHERE Menu_item_ID = #ATTRIBUTES.MenuID#  
   ORDER BY sort_order  
</CFQUERY>  
 
<CFQUERY DATASOURCE="#APPLICATION.DataSource#" NAME="APPLICATION.qGrabMenu" CACHEDWITHIN="#APPLICATION.QueryTimeOut#">  
SELECT    
 menu_item_id,  
       (SELECT menu_item_name FROM MENU_ITEMS WHERE MENU_ITEMS.menu_item_id = menu_items_xref.menu_item_id) AS Parent,  
 (SELECT menu_item_url FROM MENU_ITEMS WHERE MENU_ITEMS.menu_item_id = menu_items_xref.menu_item_id) AS Parentlink,  
 child_id,  
       (SELECT menu_item_name FROM MENU_ITEMS WHERE MENU_ITEMS.menu_item_id = menu_items_xref.child_id) AS Child,  
 (SELECT menu_item_url FROM MENU_ITEMS WHERE MENU_ITEMS.menu_item_id = menu_items_xref.child_id) AS Childlink,  
   sort_order  
   FROM menu_items_xref  
</CFQUERY>

Section F rounds out our code; it’s the final piece of our create_menu.cfm custom tag.
Using recursion, we’re able to build and populate the menu tree with a single custom tag. Create_menu.cfm uses recursion to call itself as a custom tag in order to build sub-branches off the main root menu as needed. When a sub-branch is required, the code calls <CF_create_menu>, which processes the data for the new branch. Should additional sub-branches be needed for an existing sub-branch, the code is called again and recurses another level (or as many levels as required) to create the branch(es). As each level completes, the one above continues on. After all the recursions have run, we’re left with the menu tree.

Section F

<!--- Build menu --->    
<CFLOOP QUERY="qGetMenuElement">  
   <!--- Increment the loop counter --->  
   <CFSET VARIABLES.LoopCount = VARIABLES.LoopCount + 1>  
   <CFIF (qGetMenuElement.childlink NEQ '')>  
       <!--- Last element on a branch --->  
       <CFOUTPUT>  
       <a href="#VARIABLES.RootLevel##childlink#" class="menu"><img src="#VARIABLES.RootLevel#images/transparent.gif" width="9" height="9" border="0" hspace="4">#child#<!--- -#ATTRIBUTES.divID# ---></a><CFIF ATTRIBUTES.divID NEQ ""><CFIF FindNoCase(qGetMenuElement.ChildLink, CGI.PATH_INFO)><script type="text/javascript">ShowMenu('#ATTRIBUTES.divID#');</script></CFIF></CFIF>  
       </CFOUTPUT>  
       <!--- build out branches --->  
   <CFELSE>    
       <CFOUTPUT>  
       <CFSET VARIABLES.IncreNum = "0" & VARIABLES.LoopCount>  
       <CFSET VARIABLES.Num = ATTRIBUTES.DivID & VARIABLES.IncreNum>    
           <a href="##" class="menu" onclick="ShowMenu('#VARIABLES.Num#'); this.blur(); return false"><img src="#VARIABLES.RootLevel#images/right_arrow.gif" name="i#VARIABLES.Num#" width="9" height="9" border="0" hspace="4 /">#child#<!--- -#ATTRIBUTES.divID# ---></a>  
 
           <div id="d#VARIABLES.Num#" class="expand">  
               <CF_create_menu menuID = "#child_id#" divID = "#VARIABLES.Num#" level = "#ATTRIBUTES.Level#">  
           </div>  
       </CFOUTPUT>  
   </CFIF>    
</CFLOOP>  
<!--- Reset the loop counter --->  
<CFSET VARIABLES.LoopCount = 0>

That’s all there is to it! We’ve created a dynamic collapsible tree menu using a database and ColdFusion.

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links

Rate This Article

  • 1
    Poor
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
    Great

Post A Comment

You need to be a member of the SitePoint Forums to comment on this post. Sign Up

Already a member? Post using your SitePoint Forums account: