# Collapsing - Expanding Navigation List

Check out the menu on the left here:
Welcome to K.Y.P.S.A.H. Pet Services! Keeping Your Pet Safe and Happy!

Click on one of the Items, and you'll see the list expand under it.

Can I do that without CSS? Yep, I confess: I don't know CSS. Whip me!
Can it be done with html?

Thanks!

Last edited by RickJ; Apr 27, 2006 at 02:28 PM.
Search this Question
 LTheobald Posts: 1,051, Reputation: 127 Ultra Member #2 Apr 28, 2006, 07:16 AM
To put it simply - no. You'll need some basic CSS and possible some JavaScript. But don't worry Rick - It's easy! For now look here for some inspiration on what you can do:

Listamatic: one list, many options - Using CSS and a simple list to create radically different list options

Then when I get a second, I'll write you a navigation list and I'll keep it as simple and easy to maintain as possible. I will need your help though. I need you to write a HTML list. It will need to be in this format:
Code :
<ul>
<li>First Level Item A</li>
<ul>
<li>Second Level Item A</li>
<li>Second Level Item B</li>
<li>Second Level Item C</li>
</ul>
<li>First Level Item A</li>
<ul>
<li>Second Level Item A</li>
<li>Second Level Item B</li>
<li>Second Level Item C</li>
</ul>
<li>First Level Item A</li>
<ul>
<li>Second Level Item A</li>
<li>Second Level Item B</li>
<li>Second Level Item C</li>
</ul>
</ul>
 RickJ Posts: 7,762, Reputation: 864 Uber Member #3 Apr 28, 2006, 08:00 AM
This is looking very familiar; like the trick you showed me for here.

Ok, step one, your above code, done, here:
Untitled Document
 LTheobald Posts: 1,051, Reputation: 127 Ultra Member #4 May 2, 2006, 01:36 AM
Rick,

Just to let you know I haven't forgotten you. I'm writing up a guide to how to do this at the moment. It's about 95% done and I'll finish it after work today.

Lee,
 RickJ Posts: 7,762, Reputation: 864 Uber Member #5 May 2, 2006, 02:33 AM
You're awesome, LT!

Hey Google; pick up this: LTheobald is a Website Design Expert and all around great guy! :)
 LTheobald Posts: 1,051, Reputation: 127 Ultra Member #6 May 2, 2006, 03:16 AM
You haven't seen the code yet. I be might have just done an Arnold Rimmer (Red Drawf character) and just repeatedly written "I AM A FISH" for 20 pages :P

Also - not an expert. Still young, lots to learn but I'm always eager to help :)
 RickJ Posts: 7,762, Reputation: 864 Uber Member #7 May 2, 2006, 03:23 AM
LOL.

You've helped me before... and I've learned a lot from reading your posts helping others.
 LTheobald Posts: 1,051, Reputation: 127 Ultra Member #8 May 2, 2006, 01:07 PM
Finally done writing this. I'll attach my test version on the page at the end so you can tinker with that if needs be. Just rename it from testpage.txt to testpage.html to see it in action.

OK. Sorry the reply took so long Rick. We had a 3 day weekend over here in the Uk and I didn't get a chance to get on my PC much. Well I'm on a train to work at the moment so I've got a good amount of time to write up a reply. The code below is similar to what I gave you last time in a way but it will hopefully be a little tidier. I'll also try and write it in a better to understand way. Hopefully...

The code is based on the Suckerfish Dropdown article from A List Apart.

The HTML

The best kind of HTML to use for a navigation bar or some kind is a list. After all, it's just a list of pages. So for this navigation we'll use unordered lists. This way we'll have some nice, clean HTML that should be standards complient and accessible regardless of browser type. So
1. to start off, create a basic web page with this in the body:

