Saving state with the jQuery Accordion Menu
I have been working on the new True Negative website pretty much non-stop lately and I'm using several differernt things from the jQuery JavaScript library. One of these is the jQuery Accordion Menu, from their User Interface library. It's a great simple menu that can be implemented with very little javascript code.
One thing that it doesn't inherently support is saving the state between webpages, which is something I had wanted since I'm using it as a menu, not just for content display. Functionally, I knew what had to be done in order to get it to save state. It was obvious that I needed to use cookies and some quick javascript to save what menu was open. I then came across the jQuery Cookie plugin, which really simplifies working with cookies in jQuery.
Setting a cookie with the plugin is as simple as follows:
$.cookie('cookiename', 'cookiecontents');
The accordion menu has an event change attribute, which can be set to a function or just inline code. Using both this feature and the cookie plugin, it was very simple to write the code that I needed in order to get the result I wanted. Here is the code and I will explain it below:
// accordion menu
$('#menu').accordion({
header: 'h3',
navigation: true,
active: '.selected',
autoHeight: false,
clearStyle: true,
collapsible: true,
alwaysOpen: false,
animated: 'slide',
change: function(event,ui) {
var hid = ui.newHeader.children('a').attr('id');
if (hid === undefined) {
$.cookie('menustate', null);
} else {
$.cookie('menustate', hid, { expires: 2 });
}
}
});
// check cookie for accordion state
if($.cookie('menustate')) {
$('#menu').accordion('option', 'animated', false);
$('#menu').accordion('activate', $('#' + $.cookie('menustate')).parent('h3'));
$('#menu').accordion('option', 'animated', 'slide');
}
The first section is pretty straightforward. It defines and applies the accordion menu to a div tag with an id of menu. All of the various options are laid out in the Accordion docs and I just set some of the standard ones in order to get the look and feel that I wanted. The important part is the change option:
change: function(event,ui) {
var hid = ui.newHeader.children('a').attr('id');
if (hid === undefined) {
$.cookie('menustate', null);
} else {
$.cookie('menustate', hid, { expires: 2 });
}
Here you can see that I check the value of the menu that is open to see if it is undefined, which would mean the menu is closed. If it is open, it will have a value in there, so I store that in a cookie called "menustate" for use when the page is reloaded.
// check cookie for accordion state
if($.cookie('menustate')) {
$('#menu').accordion('option', 'animated', false);
$('#menu').accordion('activate', $('#' + $.cookie('menustate')).parent('h3'));
$('#menu').accordion('option', 'animated', 'slide');
Upon page reload I have it check the "menustate" cookie to see if it has been set or not. If it is, I first turn off the animation so the visitor does not see it open again, then I call the activate method to open the one with the id that is stored in the cookie. Lastly, I reenable the animation. It works great!
Unfortunately, I have no completed the True Negative site yet, so I do not have an example of this working. As soon as I finish the site, I'll update this blog post with a link to it. Hope this helps anyone trying to do this in a simple way. Thanks for reading!
What I'm Doing...
- Talking business with the MotoOption guys 4 hrs ago
- HoneyBadgerDontCare is rocking Jelli BPM this morning. 8 hrs ago
- shower time! 8 hrs ago
- Dinner with Jeff and Jen! (@ MacGregors' Grill & Tap Room w/ @ericentola) http://t.co/9TBRKIWK 21 hrs ago
- Worrrrkkkkkk (@ Technotic Media) http://t.co/VFxW4pej 2 days ago
- More updates...
Recent Comments
- Manny on Saving state with the jQuery Accordion Menu
- George on Saving state with the jQuery Accordion Menu
- Gautham Sarang on Saving state with the jQuery Accordion Menu
- konteyner on Saving state with the jQuery Accordion Menu
- iceberg on Saving state with the jQuery Accordion Menu
Categories
Pages
Business
- Allstar Graphics
- Allstar Tactical
- Elegance by Technotic Media
- Fanboi Clothing
- ihatestickers.com
- Technotic Media Inc.
- True Negative
Social Networking
Archives
- January 2011
- December 2010
- November 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- November 2007
- July 2007
- June 2007
- March 2007
July 3rd, 2009 - 06:41
cheers for this, saved my bacon
you just need path: ‘/’ in the part that writes, or you end up with multiple cookies
$.cookie(‘menustate’, hid, { path: ‘/’, expires: 2 });
July 3rd, 2009 - 15:09
Thanks for the correction!
August 13th, 2009 - 06:21
Many thanks for sharing.
The variable ‘hid’ never did get a value in my setup (Ubuntu 9.04 Firefox 3.013, jQuery 1.3.2, ui 1.7.2). I have tried different things. this works for me:
jQuery(document).ready(function(){
var drawer = jQuery.cookie(‘accdrawer’);
if(drawer === undefined) {
drawer = “0″;
}
jQuery(‘#accordion’).accordion({
header: ‘h3′,
navigation: false,
active: parseInt(drawer),
autoHeight: false,
clearStyle: true,
collapsibe: true,
alwaysOpen: true,
animated: ‘slide’,
change: function(event,ui) {
var index = jQuery(this).find(“h3″).index(ui.newHeader[0]);
if (index > -1) {
jQuery.cookie(“accdrawer”, index, {path: “/”});
}
}
}
);
});
August 18th, 2009 - 06:31
Example of this working would be really nice, since I just can’t make it work
August 20th, 2009 - 15:32
I know I know! It’s coming soon. I swear!
August 27th, 2009 - 17:09
Thanks Per Jensen,
I didn’t get the cookie thing to work but your solution works like a charm
September 27th, 2009 - 16:14
Per Jensesn,
Thanks for your suggstion. It seems to e working for un-nested accordions, but for nested I’m having trouble as is collapses all as soon as I click on the sub-accordion. Here’s my code:
jQuery(document).ready(function(){
var drawer = jQuery.cookie(‘accdrawer’);
if(drawer == undefined) {
drawer = “0″;
}
jQuery(‘#accordion2′).accordion({
header: ‘h3′,
navigation: false,
active: parseInt(drawer),
autoHeight: false,
clearStyle: true,
collapsible: true,
alwaysOpen: true,
animated: ‘slide’,
change: function(event,ui) {
var index = jQuery(this).find(“h3″).index(ui.newHeader[0]);
if (index > -1) {
jQuery.cookie(“accdrawer”, index, {path: “/”});
}
}
});
});
Main
Search
Test
Review
Database
Summary
Dashboard
Summary
October 29th, 2009 - 18:55
Hi Mike,
Thanks for the code.
Any news on when you might have a working example?
October 30th, 2009 - 13:06
Working example is up (unofficially) at http://www.truenegative.com
Take a look and let me know what you think!
November 6th, 2009 - 07:05
Thanks for article.
How to store nested list accordions ?
In you example http://www.truenegative.com you have 1 level accordion with
Here it is nested list accordion – http://blog.evaria.com/wp-content/themes/blogvaria/jquery/index-multi.php
Any ideas?
Thank you for answer
November 18th, 2009 - 18:09
Setting the navigation attribute to true will let the accordion automatically handle this for you.
From jQuery Documentation:
navigation
Type:Boolean
Default:false
If set, looks for the anchor that matches location.href and activates it. Great for href-based state-saving. Use navigationFilter to implement your own matcher.
November 18th, 2009 - 18:23
Right, that will work for having the anchor tag in the address bar. Using a cookie circumvents that. I can’t remember why I didn’t want it in the address bar, but it will come to me haha.
January 11th, 2010 - 03:34
Your site was extremely interesting, especially since I was searching for thoughts on this subject last Thursday.
I’m Out!
September 3rd, 2010 - 11:47
thanks for sharing, just a little bug, pay attention, in the code is written “collapsibe” instead of “collapsible”.
September 23rd, 2010 - 08:09
Thanks, your article saved my day! And another big thanks to HelpSeeker, as it was his posted changes which made it all work.
October 4th, 2010 - 11:20
@maumau Thanks! Fixed the typo
October 17th, 2010 - 15:04
Hi,
thanks for the cue.
I´ve found one bug – when I implemented thi code to my site, it was working fine, but sometimes, the active field collapsed back to “inactive” state. So I was trying to fix it and there is the solution. If you are experiencing the same, set the parameter “Navigation” to false value.
November 27th, 2010 - 02:27
Very useful and thanks very much for sharing.
December 27th, 2010 - 15:10
Any idea on how to have this work per page? If I copy this page into a new page, jq and all, it reads the cookie. If a site uses multiple accordions this is not how it should work.
April 8th, 2011 - 08:50
How can I make this accordion move more smoothly?
It’s ok when it’s opening but when closing a panel it’s not smooth at all.
August 3rd, 2011 - 13:22
Nothing I found here worked for my particular installation. I developed my own way using the index, if anyone finds this useful:
$(document).ready(function() {
$(‘#accordion’).accordion({
autoHeight: false,
collapsible: true,
active: false,
change: function(event,ui) {
var index = ui.options.active;
if (index > -1) {
$.cookie(‘accidx’, index, {expires: 2, path: ‘/’});
}
}
});
if ($.cookie(‘accidx’) > -1) {
var idx = Number($.cookie(‘accidx’));
$(‘#accordion’).accordion(‘option’, ‘animated’, false);
$(‘#accordion’).accordion(‘activate’,idx);
$(‘#accordion’).accordion(‘option’, ‘animated’, ‘slide’);
}
});
September 21st, 2011 - 02:54
Here’s a working example (except for the cookie getter/setter)
jQuery(document).ready(function() {
var selected = readCookie(‘activeMkt’);
var select = -1;
if (selected){
select = parseInt(selected);
}
$( “#accordion” ).accordion({
header: ‘h3′,
autoHeight: false,
navigation: true,
collapsible: true,
alwaysOpen: false,
animated: ‘slide’,
active: select,
change: function(event,ui) {
var sel = ui.newHeader.children(‘a’).attr(‘id’);
if (sel === undefined) {
setCookie(‘activeMkt’,'-1′);
} else {
setCookie(‘activeMkt’,sel);
}
}
});
});
EINS
EIN
ZWEI
ZWE
DREI
DRE
October 1st, 2011 - 10:21
thanks for your sharing,I use accordion menu on my website…
October 2nd, 2011 - 11:14
I am very much new to Jquery. what I want is something very simple. Could anyone please tell me how to achieve this.
I have two menu’s which needs to be ‘remembered’ by the browser.
1. A menu that is hidden initially and shown when clicked on a link
2. I have put ‘help-hints’ allover the site. There is a button to hide the hint icons.
What I want is : Once that main menu is shown, it should stay shown while browsing through the pages. Same with the hint icons. When someone clicks on the link that hides/shows the hint icons, they should get hidden/displayed.
The following is my code :
JQuery :
jQuery(‘.slideout’).click(function() {
jQuery(‘.sf-green’).slideToggle();
jQuery(‘.slideout, .slidein’).toggleClass(‘slidein slideout’);
});
jQuery(‘#infobutton’).click(function(){
jQuery(‘.info_on, .info_off’).toggleClass(‘info_off info_on’);
jQuery(‘.hint, .hintoff’).toggleClass(‘hintoff hint’);
});
HTML
Main Menu
Help »
Any help will be great!
Thank you!
November 23rd, 2011 - 06:32
Thank you so much! you saved my day on implementing this in my website haha love you~
November 25th, 2011 - 08:53
Useful and brilliant thank you for sharing this. save me today this did.