Simple Code for Generating Multi-Level Divs for Menus

Author Message

Alex Jones

Monday 01 December 2003 7:46:46 am

I have been working on the code that generates our navigation menu system as it is rather large at the moment. I had been using the Tree Menu code as an example, but I think I have found a better method. I am posting the code below to see if anyone can poke holes in it, especially in regards to efficieincy. I know the code generates the proper front-end code as I have thoroughly tested that part.

If this looks like a solid piece of work, I will post a contribution with a proper write-up after any important changes are made.

The code below is meant to generate DIVs which contain links. The DIVs would be controlled by JavaScript and CSS which I have not included at this point, though I will in the final contribution. I have tried to provide appropriate comments, but am more than happy to answer any questions you may have. To see an example of the menu system (though, it uses the old code at the moment) you can see a static version at http://www.agrussell.com

[Code]------------------------------

{* Loop through folders to a depth of four levels *}
{let NavList=fetch( content, list, hash(depth, 4, parent_node_id, 2, class_filter_type, "include", class_filter_array, array(1)))}
{section name=Nav loop=$NavList}
{* This switch statement allows me to use a different class for the first level of menus versus all of the others. It also allows me to use a different naming structure for the first level compared to the other levels. I use different naming conventions as my root node (2) has a really long name that I don't want inserted multiple times within my HTML. Adding additional cases will provide more flexibility should you wish to differntiate between levels in the hierarchy. *}
{switch match=$:item.depth}
{case match=2}<div id="menu-{$Nav:item.name|wash(nospace)}" class="Menu"> {* I use a wash operater dubbed 'nospace' to strip out spaces for use in the ID *}
{/case}
{case}<div id="menu-{$Nav:item.parent.name|wash(nospace)}{$Nav:item.name|wash(nospace)}" class="SubMenu">
{/case}
{/switch}
{* Loops through Folders, articles and some custom classes, sort them by name for display. *}
{section name=NavChild loop=fetch( 'content', 'list', hash(parent_node_id, $Nav:item.node_id, class_filter_type, "include", class_filter_array, array(1,2,10,11,46), "sort_by", array("name", true())))}
{* I have added a checkbox to my folder class which allows me to toggle whether the navigation menus should display the contents within the navigation menu system. This provides a lot of flexibility as I do not want all sub-folders to be treated the same. *}

{* If the folder's contents should be displayed, print out a link which any required JavaScript statements - this would vary depending on the menu code. *}
{section show=eq($:item.object.data_map.navdisplay.data_int,1)}
{* Within the link I detect whether or not the depth is greater than 2. This detection allows me to call the name that matches the ID set in the switch statement above. *}
<a href={concat("/",$:item.url_alias)|ezroot)|ezroot} onmouseover="menu.show('{section show=$:item.depth|gt(2)}{$:item.parent.name|wash(nospace)}{/section}{$:item.name|wash(nospace)}', '{section show=$Nav:item.depth|gt(2)}{$Nav:item.parent.name|wash(nospace)}{/section}{$:item.parent.name|wash(nospace)}', this, 125, 0)" onmouseout="menu.hide('{$:item.parent.name|wash(nospace)}{$:item.name|wash(nospace)}')">{$:item.name|wash} &raquo;</a>{section-else}

{* Otherwise print out a plain link. *}
<a href={concat("/",$:item.url_alias)|ezroot)|ezroot}>{$:item.name|wash}</a>{/section}
{/section}

</div>

{/section}
{/section}
{/let}

[/Code]------------------------------

Thanks!

Alex

