How can I create page navigation that dynamically highlights the current page?
When displaying navigation to the user, it is a good idea to highlight the current page or section that user is currently viewing. This makes it easier for the user to see where they are in the site. There are a couple of ways this can be done, but here is a simple example. First, consider this simple menu:
<a href="/about.cfm">About Us</a><br>
<a href="/products.cfm">Products</a><br>
<a href="/press.cfm">Press Releases</a><br>
By looking at CGI variables, we can determine which page the user is on and highlight it within the navigation. This version simply add a bold tag to the link:
<a href="/about.cfm"><cfif cgi.script_name is "/about.cfm"><b>About Us</b><cfelse>About Us</cfif></a><br>
<a href="/products.cfm"><cfif cgi.script_name is "/products.cfm"><b>Products</b><cfelse>Products</cfif></a><br>
<a href="/press.cfm"><cfif cgi.script_name is "/press.cfm"><b>Press Releases</b><cfelse>Press Releases</cfif></a><br>
This code could be modified to check for just a folder instead of a specific file name. That would then highlight the section that use is in rather than a specific page.
This question was written by Raymond Camden.
It was last updated on November 24, 2006 at 10:26:30 AM EST.
CFML Referenced
Categories
Comments
Comment made by Armand on November 24, 2006 at 11:40 AM
I've done something similar with javascript. I think the javascript version is easier to implement (and would work regardless of the server model) but would of course fail for those with javascript disabled. See it here: http://blog.richnetapps.com/index.php?title=automatically_highlight_current_page_in&more=1&c=1&tb=1&pb=1
Comment made by Ross on November 24, 2006 at 11:50 AM
If you have a directory structure that has the sections divided into separate folders, and each folder has an index.cfm page. Is there a way to determine if the index.cfm page is the main home page (ie. http://www.yoursite.com/index.cfm)
Comment made by Raymond Camden on November 24, 2006 at 4:20 PM
Ross: Yes. cgi.script_name would have the whole path. So it could be /foo/index.cfm, where foo is the section.
Comment made by Michael Pumo on December 29, 2006 at 10:03 PM
This is a nice idea but I hated the idea of nesting all those cfif blocks. I'm only a novice but I wrote s small function that seems to work fine for me. See below...
<cfscript> function isCurrent(str) {
var page = REReplaceNoCase(cgi.script_name,"/[^>]*/","","ALL"); if (str eq page) { str = ReplaceNoCase(str, "#str#", "<strong>#str#</strong>"); } return str; } </cfscript>
<cfoutput> <ul> <li><a href="index.cfm" title="index">#isCurrent("index.cfm")#</a></li> <li><a href="about.cfm" title="about.cfm">#isCurrent("about.cfm")#</a></li> <li><a href="faq.cfm" title="faq.cfm">#isCurrent("faq.cfm")#</a></li> </ul> </cfoutput>
Hope this helps.
Thanks.
Comment made by Michael Pumo on December 29, 2006 at 10:30 PM
On second thoughts my code above is flawed because the link name as it displays would have to be the same as the template name.
I made an adjustment by adding a new parameter called "disp" (for display), which you can call anything you want.
See below...
<cfscript> // Written By Michael Pumo 30th December 2006 function isCurrent(str,disp) {
var page = REReplaceNoCase(cgi.script_name,"/[^>]*/","","ALL"); if (str eq page) { disp = ReplaceNoCase(disp, "#disp#", "<strong>#disp#</strong>"); } return disp; } </cfscript>
<cfoutput> <ul> <li><a href="index.cfm" title="index">#isCurrent("index.cfm", "Home")#</a></li> <li><a href="about.cfm" title="about.cfm">#isCurrent("about.cfm", "About")#</a></li> <li><a href="faq.cfm" title="faq.cfm">#isCurrent("faq.cfm", "Faq")#</a></li> </ul> </cfoutput>
As you can see this'll work better than the function in my previous post but I'm sure it has more flaws.
Any improvements or recommendations are welcome. I'm pretty much a newbie anyway to be honest!
Thanks.
Michael Pumo.
Comment made by Jeff Knooren on August 9, 2008 at 12:09 AM
Changing the highlight using CSS has the benefit of keeping your HTML looking like HTML and not full of Coldfusion code. That might be an important consideration in a team environment. Here is my method:
<ul> <li id="a_1">something</li> <li id="a_2">something</li> <ul> I give the LI tag an ID with a letter-underscore-number pairing. The underscore is decorative, simply easier for me to read.
Then I set a variable that corresponds to the ID of the LI tag:
<cfset name='request.xfa.TabLevel1' value='1'>
Is used here: a_#request.xfa.TabLevel1# (Or, id="a_1")
There isn't much difference between my method, and those already stated. Except, that renaming pages causes less confusion with tabs suddenly not highlighting due to name changes.
My application has 4 levels of tabs which need highlighting. So, to expand on the above example:
<cfset name='request.xfa.TabLevel1' value='1'> <cfset name='request.xfa.TabLevel2' value='1'> <cfset name='request.xfa.TabLevel3' value='1'> <cfset name='request.xfa.TabLevel3' value='1'>
As you can see, it because quite easy to control exactly what is being highlighted. This is important, because ajax type pages don't reload new page names. Also, coding frameworks like Fusebox don't actually reveal page names to highlight. So basing your highlights on CSS seems to be the better all-round choice.
Comment made by Jeff Knooren on August 9, 2008 at 12:20 AM
Oh, I forgot to mention that (id="a_1", id="a_2", etc...) is the first row of tabs. The second level would start with (id="b_1"), and so on. I've put together a screenshot that shows four levels of highlighted tabs:
http://s27.photobucket.com/albums/c185/compugasm/Miscellaneous/?action=view¤t=Image6.jpg