Code :
<ul>
<li>Categories
<ul>
<li><a href="">Computing</a></li>
<li><a href="">Geography</a></li>
<li><a href="">History</a></li>
<li><a href="">Science</a></li>
<li><a href="">Sport</a></li>
</ul>
</li>
<li>Members
<ul>
<li><a href="">LTheobald</a></li>
<li><a href="">Rickj</a></li>
<li><a href="">CurleyBen</a></li>
<li><a href="">ScottGem</a></li>
<li><a href="">Orange</a></li>
</ul>
</li>
<li>Tools
<ul>
<li><a href="">Search</a></li>
<li><a href="">Members List</a></li>
<li><a href="">New Posts</a></li>
</ul>
</li>
</ul>
That will give you a 2 level list. It should look like a helper page for AMHD. Now we have the HTML, we want to use some CSS to make this list look more like a series of dropdowns. I'm afraid this is where the CSS comes in. To keep this example simple, we'll keep the CSS styles in HTML page with the code.

2. In the <head> section of the page, enter the following:

Code :
<style>
ul {
margin: 0px;
list-style: none;
background-color: #53BF58;
width: 10em;
}
</style>

This first bit of CSS styles all lists on the page (the <ul> elements) to remove the indentation and bullet points. I've also added a width and some colour in there just to make things a little clearer. The example will now just look like lines of text one under the other. As we want a dropdown list we now have to hide the inner lists (holding the categories, member names and tools in this example). To do this,
3. add the following lines between the style tags under the existing ul {} part:

Code :
li ul {
display: none;
background-color: #86EF8A;
}

This bit of CSS means "For every list (ul) within a list item (li), set it's display to none (hide)". So this will hide all our inner lists. Yet again, a little colour added for clarity.

Now For The Magic

We now have our dropdown list all ready to code. So onto making the lists dropdown. There's two ways of doing this:
1. Having the lists appear when the user hovers over a link
2. Having the lists appear when the user clicks on a link
The code is pretty similar for either one. Now as the Suckerfish Dropdown article already handles what to do when hovering over links, I'll take what to do when the user clicks on the links. Before we can write the code itself we need to write two simple changes to the HTML & CSS we wrote earlier. First, the HTML change. We need to
4. change the root list tag (the very first <ul> tag from:

Code :
<ul>

to

Code :
<ul id="nav">

That will just give us a way of identifying our dropdown list. The CSS change adds a class that shows us which dropdown is currently active.
5. Add the following lines inbetween the style tags

Code :
li.active ul {
display: block;
}

This code will set a list to be shown when it's parent's class is set to active. So for example if we set the Members <li> tag to have a class of active, the members list will be shown. Now it's time to write the code itself.
6. Inbetween the <head> tags for the page, enter the following:

Code :
<script language="JavaScript">
function hideAll() {
var navList = document.getElementById("nav");
for (var i=0; i<navList.childNodes.length; i++) {
var node = navList.childNodes[i];
if (node.tagName == "LI") {
node.className = node.className.replace(new RegExp("\s?active", "i"), "");
}
}
}

var navList = document.getElementById("nav");
for (var i=0; i<navList.childNodes.length; i++) {
var node = navList.childNodes[i];
if (node.tagName == "LI") {
node.onclick = function() {
hideAll();
this.className += " active";
}
}
}
}
</script>

There's two parts to this script. The first function, hideAll(), hides all the lists when shown. A call to this function will ensure that we only have one dropdown shown at a time. The second part sets up what happens when we click on a link.

And That's It

All done. Hopefully now you'll have a dropdown list that'll work in nearly all browsers. I've tested this in IE, Firefox and Opera and it looks just fine.

As always - if you have any questions feel free to ask. All you need to do now is to style it :)
Attached Files
1. testpage.txt (1.9 KB, 1220 views)
2.  RickJ Posts: 7,762, Reputation: 864 Uber Member #9 May 11, 2006, 06:00 AM
Awesome, Lee! I was able to follow along to get it right:
LTheobald is too cool!

I grant that I do not yet fully understand it, but you've given me an excellent tutortial to learn from.

Thank you so much, LT!
 LTheobald Posts: 1,051, Reputation: 127 Ultra Member #10 May 11, 2006, 06:46 AM
Well if there's a certain bit you are unsure about Rick - ask.

Also if you want some extra changes (e.g. click to expand/shrink - at the moment clicking just expands), let me know what you want and I'll see what I can do.
 RickJ Posts: 7,762, Reputation: 864 Uber Member #11 May 11, 2006, 06:54 AM