Alex
[ bald_technologist on the IRC channel (irc.freenode.net): #eZpublish ]

<i>When in doubt, clear the cache.</i>

Alex Jones

Monday 01 December 2003 7:55:21 am

One Quick note, if you are looking at the source code of the site I posted, all of the menu DIVs are at the bottom of the code.

Alex

Alex
[ bald_technologist on the IRC channel (irc.freenode.net): #eZpublish ]

<i>When in doubt, clear the cache.</i>

jamie harbison

Thursday 03 June 2004 10:48:46 pm

Nice work!!

This is looking really cool, and more or less what i'm looking to implement>>>have you done any further development on the code?

Mark Marsiglio

Thursday 02 December 2004 5:34:58 pm

Alex,

Did you ever get a chance to finish out this menu? I did not see the javascript code or CSS anywhere else, but I am not sure if I am missing it.

It sure would be helpful for the project i am working on right now if it is available...if not the code you provided already will be a good start.

Thanks
Mark

http://www.thinkcreative.com
Turning Ideas Into Strategic Solutions

Alex Jones

Friday 03 December 2004 7:35:56 am

I'm afraid I haven't provided a contribution for this, for several reasons, the foremost of which is time. Sorry. :( I would recommend you adapt the code I provided above to fit the structure of your chosen menu code. If you haven't decided what to use to control the drop downs, here are a couple of recommendations:

<b>Son of Suckerfish Dropdown Menus</b>
Accessible, and only needs 12 lines of JavaScript.I haven't used them yet, but have heard great things.
Site: http://www.htmldog.com/articles/suckerfish/dropdowns/
Example 1: http://www.htmldog.com/articles/suckerfish/dropdowns/example/
Example 2: http://www.htmldog.com/articles/suckerfish/dropdowns/example/vertical.html

<b>TwinHelix FreeStyle Menus</b>
This is a newer version of the script I use on www.agrussell.com. Note, if you want to use it without providing a visible link to the TwinHelix site, you need to make a donation. Personally, I think it is well worth it, as the developer was very responsive and has produced some great code.

What I like about this script over Suckerfish is the delay before a menu disappears. The Suckerfish menus seem a bit too abrupt as they disappear the instant the cursor isn't over them.
Site: http://www.twinhelix.com/dhtml/fsmenu/
Example: http://www.twinhelix.com/dhtml/fsmenu/demo/

Hope that helps. One day, I'll try to put a contribution together.

Alex
[ bald_technologist on the IRC channel (irc.freenode.net): #eZpublish ]

<i>When in doubt, clear the cache.</i>

Xavier Dutoit

Saturday 04 December 2004 1:10:54 am

I don't think the div are the right thing to do to represent a menu. After all, a menu is a multilevel list of links, isn't it ?

I've used this code http://www.csscreator.com/menu/multimenu.php and it works fine. You just need to use css for xhtml compatible browsers and a 10 lines javascript program deals with ie.

For the template code, I simply used three imbricated section loop.

X+

http://www.sydesy.com

Lazaro Ferreira

Saturday 04 December 2004 4:26:14 am

Hi Xavier,

Can you post a sample of your template code to feed the JS popmenu ?

Another question have you tried EZP 3.5 popmenu ?

What do you think about it ?

Lazaro
http://www.mzbusiness.com

Marco Zinn

Saturday 04 December 2004 6:54:11 am

Hi Folks,
just another link:
Eric Meyer (CSS-Guru) shows off a very nice "pure CSS" menu here:
http://www.meyerweb.com/eric/css/edge/menus/demo.html
I was very impressed by this. It's using nested lists (ULs and LIs) with CSS 2.

This means, that the "pure CSS" version does not work (menu's don't popup) in IE's . This is a design-design of Eric, as he wanted to show off a pure CSS solution without the usuall JS stuff.

This might be usefull for site, which can rely on the users having Gecko-Powered browser (like Firefox) or as a starting point for a CSS+JS menu based on lists rather than divs.

Marco
http://www.hyperroad-design.com

Alex Jones

Saturday 04 December 2004 7:37:23 am

Xavier, you are quite right, <i>DIV</i>s are not the way to go. Since I built agrussell.com, I have switched to using nested lists, and highly recommend others do the same. Ultimately though, the concept is the same.

Marco, I am a big fan of Eric Meyer, and actually thought about those menus, but ultimately, I don't think they are ready for production use, quite specifically because they don't work in IE. :( That is one of the reasons I pointed out the Suckerfish menus, as the JavaScript that is included (all 12 lines of it) makes it work in IE, DOM-compatible browsers do not use the JS at all. So, the suckerfish menus are a half way between menu systems that are driven by JavaScript, and those that are driven purely by CSS.

As I mentioned above, I have one issue with the SuckerFish, and Eric Meyer's menu systems: menus disappear the instant the cursor moves away from them. I don't think this is very user friendly, and ultimately can prove very frustrating once a site needs multi-level menus. A user may accidentally move the cursor and have to go find the same spot again, three sub-menus down. If this happens more than once, they will get quite annoyed - well, at least I do.

So, while I am a huge fan of CSS and promote its use everywhere that I can, I don't think it is the best solution for menus. Pure JavaScript menus are not the answer either. It is important to use the technologies for their respective strengths and purposes. In my opinion, the ideal system is a combination of JavaScript to control how the menus work, with CSS to control how the menu style and location.

Sorry to go off on a tangent there, but I think it is applicable to the subject at hand. If not, let me know. :)

Alex
[ bald_technologist on the IRC channel (irc.freenode.net): #eZpublish ]

<i>When in doubt, clear the cache.</i>

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.