The example in the
MODx wiki post on accordion menu with Wayfinder didn’t work for me, so i explored a bit and came up with an alternative solution that uses each menu row’s unique id and some classes to identify which menus to open/close. I like this solution better because:
- it uses standard unordered lists (no divs)
- works with menu items that aren’t folders (weblinks included)
- theoretically, it is extendable to menus over 2 levels deeps, though the js needs some tweaking so the accordion effect on deeper menus doesn’t collide with the top menu one - Help needed on this
- on the whole it seems more understandable to us mere mortals - no offense doze

The js code is pretty ugly and certainly needs cleanup. Besides, I guess it would be better to use mootools/moofx (smaller size), but that’s a bit out of my league for now...
This method does have a problem with IE (slight flickering when animating the effect) that I tried to solve with an init() function - to no avail (it works with FF2.0 tough).
Now for what really matters, the code:
MENU LAYOUT CHUNKS:
wfOuter:
[tt]<ul id="mainMenu">[+wf.wrapper+]</ul>[/tt]
wfRow:
[tt]<li[+wf.classes+]><a href="[+wf.link+]" title="[+wf.title+]" onclick="accordion(’nomenu’)">[+wf.linktext+]</a>
[+wf.wrapper+]</li>[/tt]
wfparentRow:
[tt]<li[+wf.classes+]><a href="[+wf.link+]" title="[+wf.title+]" onclick="accordion(’menu-[+wf.docid+]’)">[+wf.linktext+]</a>
<ul id="menu-[+wf.docid+]">[+wf.wrapper+]</ul></li>[/tt]
wfInner:
[tt][+wf.wrapper+][/tt]
wfInnerRow:
[tt]<li[+wf.classes+]><a href="[+wf.link+]" title="[+wf.title+]">[+wf.linktext+]</a>[+wf.wrapper+]</li>[/tt]
JAVASCRIPT CHUNK (includes prototype and scriptaculous calls, remove them if already called elsewhere on page template)
wfJs:
<script type="text/javascript" src="[(base_url)]manager/media/script/scriptaculous/prototype.js"></script>
<script type="text/javascript" src="[(base_url)]manager/media/script/scriptaculous/scriptaculous.js"></script>
<script type="text/javascript">
function closeVisible() {
var mmenu = document.getElementById('mainMenu');
var mheads = mmenu.getElementsByTagName('li');
for (i = 0; i < mheads.length; i++) {
if (mheads[i].className == 'hasmenu active'){
var smenu = mheads[i].getElementsByTagName('ul')[0];
new Effect.BlindUp(smenu.id, {duration: 0.2});
}
}
}
function accordion(selected) {
if (selected == 'nomenu'){ //if user clicks menu row with no child menu
closeVisible(); //close visible menu
return;
}
else {
if (document.getElementById(selected).parentNode.className == 'hasmenu active') {
return; //if user clicks menu row which is already opened, do nothing
}
else { //if user clicks any other row that has a sub menu
closeVisible(); //close opened menu
new Effect.BlindDown(selected, {duration: 0.2});//open respective menu
}
}
}
function init() {
// quit if this function has already been called
if (arguments.callee.done) return;
// flag this function so we don't do the same thing twice
arguments.callee.done = true;
// process menus
var mmenu = document.getElementById('mainMenu');
var mheads = mmenu.getElementsByTagName('li');
for (i = 0; i < mheads.length; i++) {
if (mheads[i].className == 'hasmenu'){
var smenu = mheads[i].getElementsByTagName('ul')[0];
smenu.style.display = 'none';
}
}
}
/* for Mozilla */
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", init, false);
}
/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
document.write("<script defer src=[(base_url)]assets/templates/ie_onload.js><"+"/script>");
/*@end @*/
/* for other browsers */
window.onload = init;
</script>
This line: [tt]document.write("<script defer src=[(base_url)]assets/templates/ie_onload.js><"+"/script>");[/tt] calls an external file, ie_onload.js that just contains this: [tt]init();[/tt] Still, it doesn’t work...
FINALLY, WAYFINDER SNIPPET CALL (using UltimateParent snippet to search for top container of documents):
[tt][[Wayfinder? &startId=`[[UltimateParent]]` &level=`2` &outerTpl=`wfOuter` &rowTpl=`wfRow` &parentRowTpl=`wfParentRow` &innerTpl=`wfInner` &innerRowTpl=`wfInnerRow` &parentClass=`hasmenu` &hereClass=`active` &lastClass=`` &jsTpl=`wfJs`]][/tt]
That’s it! I’d like to have further input from the js gurus out there with the issues I
mentioned...
Regards,
JP