Ask a Jedi: Delaying CFMENU

This post is more than 2 years old.

Ronald asks:

Ray, I am new to ColdFusion (and web programming) and really like the new CF8 menu tags. I am using a horizonal menu on a site I am developing and on one page I have embedded a google calendar. It works great except that it takes a couple of seconds to get the google calendar and during that time the menu gets a little crazy and show the menu items in horizonal fashion. It only lasts a second or 2, but is enough to be an annoyance. Do you have any suggestions? Is there a way to turn off the menu until after the page content appears?

Absolutely. Don't forget that you can embed items on a page via the CFDIV tag. Consider this simple example:

<!--- Menu ---> <cfdiv id="menuDiv" />

<p> Normal content... </p>

When rendered, all you will see is "Normal content..." because we didn't actually load anything into menuDiv. ColdFusion makes it easy to load the content though via the ColdFusion.navigate function:

ColdFusion.navigate('menu.cfm','menuDiv');

Where menu.cfm is simply your menu. Here is what I used:

<cfmenu name="mainMenu" selectedFontColor="white" selectedItemColor="red"> <cfmenuitem display="Alpha" href="foo" /> <cfmenuitem display="Geta" href="foo" /> <cfmenuitem display="Gamma" href="foo" /> </cfmenu>

The only thing you have to remember is to use the CFAJAXIMPORT tag in your main page. This "warns" ColdFusion that it will be using a feature at some point that requires particular JavaScript files. Here is the complete sample file I used.

<cfajaximport tags="cfmenu"> <html> <head> <script> function loadMenu() { ColdFusion.navigate('menu.cfm','menuDiv'); } </script> </head>

<body>

<!--- Menu ---> <cfdiv id="menuDiv" />

<cfset sleep(2000)> <p> Normal content... </p>

</body> </html>

<cfset ajaxOnLoad("loadMenu")>

In my code, I used a sleep() call to represent the 'slow' Google Map. I told the page to run loadMenu when done. You would need to change this to find some other way to see if your Google Map is done. All loadMenu does then is load the menu into the div.

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 Joshua Michael Hublar posted on 3/17/2008 at 1:57 AM

This is a great technique. . . It really makes a page come in a lot cleaner. I would like to offer a warning, though: The script that invokes the ColdFusion.navigate portion *must* be in the head portion of your template or it won't work.

Comment 2 by Conrad posted on 4/5/2008 at 12:17 AM

Hi raymond,

I want to use the Spry accordion widget inside a CFDIV tag, like this:

menu.cfm:

<div id="Accordion1" class="AquaAccordion" tabindex="0">
<div class="Panel">
<div class="Tab">
<div class="Label">Panel 1</div>
</div>
<div class="Content">
...
</div>
</div>
<div class="Panel">
<div class="Tab">Panel 2</div>
<div class="Content">
...
</div>
</div>
</div>

menu_call.cfm

<html>
<head>
<script src="SpryAssets/SpryAccordion.js" type="text/javascript"></script>
<link href="SpryAssets/SpryAccordion.css" rel="stylesheet" type="text/css">
</head>
<body>
<cfajaximport>

<cfset ajaxonload("sp2")>
<cfdiv bind="url:menu.cfm"/>

<script type="text/javascript">
<!--
var sp2 = new Spry.Widget.Accordion("Accordion1");
//-->
</script>
</body>
</html>

What I do it wrong?

Thanks,

Conrad

Comment 3 by Raymond Camden posted on 4/7/2008 at 8:27 PM

I have not messed with mixing Spry and CF's Ajax features. Sorry.

Comment 4 by Ramesh Sabetiashraf posted on 6/22/2008 at 3:14 AM

I've been struggling with the same issue until I ran into this blog today. Interesting work around, but a problem with CFDIV binding is loss of search engine visibility (i.e., search engines won't see your main navigation and may not index your site properly.)

So here's what I came up with after playing with CSS. It does keep the menu search engine optimized.

<head>
<style type="text/css">
/* this should stop the horizontal menu from showing vertically (until the page load is complete) */
#topmenu li {
display:inline;
}

/* use this to ensure submenus aren't displayed horizontally */
#topmenu li li {
display:list-item;
}
</head>

<cfmenu name="topmenu" type="horizontal">
...
</cfmenu>

Cheers,

Ramesh.