Accordion Menu in MadCap Flare - Part Four

UPDATE - Thanks to Nita Beck for pointing out the WordPress-introduced weirdness in the script in this section. I've changed the content so that you can now download the script rather than create it from scratch. I still recommend that you read through this section so that you understand how the script works.This is Part 4 of a series of posts on how to create the following layout, complete with accordion menu and slide-in drill-down menu, in MadCap Flare.

Flare with Accordion Menu

If you missed the previous parts, here are links:

Menu Proxy to Foundation Menu Script

The menu proxy in Flare creates a regular ul list based on the toc. The output from the menu proxy looks like this:

<div id="menu"><ul class="menu _Skins_Menu"><li class="has-children"><a href="#" class="selected">Sect A (book)</a><ul class="sub-menu"><li><a href="#" class="selected">Sect A</a></li><li class="has-children"><a href="Topic A.htm">Sect A - Topic A (book)</a><ul class="sub-menu"><li><a href="Topic A.htm">Sect A - Topic A</a></li>

You can see that the unordered list class is named 'menu_Skins_Menu', book-level entries are li class="has-children", sub-levels are in a ul class named "sub-menu", and options are regular <li> entries. There is a 'selected' class for the currently selected option.

Flare Menu Proxy Output

If you take a look at the Foundation accordion menu documentation, it says that the menu needs to use classes named like this:

<ul class="vertical menu" data-accordion-menu><li><a href="#">Item 1</a><ul class="menu vertical nested"><li><a href="#">Item 1A</a></li><li><a href="#">Item 1B</a></li></ul></li><li><a href="#">Item 2</a></li></ul>

And the classes needed for the Foundation drill-down menu are:

<ul class="vertical menu" data-drilldown><li><a href="#Item-1">Item 1</a><ul class="vertical menu"><li><a href="#Item-1A">Item 1A</a></li><!-- ... --></ul></li><li><a href="#Item-2">Item 2</a></li></ul>

