How to keep accordion drop-down menu open when opening a new page?

Hi,
I can’t seem to figure out how to keep my accordion drop-down menu open when loading a new page. Here’s my site I’m working on:

http://www.kainproductions.com/photography/

For example I want it so when I select a link from a drop down category I want the containing category to stay open when loading the new page until I decide to select a link from a different category. I did a google search and some people suggested cookies to save the state of the menu while others suggested added an script to run on page load. I’m somewhat a JavaScript/Jquery n00b, I’m not sure how to go about any of this.

One other way to do such a thing is to have the server side apply a class to the currently active section (for example if you are on a child page of the “People” category, set the class “active” on the element that contains the accordion for that category)

Definitely cookies and/or [URL=“http://www.jstorage.info/”]local storage could be helpful here. You could store the ID of the currently active accordion whenever it is opened for example.

Thanks. I think I solved it with CSS but another problem has come up. So far I’ve only applied the CSS fix to the people category. I have click on the people category twice to close it. Clicking other categories does not close the one that is open. Does anyone know what I need to modify to make the opened drop-down close when clicking on other categories? It works fine as it should if I don’t click on the people category drop-down.

I took the liberty to fully rewrite your page to use <ul> and <li> which are far more appropriate for this purpose than <div>'s.
This works for me (save it as a file and call it index.php to test this).


<html>
	<head>
		<title>Accordion test</title>
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
		<script type="text/javascript">
			$(document).ready( function() {
				
				// initialize accordion
				$('#Accordion ul').each( function() {
					var currentURI = window.location.href;
					var links = $('a', this);
					var collapse = true;
					for (var i = 0; i < links.size(); i++) {
						var elem = links.eq(i);
						var href = elem.attr('href');
						var hrefLength = href.length;
						var compareTo = currentURI.substr(-1*hrefLength);
						
						if (href == compareTo) {
							collapse = false;
							break;
						}
					};
					if (collapse) {
						$(this).hide();
					}
				});
				
				// on click, show this element and hide all others
				$('#Accordion > li').click( function() {
					var me = $(this).children('ul');
					$('#Accordion ul').not(me).slideUp();
					me.slideDown();
				});
			});
		</script>
</html>
<body>
	<ul id="Accordion">
		<li>
			PEOPLE
			<ul>
				<li><strong>+</strong> <a href="index.php?show=philip&tiffany">PHILIP & TIFFANY</a></li>
				<li><strong>+</strong> <a href="index.php?show=heindo">HEINDO</a></li>            
				<li><strong>+</strong> <a href="index.php?show=juan">JUAN</a></li>
				<li><strong>+</strong> <a href="index.php?show=bettina">BETTINA</a></li>
				<li><strong>+</strong> <a href="index.php?show=adam">ADAM</a></li>
				<li><strong>+</strong> <a href="index.php?show=hazel">HAZEL</a></li>
				<li><strong>+</strong> <a href="index.php?show=ashton">ASHTON</a></li>
				<li><strong>+</strong> <a href="index.php?show=martina">MARTINA</a></li>
				<li><strong>+</strong> <a href="index.php?show=ava">AVA</a></li>
				<li><strong>+</strong> <a href="index.php?show=michelle">MICHELLE</a></li>
				<li><strong>+</strong> <a href="index.php?show=red">RED</a></li>
				<li><strong>+</strong> <a href="index.php?show=erin">ERIN</a></li>
				<li><strong>+</strong> <a href="index.php?show=scotty">SCOTTY</a></li>
			</ul>
		</li>
		<li>
			EVENTS
			<ul>
				<li><strong>+</strong> <a href="#">COMING SOON</a></li>
			</ul>
		</li>
		<li>
			LANDSCAPES
			<ul>
				<li><strong>+</strong> <a href="#">COMING SOON</a></li>
			</ul>
		</li>
		<li>
			INFO
			<ul>
				<li><strong>+</strong> <a href="#">COMING SOON</a></li>
			</ul>
		</li>
	</ul>
</body>
</html>

In essence what it does is when the page is loaded, it walks through all sub-items of the accordion, and then through all links in that sub-item. When it finds a link that has the same URL as the URL of the current page, it stop and go on to the next sub-item. If it doesn’t find such a link it will collapse the current sub-item, in end effect only leaving open the sub item that contains the link to the current page, and collapsing all others :slight_smile:

It would be best if you move the javascript to an external .js file, but for purposes of demonstration I found it easier to leave it inline.

HTH :slight_smile:

Thanks! How do I link or load each individual page? Also how do I make the drop-downs open faster?

Sorry for the late reply, I’ve been kinda busy.

The links can just be regular links, nothing special. The links you had should work fine. If not, please update your website and point me to it so I can have a look.

As for the speed, you can give an argument to slideUp() and slideDown() that indicates how many ms the animation should take. So if you say slideUp(500) the element will slide up in half a second, with slideUp(250) it will take a quarter of a second, etc.

Thanks! I got it working. As for the slideUp argument what would the code look like?

[COLOR=#222222][FONT=Verdana]Would it be like this?

[/FONT][/COLOR]


// on click, show this element and hide all others
$('#Accordion > li').click( function() {
var me = $(this).children('ul');
$('#Accordion ul').not(me).slideUp(500);
me.slideDown(500);
});[COLOR=#222222][FONT=Verdana]
[/FONT][/COLOR]

[COLOR=#222222][FONT=Verdana]

If not, what would the code look like?
[/FONT][/COLOR]

Yup, it would indeed look like that :slight_smile:

Cool. Thank you so much for your help. One last thing. How do I make the Categories clickable so they can close themselves? Say I click on People, it expands, but if I click on People again, it doesn’t close.

Not tested, but this should work


$('#Accordion > li').click( function() {
  $('#Accordion ul').slideToggle(500);
});

instead of


// on click, show this element and hide all others
$('#Accordion > li').click( function() {
  var me = $(this).children('ul');
  $('#Accordion ul').not(me).slideUp(500);
  me.slideDown(500);
});

Hi, that kind of worked but it opens all of drop-downs at once. Also it has a weird drop-down animation.

Try this:


<html>
	<head>
		<title>Accordion test</title>
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
		<script type="text/javascript">
			$(document).ready( function() {
				
				// initialize accordion
				$('#Accordion ul').each( function() {
					var currentURI = window.location.href;
					var links = $('a', this);
					var collapse = true;
					for (var i = 0; i < links.size(); i++) {
						var elem = links.eq(i);
						var href = elem.attr('href');
						var hrefLength = href.length;
						var compareTo = currentURI.substr(-1*hrefLength);
						
						if (href == compareTo) {
							collapse = false;
							break;
						}
					};
					if (collapse) {
						$(this).hide();
					}
				});
				
				$("#Accordion").delegate('span', 'click', function() {
					var ul = $(this).next('ul');
					if (ul.is(':visible')) {
						ul.slideUp(500);
					} else {
						$('#Accordion ul').not(ul).slideUp(500);
						ul.slideDown(500);
					}
				});
			});
		</script>
</html>
<body>
	<ul id="Accordion">
		<li>
			<span>PEOPLE</span>
			<ul>
				<li><strong>+</strong> <a href="index.php?show=philip&tiffany">PHILIP & TIFFANY</a></li>
				<li><strong>+</strong> <a href="index.php?show=heindo">HEINDO</a></li>            
				<li><strong>+</strong> <a href="index.php?show=juan">JUAN</a></li>
				<li><strong>+</strong> <a href="index.php?show=bettina">BETTINA</a></li>
				<li><strong>+</strong> <a href="index.php?show=adam">ADAM</a></li>
				<li><strong>+</strong> <a href="index.php?show=hazel">HAZEL</a></li>
				<li><strong>+</strong> <a href="index.php?show=ashton">ASHTON</a></li>
				<li><strong>+</strong> <a href="index.php?show=martina">MARTINA</a></li>
				<li><strong>+</strong> <a href="index.php?show=ava">AVA</a></li>
				<li><strong>+</strong> <a href="index.php?show=michelle">MICHELLE</a></li>
				<li><strong>+</strong> <a href="index.php?show=red">RED</a></li>
				<li><strong>+</strong> <a href="index.php?show=erin">ERIN</a></li>
				<li><strong>+</strong> <a href="index.php?show=scotty">SCOTTY</a></li>
			</ul>
		</li>
		<li>
			<span>EVENTS</span>
			<ul>
				<li><strong>+</strong> <a href="index.php?show=events-coming-soon">COMING SOON</a></li>
			</ul>
		</li>
		<li>
			<span>LANDSCAPES</span>
			<ul>
				<li><strong>+</strong> <a href="index.php?show=landscapes-coming-soon">COMING SOON</a></li>
			</ul>
		</li>
		<li>
			<span>INFO</span>
			<ul>
				<li><strong>+</strong> <a href="index.php?show=info-coming-soon">COMING SOON</a></li>
			</ul>
		</li>
	</ul>
</body>
</html>

Note I’ve added the <span>'s to the top level menu items, i.e., <span>PEOPLE</span>, <span>EVENTS</span>, etc.
Without these <span>s it will not work.

Thanks, but your code interferes with the gallery sliders and stops them from working.

Looks like you have an old version of jQuery that doesn’t support .delegate.

Try this instead:


$("#Accordion span").click( function() {
	var ul = $(this).next('ul');
	if (ul.is(':visible')) {
		ul.slideUp(500);
	} else {
		$('#Accordion ul').not(ul).slideUp(500);
		ul.slideDown(500);
	}
});

Hi Kain,

I see you found a solution. I’m faced with the same problem. Please could you share with us how you solved it.

Many thanks,

JJ

Sorry that I use this quit old Topic. But I used your script without any problems and I really happy about it. Thank you.
But I would like to do some small changes but I’m not able to do it.
I would like to have that the topics (<spam>topic</spam>) stay open and only close when you click with the mouse.
like on this page: http://claireschvartz.free.fr/

thank you for any advise.
best, carol

nobody has a idea how I could manage this?

Remove the part in red:


$("#Accordion span").click( function() {
	var ul = $(this).next('ul');
	if (ul.is(':visible')) {
		ul.slideUp(500);
	}[COLOR="#FF0000"] else {
		$('#Accordion ul').not(ul).slideUp(500);
		ul.slideDown(500);
	}[/COLOR]
});

Hi Thanks for you answer. I tried but now the menu doesn’t open.
I have to add something like this. But I don’t know how:


item_title.css({cursor:"pointer"}).toggle(
		function () {
			items.show(speed);
		}, function () {
			items.hide(speed);
		}

Right, my bad.
You only need to remove 1 line, the one in red below.
You don’t need .toggle for this. .click works fine here as well, because it finds out what it should do itself.


$("#Accordion span").click( function() {
	var ul = $(this).next('ul');
	if (ul.is(':visible')) {
		ul.slideUp(500);
	} else {
		[COLOR="#FF0000"]$('#Accordion ul').not(ul).slideUp(500);[/COLOR]
		ul.slideDown(500);
	}
});