Multilevel (3 depth) jQuery Accordion Side Menu

Do something cool with CMS? Show us ...
This board is for 'Answers', and the discussion of answers... Not for questions.
destinydriven
New Member
New Member
Posts: 3
Joined: Fri Nov 05, 2010 8:41 pm

Multilevel (3 depth) jQuery Accordion Side Menu

Post by destinydriven »

I recently went through a lot of trouble trying to implement a jquery accordion side menu which could go 3 depths and with some help from Dr.CSS I finally got it up and running. Demo can be found  here http://multiintech.com/default/index.php?page=jquery.  I have included all the relevant code below:
Menu template:

Code: Select all

{if $count > 0}
<ul class="acmenu collapsible">
{foreach from=$nodelist item=node}
{if $node->depth > $node->prevdepth}
{repeat string="<ul class='acmenu menuitem collapsible'>" times=$node->depth-$node->prevdepth}
{elseif $node->depth < $node->prevdepth}
{repeat string="</li></ul>" times=$node->prevdepth-$node->depth}
</li>
{elseif $node->index > 0}</li>
{/if}

{if $node->current == true}
<li><a href="{$node->url}" class="currentpage"{if $node->target ne ""} target="{$node->target}"{/if}> {$node->menutext} </a>

{elseif $node->parent == true && $node->depth == 1 and $node->type != 'sectionheader' and $node->type != 'separator'}
<li class="activeparent"> <a href="{$node->url}" class="activeparent"{if $node->target ne ""} target="{$node->target}"{/if}> {$node->menutext} </a>

{elseif $node->type == 'sectionheader'}
<li class="sectionheader"><a href="#">{$node->menutext}</a>

{else}
<li><a href="{$node->url}"{if $node->target ne ""} target="{$node->target}"{/if}> {$node->menutext} </a>

{/if}

{/foreach}

{repeat string="</li></ul>" times=$node->depth-1}</li>
</ul>
{/if}
Now for the actual accordion menu, you will need jquery-1.4.2.min.js or later and your markup should look like the following:

Code: Select all


<ul class="acmenu [optional class] [optional class]">
<li><a href="#">Sub menu heading</a>
<ul>
<li><a href="http://site.com/">Link</a></li>
<li><a href="http://site.com/">Link</a></li>
<li><a href="http://site.com/">Link</a></li>
...
...
</ul>
<!-- This item is open at page load time -->
<li class="expand"><a href="#">Sub menu heading</a>
<ul>
<li><a href="http://site.com/">Link</a></li>
<li><a href="http://site.com/">Link</a></li>
<li><a href="http://site.com/">Link</a></li>
...
...
</ul>
...
...
</ul>

Here is the js you will need for the menu:

Code: Select all



jQuery.fn.initMenu = function() {
    return this.each(function() {
        $('.menuitem', this).hide();
        $('li.expand > .menuitem', this).show();
        $('li.expand > .menuitem', this).prev().addClass('active');
        $('li a', this).click(function(e) {
            e.stopImmediatePropagation();
            var $this = $(this);
            var theElement = $this.next();
            var parent = $this.parent().parent();
            if (parent.hasClass('noaccordion')) {
                if (theElement[0] === undefined) {
                    window.location.href = this.href;
                }
                theElement.slideToggle('normal', function() {
                    var slideThis = $(this);
                    if (slideThis.is(':visible')) {
                       slideThis.prev().addClass('active');
                    }
                    else {
                       slideThis.prev().removeClass('active');
                    }
                });
                return false;
            }
            else if ( theElement.hasClass('menuitem') ) {
                if (theElement.is(':visible')) {
                    if (parent.hasClass('collapsible')) {
                        $('.menuitem:visible', parent).slideUp('normal', function() {
                            $this.prev().removeClass('active');						
                        });
                        return false;
                    }
                    return false;
                }
                else {
                    $('.menuitem:visible', parent).slideUp('normal', function() {
                        $this.prev().removeClass('active');
                    });
					$('ul.menuitem li:has(ul.menuitem)').addClass('parentMenu');  // add different style for items with children
                    theElement.slideDown('normal', function() {
                        $this.prev().addClass('active');
                    });
                    return false;
                }
            }
        });
    });
};

$(document).ready(function() {
    $('.acmenu').initMenu();
});


And here is some sample css to style the menu:

Code: Select all


ul.acmenu, ul.acmenu ul {
  list-style-type:none;
  margin: 0;
  padding: 0;
  width: 15em;
}

ul.acmenu a {
  display: block;
  text-decoration: none;	
}

