Accordion menu with Wayfinder using JQuery

From MODx Wiki
Jump to: navigation, search


This wiki has been written in order to elucidate some of the more nefarious issues beginners may encounter when using Wayfinder, with specific reference to an accordion menu. It has been written to complement the previous article posted for an accordion menu with Wayfinder. However, this menu uses the Dynamic Drive accordion menu script and JQuery, rather than script.aculo.us, javascript libraries.

Please read the documentation for Dynamic Drive's Accordion Menu and obtain their two required scripts:

  • ddaccordion.js
  • jquery-1.2.2.pack.js


Contents

Wayfinder Menu Outline

Example of an accordion menu

For the uninitiated, it is perhaps much easier to understand Wayfinder's snippet- and chunk-call system visually rather than textually.

Assuming you have a simple two-level document structure where your document resides in your container then the accordion menu in Wayfinder will reveal the document when the container is clicked. This follows as per the previous accordion menu article, except for several subtle changes. In this example we shall assume that Container 1 (see below) is in fact a document itself (e.g. the Home button on your website) and that a document(s) resides in Container 2 (and therefore requires the accordion effect):

  • Container 1
  • Container 2
    • Document 2.1

An example of this menu and the accordion effect is animated at right. Any number of Documents may reside in a Container, and similarly, any number of Containers (with or without documents) may exist.

Menu HTML

We will now look at the HTML for this menu and how each piece of code relates to Wayfinder's chunk calls. Based on the accordion menu from Dynamic Drive, the HTML controlling our above menu is:

<div class="accordion-menu">
  <ul>
  <li><a class="menuitem" href="#">Container 1</a></li>
  <li><a class="menuitem submenuheader" href="#" >Container 2</a>
    <ul class="submenu">
	    <li><a href="#">Document 2.1</a></li>
    </ul>	
  </li>
  </ul>
</div>
Illustration detailing the Wayfinder Template Parameter chunks required in the accordion menu

Wayfinder has a number of template parameters which control the generation of our menu, using the code that we stipulate. Based on our example menu, the chunks that Wayfinder requires are represented in the illustration at right.

As shown, the menu requires five chunks to be created in order to generate the menu: outerTpl, rowTpl, parentRowTpl, innerTpl and innerRowTpl. As will be seen later, there are also requirements to include chunk calls to highlight the active menus as illustrated in the animation above.

A Brief Menu Dissection

Examining the HTML comprising the outerTpl chunk, the top-level template, we see that the code can be presented as:

<div class="accordion-menu">
  <ul>
    *** REMAINDER OF MENU CHUNKS ***
  </ul>
</div>

Wayfinder treats any part of the menu where an additional chunk is required in the same manner; by simply adding the term [+wf.wrapper+]. Thus, the chunk for outerTpl is simply:

<div class="accordion-menu">
  <ul>
    [+wf.wrapper+]
  </ul>
</div>

Similarly, the innerTpl is therefore:

<ul class="submenu">
	[+wf.wrapper+]
</ul>

Chunks

With a basic understanding of how Wayfinder's template parameters work we can move on to look at each chunk call. We will first set up chunks for the javascript and CSS. These can either be called diectly from your main template (e.g.):

<link rel="stylesheet" type="text/css" href="assets/css/accordion-menu.css" />
<script type="text/javascript" src="assets/js/jquery-1.2.2.pack.js"></script>
<script type="text/javascript" src="assets/js/ddaccordion.js"></script>

or, you can call them as chunks. In this example we will call Dynamic Drive's jquery-1.2.2.pack.js and ddaccordion.js from our main template (as above), but will add the additional required javascript to a chunk, as well as the menu styles.

wfStyle

wfStyle: The CSS classes required to style our menu.

<style type="text/css">
.accordion-menu {
	width:160px;
	font:11px "Verdana";
}
.accordion-menu a.menuitem{
	background:#e5e5e5;
	font:bold 11px "Verdana";
	display:block;
	width:auto;
	padding:3px 0 3px 5px;
	border-top:2px solid #FFFFFF;
}
.accordion-menu li{
	list-style-type:none;
}	
.accordion-menu a.menuitem:visited, .accordion-menu .menuitem:active{
	color:#cc3300;
}
.accordion-menu a.menuitem:hover{
	background:#d8d8d8;
}
.accordion-menu ul.submenu{
	width:auto;
	list-style-type:none;
}
.accordion-menu ul.submenu li{
	text-indent:5px;
	background:#d3d3d3;
	display:block;
	width:auto;
}
.accordion-menu ul.submenu li a{
	text-indent:5px;
	background:#d3d3d3;
	display:block;
	width:auto;
	padding:3px 0 3px 5px;
 	border-top:2px solid #FFFFFF;
}
.accordion-menu ul.submenu li a:hover{
	background-color:#c0bfbf;
}
.activemenu{
	background:#665f6e url("../images/icons/menu-bg.gif") no-repeat right;
	color:#FFFFFF;
	font:bold 11px "Verdana";
	display:block;
	width:auto;
	padding:3px 0 3px 5px;
	border-top:2px solid #FFFFFF;
}
.accordion-menu ul.submenu li a.activemenu{
	background:#8d8793 url("../images/icons/submenu-bg.gif") no-repeat right;
	color:#FFFFFF;
	font:11px  "Verdana";
	display:block;
	width:auto;
	padding:3px 0 3px 5px;
	border-top:2px solid #FFFFFF;
	text-indent:5px;
}
#active-submenuheader{
	background:#665f6e;
	color:#FFFFFF;
	font:bold 11px  "Verdana";
	display:block;
	width:auto;
	padding:3px 0 3px 5px;
	border-top:2px solid #FFFFFF;
}	
</style>

