jQuery experiments: Nested Accordion

the script

v.1.4.7.4 – updated for jQuery v. 1.9

The Nested Accordion plugin provides support for unlimited number of levels.

The plugin could easily be customized and used with any website.

It allows multiple instances of the accordion on the same page.

There is an option to open the sections when a click or a hover event occurs. Thus, if we override the default event:click with event:hover, every item could be a link which is followed whenever the link is clicked and the nested levels are expanded whenever a hover event occurs.

If the accordion is used for site navigation, the plugin saves the state of the menu for whatever level it is expanded. The default option expandSub:true forces the sub-list under the 'current' item to be expanded on page load.

There is an option to shift the clicked item to the first position.

If, during the accordion animation, the newly opened section is about to be pushed behind the top edge of the screen, the plugin will reposition it near the top of the viewport. This animation function is called only if needed, usually, if we have a long content inside the collapsible elements.

The functionality is keyboard accessible.

Three demonstrations are included in demo1. The accordions in the Side Column, based on nested lists, can be used for site navigation. The sub-list with the anchor whose target matches the current location is initially expanded. For the two accordions in the Main Content Column, some of the default options are overridden (see below).

The animations in demo2 are activated whenever the mouse hovers over the links. The first example is a simple one-level accordion, that uses the option collapsible:false which forces one section to be open at any time. The second example can be used for site navigation.

The first two examples in demo3 have standard expand/collapse functionality (standardExpansible:true), instead of accordion functionality. They also use the expandAll plugin.

In demo4, the accordion is initialized with the option shift:'all', so when an item is clicked, the clicked item and all following siblings will be moved to the top.

In demo5, the accordion animations are triggered by clicking the icons

Getting started:

Overview

This plugin creates 'accordion' functionality on a hierarchically structured content (multilevel content), based on nested lists or nested div-s (see section 'Example markup' below). It requires jQuery v1.4.3+.

If we want to initialize two or more accordions residing in a given section with just one call, we have to call the plugin on the ID of their common container, e.g. $('#container').accordion(); The accordions should have class="accordion" (we can override this class name).

We can call the plugin on the ID of the accordion element itself, e.g. $('#acc1').accordion({container:false});

The plugin has many options you can pass in at initialization (see section 'Usage' below).

The default options are for standard unordered lists.

The script generates <a>-tags with class="trigger" around the text nodes in LI elements or headings. These A elements are the triggers that handle the toggle action on the next collapsible sections.

If you use headings to show/hide the collapsible elements, you need to pass in an override option, for example, head:'h2, h3'. The script adds class="h" to the specified headings. So you should pass in the option el:'.h'.

If the structure is based on nested div-s and headings, the script wraps each pair of heading and next collapsible div in <div></div>. You need to pass in the option wrapper:'div'

If the collapsible element is a div, the script wraps it in <div class="outer"></div>. You need to pass in the option next:'div.outer'

See more in section 'Usage'.

Example markup

Nested Lists
<ul class="accordion">
    <li> Item 1
        <ul>
            <li> Sub 1.1
                <ul>
                    <li> Sub 1.1.1 </li> ...
                </ul>
            </li> ...
        </ul>
    </li> ...
</ul>
Nested Lists + Headings + DIVs
<ul class="accordion">
    <li>
        <h2>Heading</h2>
        <div>Some content here ... (optional)
            <ul>
                <li>
                    <h3>Heading</h3>
                    <div>Some content here ... </div>
                </li> ...
            </ul>
        </div>
    </li> ...
</ul>
Nested DIVs + Headings
<div class="accordion">
    <h2>Heading</h2>
    <div>Some content here ... (optional)
            <h3>Heading</h3>
            <div>
                Some content here ...
            </div>
            ...
    </div> 
    ...
</div>

Usage

Options
  • container : true, // {true} if the plugin is called on the closest named container, {false} if the pligin is called on the accordion element
  • obj : 'ul', // the element which contains the accordion - 'ul', 'ol', 'div'
  • objClass : '.accordion', // the class name of the accordion - required if you call the accordion on the container
  • objID : '', // the ID of the accordion (optional)
  • wrapper : 'li', // the common parent of 'a.trigger' and 'o.next' - 'li', 'div'
  • el : 'li', // the parent of 'a.trigger' - 'li', '.h'
  • head : '', // the headings that are parents of triggers (if any)
  • next : 'ul', // the collapsible element - 'ul', 'ol', 'div'
  • iconTrigger : false, // {false}, {true}
  • initShow : '', // the initially expanded section (optional)
  • expandSub : true, // {true} forces the sub-content under the 'current' item to be expanded on page load
  • showMethod : 'slideDown', // 'slideDown', 'show', 'fadeIn', or custom
  • hideMethod : 'slideUp', // 'slideUp', 'hide', 'fadeOut', or custom
  • showSpeed: 400,
  • hideSpeed: 800,
  • scrollSpeed : 600, //speed of repositioning the newly opened section when it is pushed off screen.
  • activeLink : true // 'true' if the accordion is used for site navigation
  • event : 'click', // 'click', 'hover'
  • focus : true, // it is needed for keyboard accessibility when we use {event:'hover'}
  • interval : 200, // time-interval for delayed actions used to prevent the accidental activation of animations when we use {event:hover} (in milliseconds)
  • collapsible : true // {true} - the accordion is fully collapsible, 'false' - one section is open at any time
  • standardExpansible : false, // if {true}, the functonality will be standard Expand/Collapse without 'accordion' effect
  • lastChild : true, //if {true}, the items without sub-elements will also trigger the 'accordion' animation
  • shift : false, // false, 'clicked' or 'all' *
  • elToWrap : null // null, or the element, besides the text node, to be wrapped by the trigger, e.g. 'span:first'
  • uri : 'full', // 'full' if you use absolute paths. 'relative' - if you use relative paths in a navigation accordion - specify splitUrl option below
  • splitUrl: '/', // If you use relative paths in a navigation accordion, specify a symbol '/', '?', '#', etc.
  • retFunc : null

* If shift:'clicked', the clicked item will be moved to the first position inside its level, if shift:'all', the clicked item and all following siblings will be moved to the top.

Invoking the plugin

To call the plugin, add the following code in a $(document).ready() function inside the <head> of your HTML document:

1. To create accordions with different options in two different divisions of the page (for example #side and #main), you'll add a code like this:

$('#side').accordion(); // uses all default options

$('#main').accordion({el:'.h', head:'h2, h3', next:'div', initShow:'div.outer:eq(1)'});

2. To override some options for a specific element, specify the ID:

$('#acc3').accordion({container:false, initShow:'#current'});

$('#acc2').accordion({container:false, obj:'div', wrapper:'div', el: '.h', head:'h2, h3', next:'div.outer'});

3. We can globally override the defaults:

$.fn.accordion.defaults.container = false;

$.fn.accordion.defaults.initShow = '#current';

Necessary files to reproduce the demos on your computer:

Place the script in a directory scripts and the images in a directory img, or edit the paths in the HTML documents as needed.

  1. DEMO 1
  2. DEMO 2
  3. DEMO 3
  4. DEMO 4
  5. DEMO 5
  6. jquery.nestedAccordion.js
  7. plus.gif
  8. minus.gif

If you find a bug or have a suggestion/request, please send me an e-mail. I apologize if sometimes, because of limited time, I can't respond to all requests or my responses are delayed.

If some of my scripts have been useful to you and you would like to thank me, feel free to donate any amount you wish. Thanks :)