Actually, you just named #1 of 2 things I was going to do some digging on.

1. I'd like a 2nd click on "categories" for example, to close it back up.

2. When clicking on something under categories, it does close back up, but when a user clicks on something underneath, I'd like it to stay open.

I do love this, though, as it is simple and all in one page, unlike the other one that involved a separate file.
 LTheobald Posts: 1,051, Reputation: 127 Ultra Member #12 May 11, 2006, 08:29 AM
Originally Posted by rickj
1. I'd like a 2nd click on "categories" for example, to close it back up.
Change this bit of code:
Code :
window.onload = function () {
var navList = document.getElementById("nav");
for (var i=0; i<navList.childNodes.length; i++) {
var node = navList.childNodes[i];
if (node.tagName == "LI") {
node.onclick = function() {
hideAll();
this.className += " active";
}
}
}
}

To be:

Code :
window.onload = function () {
var navList = document.getElementById("nav");
for (var i=0; i<navList.childNodes.length; i++) {
var node = navList.childNodes[i];
if (node.tagName == "LI") {
node.onclick = function() {
// Check to see if the item is already active
if (this.className.indexOf("active") >= 0) {
}

// Hide everything
hideAll();

// If the item was already active - don't reshow
this.className += " active";
}
}
}
}
}
Grrr... Couldn't get that to format well
Originally Posted by rickj
2. When clicking on something under categories, it does close back up, but when a user clicks on something underneath, I'd like it to stay open.
Actually, clicking on a sub category doesn't cause the elements to close. It's because the URL's on the page are blank. That's reloading the page and making it appear as if they have been closed. If you change the sub items to either (changes highlighted:

Code :
<li><a href="#">LTheobald</a></li>
Or

Code :
<li><a href="http://www.somewhere.com" target="_blank">LTheobald</a></li>
It'll be fine.
 RickJ Posts: 7,762, Reputation: 864 Uber Member #13 May 11, 2006, 09:07 AM
Thanks, Lee! The open/close works great, and I'm starting to understand a little of it.

I'll take er a bit further and assign some links/play around a bit more.
 RickJ Posts: 7,762, Reputation: 864 Uber Member #14 May 11, 2006, 09:14 AM
On a side note, in the script tag we have ems as the width. I see that I can use px and % also. Are there design or useability reasons to not choose px or %?
 hmartens Posts: 1, Reputation: 1 New Member #15 Mar 16, 2011, 05:43 AM
Comment on LTheobald's post
Originally Posted by LTheobald
Finally done writing this. I'll attach my test version on the page at the end so you can tinker with that if needs be. Just rename it from testpage.txt to testpage.html to see it in action.

OK. Sorry the reply took so long Rick. We had a 3 day weekend over here in the Uk and I didn't get a chance to get on my PC much. Well I'm on a train to work at the moment so I've got a good amount of time to write up a reply. The code below is similar to what I gave you last time in a way but it will hopefully be a little tidier. I'll also try and write it in a better to understand way. Hopefully...

The code is based on the Suckerfish Dropdown article from A List Apart.

The HTML

The best kind of HTML to use for a navigation bar or some kind is a list. After all, it's just a list of pages. So for this navigation we'll use unordered lists. This way we'll have some nice, clean HTML that should be standards complient and accessible regardless of browser type. So
1. to start off, create a basic web page with this in the body:

Code :
<ul>
<li>Categories
<ul>
<li><a href="">Computing</a></li>
<li><a href="">Geography</a></li>
<li><a href="">History</a></li>
<li><a href="">Science</a></li>
<li><a href="">Sport</a></li>
</ul>
</li>
<li>Members
<ul>
<li><a href="">LTheobald</a></li>
<li><a href="">Rickj</a></li>
<li><a href="">CurleyBen</a></li>
<li><a href="">ScottGem</a></li>
<li><a href="">Orange</a></li>
</ul>
</li>
<li>Tools
<ul>
<li><a href="">Search</a></li>
<li><a href="">Members List</a></li>
<li><a href="">New Posts</a></li>
</ul>
</li>
</ul>
That will give you a 2 level list. It should look like a helper page for AMHD. Now we have the HTML, we want to use some CSS to make this list look more like a series of dropdowns. I'm afraid this is where the CSS comes in. To keep this example simple, we'll keep the CSS styles in HTML page with the code.

2. In the <head> section of the page, enter the following:

Code :
<style>
ul {
margin: 0px;
list-style: none;
background-color: #53BF58;
width: 10em;
}
</style>

This first bit of CSS styles all lists on the page (the <ul> elements) to remove the indentation and bullet points. I've also added a width and some colour in there just to make things a little clearer. The example will now just look like lines of text one under the other. As we want a dropdown list we now have to hide the inner lists (holding the categories, member names and tools in this example). To do this,
3. add the following lines between the style tags under the existing ul {} part:

Code :
li ul {
display: none;
background-color: #86EF8A;
}

This bit of CSS means "For every list (ul) within a list item (li), set it's display to none (hide)". So this will hide all our inner lists. Yet again, a little colour added for clarity.

Now For The Magic

We now have our dropdown list all ready to code. So onto making the lists dropdown. There's two ways of doing this:
1. Having the lists appear when the user hovers over a link
2. Having the lists appear when the user clicks on a link
The code is pretty similar for either one. Now as the Suckerfish Dropdown article already handles what to do when hovering over links, I'll take what to do when the user clicks on the links. Before we can write the code itself we need to write two simple changes to the HTML & CSS we wrote earlier. First, the HTML change. We need to
4. change the root list tag (the very first <ul> tag from:

Code :
<ul>

to

Code :
<ul id="nav">

That will just give us a way of identifying our dropdown list. The CSS change adds a class that shows us which dropdown is currently active.
5. Add the following lines inbetween the style tags

Code :
li.active ul {
display: block;
}

This code will set a list to be shown when it's parent's class is set to active. So for example if we set the Members <li> tag to have a class of active, the members list will be shown. Now it's time to write the code itself.
6. Inbetween the <head> tags for the page, enter the following:

Code :
<script language="JavaScript">
function hideAll() {
var navList = document.getElementById("nav");
for (var i=0; i<navList.childNodes.length; i++) {
var node = navList.childNodes[i];
if (node.tagName == "LI") {
node.className = node.className.replace(new RegExp("\s?active", "i"), "");
}
}
}

var navList = document.getElementById("nav");
for (var i=0; i<navList.childNodes.length; i++) {
var node = navList.childNodes[i];
if (node.tagName == "LI") {
node.onclick = function() {
hideAll();
this.className += " active";
}
}
}
}
</script>

There's two parts to this script. The first function, hideAll(), hides all the lists when shown. A call to this function will ensure that we only have one dropdown shown at a time. The second part sets up what happens when we click on a link.

And That's It

All done. Hopefully now you'll have a dropdown list that'll work in nearly all browsers. I've tested this in IE, Firefox and Opera and it looks just fine.

As always - if you have any questions feel free to ask. All you need to do now is to style it :)
HI, thanks it works beautifully!! One question, if I don't want to hide a list when I click on another list... how would I change this piece of code? I want all the list to start minimized but when I click on the different lists, it must not minimized... it must stay expanded. Thanks
 SandpaperSandy Posts: 1, Reputation: 1 New Member #16 May 15, 2012, 11:52 AM
I am so happy to have found this information.

I am getting an an error regarding the childNodes [i]

Unable to get value of the proerty 'childNodes': object is null or undefined

I took your code and pieced it in existing web page I am working on.

Can you help me to understand what the error means and how I can correct.

 Question Tools Search this Question Search this Question: Advanced Search

## Check out some similar questions!

Expanding an existing concrete patio [ 1 Answers ]

I have an existing concrete patio that is less than 6 months old. In my opinion, it is of high quality. It is 4-6 in thick and rebar reinforced. It is approximately 30 x 15 ft. We are considering putting in a pool. The pool decking (concrete) will need to be tied into the existing concrete...

Expanding washer [ 3 Answers ]

What happens to the hole in the centre of a metal washer when the washer is heated? The washer expands but does it expand into the hole and the hole get smaller, does the hole get bigger or remain the same size? Thanks Chris