wfJs

wfJs: The small javascript chunk required to initialise menu parameters. For more information see Dynamic Drive.

<script type="text/javascript">
ddaccordion.init({
	headerclass: "submenuheader", //Shared CSS class name of headers group
	contentclass: "submenu", //Shared CSS class name of contents group
	revealtype: "click", //Reveal content when user clicks or onmouseover the header? Valid value: "click" or "mouseover
	collapseprev: true, //Collapse previous content (so only one open at any time)? true/false 
	defaultexpanded: [], //index of content(s) open by default [index1, index2, etc] [] denotes no content
	onemustopen: false, //Specify whether at least one header should be open always (so never all headers closed)
	animatedefault: false, //Should contents open by default be animated into view?
	persiststate: true, //persist state of opened contents within browser session?
	toggleclass: ["", ""], //Two CSS classes to be applied to the header when it's collapsed and expanded, respectively ["class1", "class2"]
	togglehtml: ["suffix", "", ""], //Additional HTML added to the header when it's collapsed and expanded, respectively  ["position", "html1", "html2"] (see docs)
	animatespeed: "fast", //speed of animation: "fast", "normal", or "slow"
	oninit:function(headers, expandedindices){ //custom code to run when headers have initalized
		//do nothing
	},
	onopenclose:function(header, index, state, isuseractivated){ //custom code to run whenever a header is opened or closed
		//do nothing
	}
})
</script>

wfOuter

wfOuter: We need to wrap the menu in a div with a class of "accordion-menu" so that we can style the menu using our wfStyle chunk.

<div class="accordion-menu">
  <ul>
    [+wf.wrapper+]
  </ul>
</div>

wfRow

wfRow: This chunk controls templating of containers which have no child documents (Container 1 in our example). It has the class "menuitem"

<li><a class="menuitem" href="[+wf.link+]" title="[+wf.title+]">[+wf.linktext+]</a></li>

wfParentRow

wfParentRow: This chunk controls the template for containers that hold documents (Container 2 in our example). As we require the accordion menu script to expand and reveal our contained documents it requires the class "menuitem submenuheader" given in the Dynamic Drive javascript libraries. As pointed out previously, the submenu (i.e. our documents) is generated by the code [+wf.wrapper+].

<li><a class="menuitem submenuheader" href="[+wf.link+]" title="[+wf.title+]">[+wf.linktext+]</a>
[+wf.wrapper+]</li>

wfInner

wfInner: This chunk templates the (un-ordered) list style required for the documents in our container. Just as [+wf.wrapper+] was invoked in the previous chunk (wfParentRow), we again call it here to generate the individual documents to be set in the following chunk.

<ul class="submenu">
  [+wf.wrapper+]
</ul>

wfInnerRow

wfInnerRow: This chunk controls the template for our individual documents in a container (Document 2.1 of Container 2 in our example).

<li><a href="[+wf.link+]" title="[+wf.title+]">[+wf.linktext+]</a></li>

wfActiveParentRow

wfActiveParentRow: This chunk controls the template for Containers which have a document currently selected. We use an id call to "active-submenuheader" defined in the CSS chunk in order to maintain functionality of the accordion menu with class "menuitem submenuheader".

<li><a class="menuitem submenuheader" id="active-submenuheader" href="[+wf.link+]" title="[+wf.title+]">[+wf.linktext+]</a>
[+wf.wrapper+]</li>

wfHere

wfHere: This is the template chunk for the currently selected (active) document within a container.

<li><a class="activemenu" href="[+wf.link+]" title="[+wf.title+]">[+wf.linktext+]</a></li>
[+wf.wrapper+]


Wayfinder Call

With all the chunks set-up all we need to do is add a snippet call to Wayfinder with the following parameters:

[!Wayfinder? &startId=`0` &level=`2` &outerTpl=`wfOuter` &parentRowTpl=`wfParentRow` &activeParentRowTpl=`wfActiveParentRow` &innerTpl=`wfInner` &rowTpl=`wfRow` &innerRowTpl=`wfInnerRow` &cssTpl=`wfStyle` &jsTpl=`wfJs` &hereTpl=`wfHere` !]

Your menu should now work like the animation at the top of the page.

Personal tools