ul.acmenu li {
  margin-top: 1px;
}

ul.acmenu li a, ul.acmenu ul.acmenu li a {
  background: #333;
  color: #fff;	
  padding: 0.5em;
}

ul.acmenu li a:hover, ul.acmenu ul.acmenu li a:hover {
  background: #000; /*level 1 background hover*/
}

ul.acmenu li ul li a, ul.acmenu ul.acmenu li ul li a {
  background: #ccc;
  color: #000;
  padding-left: 20px;
}

ul.acmenu li ul li a:hover, ul.acmenu ul.acmenu li ul li a:hover {
  background: #aaa;  /* level 3 highlight colour */
  border-left: 5px #000 solid;
  padding-left: 15px;
}
ul.acmenu ul.acmenu li a:hover {
    border-left: 0;
    padding-left: 0.5em;
}
ul.acmenu ul.acmenu {
    border-left: 5px #f00 solid; /* level 3 border highlight*/
}
ul.acmenu a.active, ul.acmenu ul.acmenu li a.active, ul.acmenu a.active:hover, ul.acmenu ul.acmenu li a.active:hover {
    text-decoration: underline;
    background: #c00;  /* active menu background colour */
}


ul.acmenu div.panel a, ul.acmenu div.panel li a:hover  {
    display :inline;
    color: #666;
    background: none;
    margin: 0;
    padding: 0;
    border: none;
    font-weight: bold;
}
ul.acmenu div.panel a:hover {
    color: #000;
    text-decoration: underline;
}

N.B. This menu is not to be used with separators. Actual top level parent menu items are not clickable to carry you to target pages (best used with section headers).

Hope this helps someone with intentions to implement similar functionality in cmsms. Happy developing! Peace!
Last edited by destinydriven on Fri Nov 05, 2010 11:21 pm, edited 1 time in total.
nockenfell
Power Poster
Power Poster
Posts: 751
Joined: Fri Sep 12, 2008 2:34 pm
Location: Schweiz / Switzerland

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by nockenfell »

Thanks for the demo.  :)
[this message is written with 100% recycled bits]
destinydriven
New Member
New Member
Posts: 3
Joined: Fri Nov 05, 2010 8:41 pm

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by destinydriven »

You're welcome. No probz :D
boby
Forum Members
Forum Members
Posts: 94
Joined: Thu Feb 21, 2008 11:31 pm

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by boby »

This is great, just what I was looking for.

The only thing when I click on a page link, the menu closes itself.

Is it posible to get the menu open to the current page?

May be I missed something... is it easy to emplement?

thanks for any help
User avatar
Dr.CSS
Moderator
Moderator
Posts: 12708
Joined: Thu Mar 09, 2006 5:32 am
Location: Arizona

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by Dr.CSS »

More than likely there may be a way to use one of the calls they have for keeping it open when going to a page, I would have to look thru the JS to see if/what they use to make a menu open to a specific place, they have it in the demo this JS came from...
nicmare
Power Poster
Power Poster
Posts: 1150
Joined: Sat Aug 25, 2007 9:55 am
Location: Berlin

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by nicmare »

Just as a little addition. I realized my own Accordion jquery Script:
http://www.smomkenya.org/
The Advantage: the menu saves its state. if you open a specific page, then the menu link will be opened at startup. maybe this helps someone
boby
Forum Members
Forum Members
Posts: 94
Joined: Thu Feb 21, 2008 11:31 pm

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by boby »

That's what I was looking for!

Can you share the code?
I 'm not doing great with JS
thanks
nicmare
Power Poster
Power Poster
Posts: 1150
Joined: Sat Aug 25, 2007 9:55 am
Location: Berlin

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by nicmare »

you need a simple menu template like this:

Code: Select all

{if $count > 0}
<ul class="menu" id="menu">
{foreach from=$nodelist item=node}
{if $node->depth > $node->prevdepth}
			{repeat string="<ul>" times=$node->depth-$node->prevdepth}
{elseif $node->depth < $node->prevdepth}{repeat string="</li></ul>" times=$node->prevdepth-$node->depth}</li>{elseif $node->index > 0}</li>
{/if}

{if $node->current == true || $node->parent == true}
			<li class="selected"><a href="{$node->url}">{$node->menutext}</a>

{else}
			<li><a href="{$node->url}">{$node->menutext}</a>{/if}{/foreach}{repeat string="</li></ul>" times=$node->depth-1}</li>
</ul>
{/if}
make sure, its the default template.
and some stylesheet

Code: Select all