The classes needed for the Foundation menus are different to the classes that the Flare menu proxy creates. That's why we need a script to make changes to the menu proxy output. Luckily for us, the classes for the Foundation menus are pretty similar, so that's going to make the script a bit easier to work with.To add the script:

  1. In Flare's Content Explorer, right-click on the Resources folder.
  2. Select New>Folder to create a new folder. Give the new folder the name: Scripts.
  3. Get the following jQuery script, created by Dave Lee:foundation-menu-off-canvas-initialisation.The script should look like this (but with Dave's comments in place):$(document).ready(function() {$("#nav-accordion ul.menu").removeClass("_Skins_Menu");$("#nav-accordion ul.sub-menu").addClass("menu vertical");$("#nav-accordion .selected").parents("ul").addClass("is-active");$("#nav-accordion>ul").clone().appendTo("#nav-drilldown");$("#nav-accordion ul.sub-menu").addClass("nested");$("#nav-accordion>ul").addClass("menu vertical").attr("data-accordion-menu", "").attr("data-multi-open", "true");$("#nav-drilldown>ul").addClass("menu vertical").attr("data-drilldown", "");$("#nav-drilldown, #nav-accordion").css("display", "block");$(document).foundation();});
  4. Copy the foundation-menu-off-canvas-initialisation.js file into the Scripts folder that you created in Flare.If you want, you can give the file a different name (but it needs the .js extension). If you use a different name, you will need to make sure any references to the foundation-menu-off-canvas-initialisation.js script are changed to the same name as your file. You should have referenced the script when creating the master page in part three.

You now have the script. Let's look more closely at what it does.

How the Script Works

In the original script file, which I hope to share in a downloadable project, Dave has commented the script. I've only removed the comments here, because I'm going to quickly go through each part of the script.

$(document).ready(function() {

The code above begins our script, and (as far as I know) is common to all scripts.

$("#nav-accordion ul.menu").removeClass("_Skins_Menu");

The next part of the script selects the 'nav-accordion ul.menu' part of the Flare output pages, and removes the Skins_Menu class, which is the 'Menu' stylesheet. The nav-accordion part of the page is the container for the accordion menu, and the ul.menu is the menu in it.

navigation menu ul

If your stylesheet for the menu is called something else, you will need to enter ("_Skins_your menu skin name") instead. For example, if your menu skin is called OrangeMenu, you would enter ("Skins_OrangeMenu"). By removing the skin class, you take out a lot of the formatting that Flare applies to the menu proxy output. A lot of, but not all. The remaining parts you can override in the stylesheet.Next, we have:

$("#nav-accordion ul.sub-menu").addClass("menu vertical");

This part of the script finds all of the ul.sub-menu classes in the nav-accordion part of the page, and adds the 'menu' and 'vertical' classes to them. The 'menu' and 'vertical' classes are needed by the Foundation menu.For the next part, we have:

$("#nav-accordion .selected").parents("ul").addClass("is-active");

The Flare menu uses 'selected' to indicate which topic is currently selected. So what's happening with this part of the script is: find the 'selected' class in the nav-accordion div, locate the parent uls of that topic, and then add the 'is-active' class to those uls. This sets the accordion menu to open at the selected current topic. (The instructions at Foundation accordion menu documentation tell us that the is-active class is needed).That's the Foundation accordion menu almost done - we still need to do the indenting and some formatting, but that's going to come later in the script. Before we get to that, we need to sort out the drill-down menu. Remember that in the Master Page (see Part 3), we didn't add a menu proxy for the drill-down menu, because we are going to copy the menu we have already modified for the Accordion menu. That's what the next line of the script does:

$("#nav-accordion>ul").clone().appendTo("#nav-drilldown");

Here, we are finding the ul in the nav-accordion div. That's the ul we have already converted from Flare menu proxy classes to the classes needed for the Foundation accordion menu. Once the ul is found, the next thing to do is copy it (clone), and add (appendTo) the copied ul to the 'nav-drilldown' div. The 'nav-drilldown' div is the empty div we created in the Master Page to contain the drill-down menu.Okay, so now back to the accordion menu.$("#nav-accordion ul.sub-menu").addClass("nested");With this line, we are finding the sub-menu class in the nav-accordion ul class. The sub-menu class is created by the Flare menu proxy and we are adding the 'nested' class to indent the accordion sub-menu items. Again, the use of the 'nested' class for indentation is specified in the Foundation accordion menu documentation.It's important to note that the indentation is added after the menu is cloned for the drill-down menu. This is because we only want indentation on the accordion sub-menus, not the drill-down menu sub-menus. The script runs in order from top to bottom, so if you cloned the menu after adding the 'nested' sub-menu class, both menus would have indented sub-menus.

Bothmenusindent

Next up is:

$("#nav-accordion>ul").addClass("menu vertical").attr("data-accordion-menu", "").attr("data-multi-open", "true");

This part of the script finds the ul in the nav-accordion div and adds the 'menu vertical' class and data-accordion-menu attribute needed for the Foundation accordion menu. It also adds the data-multi-open attribute and sets it to true. The data-multi-open attribute controls whether multi-levels of the accordion menu can be open at the same time (true is yes, false is no).That's the accordion menu pretty much done. On to the drill-down menu:

$("#nav-drilldown>ul").addClass("menu vertical").attr("data-drilldown", "");

This searches the page for the ul in the nav-drilldown div (this div is the container we created for the drill-down menu in the Master Page). It adds the class 'menu vertical' to the ul and the attribute data-drilldown. This class and attribute are required to set the menu to a drill-down menu, as explained in the Foundation drill-down menu documentation.It's important that the menu vertical class and data-drilldown are added after the accordion menu has been cloned into the nav-drilldown div. If they were added before the clone, they would be added to the accordion menu entries, which would result in a mess.Almost done. Next:

$("#nav-drilldown, #nav-accordion").css("display", "block");

This bit of code fixes a problem that also occurs with the smartmenus solution. The problem is known as FOUC, and stands for Flash Of Unstyled Content. As the name suggests, the problem relates to the menu being shown unformatted when the page is first loaded. It quickly becomes formatted when the script kicks in, but the overall effect is just...ugh.Here's what it does:Find the nav-drilldown and nav-accordion divs and hides these divs in the CSS until the scripts have run. When the scripts have run, and our menus are ready for formatting, the display:block part tells the browser to show the divs (and the menus in them). It is important that this part of the script comes after all of the other parts of the menu manipulation.Finally, the script needs to initialise Foundation on the whole document, and that's what this line of the script does:

$(document).foundation();

That's the script finished.In the next post, I will cover the stylesheet and some issues I had when implementing this solution on an old project. But you now have the key parts of the solution: the Foundation files, the master page, the target settings, and the script.

Craig Wright technical author

Craig Wright is an experienced technical writer based in Chesterfield, UK.  He hates writing about himself in the third person, so I shall stop now.

Always interested in new content writing opportunities. Remote working preferred.

Email help@straygoat.co.uk
Phone +44 07954141761

Straygoat Writing Services Ltd
26 Wheatlands Road
Wingerworth
Chesterfield
Derbyshire

Registered Number: 08029184

Straygoat logo design by Bristol graphic designer, Nik Jones.

© Straygoat Writing Services Ltd.