.navi li a {
	display:block;
	font-family:Georgia, "Times New Roman", Times, serif;
	background:#8D8D8D;
	margin-bottom:2px;
	color:#fff;
	font-size:1.4em;
	font-weight:normal;
	text-decoration:none;
	padding:12px 12px 4px 12px;}
	
.navi li a:hover {
	background:#666}
	
.navi ul ul {
	border-top:1px solid #8D8D8D;}
	
.navi ul ul a {
	background:#ededed url(images/bullet.gif) no-repeat 20px center;
	color:#8D8D8D;
	margin:0;
	font-family:arial, verdana;
	border-bottom:2px solid #fff;
	padding:10px 8px 8px 32px;
	font-size:1.2em;}
	
.navi ul ul a:hover {
	color:#8D8D8D;
	background:#d8d8d8 url(images/bullet.gif) no-repeat 20px center}
	
.navi ul ul li.selected a {
	background:#fff url(images/bullet.gif) no-repeat 20px center}
now call the menu in your maintemplate. i wrapped a div around it.

Code: Select all

<div class="navi">{menu}</div>
now embed javascript library:

Code: Select all

<__script__ type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></__script>	
put it in your own site(template) before .

after that code, insert the javascript call in the template:

Code: Select all

<__script__ type="text/javascript">
/* <![CDATA[ */
$(document).ready(function(){ 
	$('ul.menu ul').hide();
	$('ul.menu').find("li.selected").parent().show();
	$('ul.menu li a').not('ul ul a').click(
		function() {
			var checkElement = $(this).next();
			var parent = this.parentNode.parentNode.id;
			if($('#' + parent).hasClass('noaccordion')) {
				if((String(parent).length > 0) && (String(this.className).length > 0)) {
					$(this).next().slideToggle('normal');
				}
			}
			if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
				if($('#' + parent).hasClass('collapsible')) {
					$('#' + parent + ' ul:visible').slideUp('normal');
				}
				return false;
			}
			if((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
				$('#' + parent + ' ul:visible').slideUp('normal');
				checkElement.slideDown('normal');
				return false;
			}

		}
	);
})
/* ]]> */
</__script>
Last edited by nicmare on Fri Nov 19, 2010 9:25 am, edited 1 time in total.
boby
Forum Members
Forum Members
Posts: 94
Joined: Thu Feb 21, 2008 11:31 pm

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by boby »

Thanks Nicmare!!!

It works like a charm.

It's a two depth level but just fine for me and for SEO.

My Jquery tabs don't work anymore but I'll have a siesta and check it later on.
Thanks
nicmare
Power Poster
Power Poster
Posts: 1150
Joined: Sat Aug 25, 2007 9:55 am
Location: Berlin

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by nicmare »

keep care that you embed jquery library just one time! so if you have already jquery in your template, then leave the jquery google link!
you can easly add more depths. you just have to write more CSS ;-)

PS: Sorry, you do not need the cookie javascript. its a long time ago i developed the site ;-)
Last edited by nicmare on Fri Nov 19, 2010 9:24 am, edited 1 time in total.
concentre
New Member
New Member
Posts: 8
Joined: Tue Dec 21, 2010 4:55 am

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by concentre »

Nicmare -- your accordion menu is exactly what I have been looking for. I've got it working, but am a newbie and am wondering how to add another sub level? You said add more CSS, I tried this and the menu will not display the 3rd level. Do I need to add something to the javascript?

Any help you can offer would be very appreciated.

Thx.
nicmare
Power Poster
Power Poster
Posts: 1150
Joined: Sat Aug 25, 2007 9:55 am
Location: Berlin

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by nicmare »

if you post a link to the site i could take a look…
concentre
New Member
New Member
Posts: 8
Joined: Tue Dec 21, 2010 4:55 am

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by concentre »

Here's the link to the site in development:

http://dev.concentre.us/federalcms/inde ... d-overview

There are 5 links that should be below Bakery & Deli. Ideally, when you click Bakery & Deli the next level would drop down. The way it stands the menu wont display this level at all.

Any suggestions?
nicmare
Power Poster
Power Poster
Posts: 1150
Joined: Sat Aug 25, 2007 9:55 am
Location: Berlin

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by nicmare »

what happens when u edit this line

Code: Select all

$('ul.accordion li a').not('ul ul a').click(
to

Code: Select all

$('ul.accordion li a').click(
?
concentre
New Member
New Member
Posts: 8
Joined: Tue Dec 21, 2010 4:55 am

Re: Multilevel (3 depth) jQuery Accordion Side Menu

Post by concentre »

Nothing. It stays exactly the same.
Post Reply

Return to “Tips and Tricks”