Useful JavaScript: Expandable/Collapsable Divs
Keeping with the theme of my recent JavaScript posts, here are a couple of simple JavaScript functions that are extremely useful for creating a clean user interface. The scripts themselves are simple, but together they allow you to create the effect of a div that expands and collapses to show or hide its contents.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <script type="text/javascript"> function findElement(element_id) { if (document.getElementById && document.getElementById(element_id)) { return document.getElementById(element_id); } else { return false; } } function hideElement(element_id) { element = findElement(element_id) if (element) { element.style.display = 'none'; return element; } else { return false; } } function showElement(element_id) { element = findElement(element_id) if (element) { element.style.display = ''; return element; } else { return false; } } </script> |
The first function simply locates an element on a page. For example, if you pass it an element_id like “sidebar” it will locate the element with that id, such as <div id=”sidebar”>. The second two functions use findElement to locate the element and then either tell it to display on the page or not. So a hidden element can be revealed or a visible element can be hidden.
Though simple, these functions allow us to perform a nice slight-of-hand. We can hide a large block of text but leave the title or a short summary visible. Clicking on the title will reveal the full text in a larger div. Clicking it again will re-hide it. The effect is made even better by adding arrow icons: right-facing (or left-facing) for the “collapsed” or hidden state, downward-facing for the “expanded” or visible state.
Here is an example: (WordPress is keeping the JavaScript from running properly… working to fix it.)
Here’s how you can do it yourself. Put the above JavaScript on a page. Next, create two div elements. In the first, put the collapsed or summary view. In the second, put the expanded view with the full text and give the div a style attribute of “display: none;” to hide it when the page first loads. Now you need to two links. In the first div put a link that shows the second div and hides itself. In the second div, put a link that shows the first div (remember: when this link is visible, the first div won’t be anymore) and hides itself.
1 2 3 4 5 6 7 8 9 10 11 | <div id="text_off"> <a href="#" onclick="showElement('text'); hideElement('text_off'); return false;"> <img src="icon_arrow_right.gif" /> Text Title</a> </div> <div id="text" style="display: none;"> <a href="#" onclick="showElement('text_off'); hideElement('text'); return false;"> <img src="icon_arrow_down.gif" /> Text Title</a><br /> <p>Longer text goes here.</p> <p>Click the title again to collapse the view.</p> </div> |
Because one div hides at the same time as the next one displays, and because all the other page elements shift up or down, the effect is that the original div has simply “opened up” to reveal its contents. You could also reverse the effect—start with an expanded div that can be folded out of the way—by simply moving “display: none;” to the other div. You can add more expandable divs to the page and, provided you give them unique ids, they will all work.
It is a simple way to put a lot of information at the user’s fingertips without overloading the page all at once. It also could save you additional page loads or MySQL calls that would result from putting the same data on a different page.

May 30th, 2008 at 12:01 pm
You should really consider using some kind of JS loader to add these events, instead of modifying the code directly. Not only will it move things out of your HTML, it can be cached, etc, blah blah blah.
Plus, it looks pretty to not have those onclicks.
May 30th, 2008 at 12:11 pm
You could and you could also use various JavaScript libraries to do the showing and hiding.
This is just a simplified version to illustrate the process.
August 22nd, 2008 at 10:54 am
you should have considered implementing opening one div while closing previously open divs.
August 25th, 2008 at 2:45 pm
Love it!! Just applied it to our site and works great. It may also be of interest to know that this is a good tool for SEO. Google has gotten much better at crawling text within java so it counts for keyword density and such. I would also like to learn how to do a scrolling java div such as the one at the bottom of this site:
http://www.volusion.com/
Thanks again!
January 5th, 2009 at 7:43 pm
Hi,
Somehow I get an error (blank page) when my text is too large in the content div.
Is there any way I can avoid this?
I am using the second coding with first and second section.
Thanks a bunch,
Monique
Harmelen, the Netherlands
January 7th, 2009 at 9:08 am
I got it working! It turned out I needed to add per line.
Overlooked that…..
Thanks for the code, it helped me out!
Monique
January 8th, 2009 at 4:16 am
Hi,
I would like to be able to close all divs at the same time, any idea on how I could do this?
Thanks,
Monique
January 8th, 2009 at 7:58 am
Hi, found a solution to my own question :o)thought I’ld post it, save other people the hassle. This code gives a + or a - button.
Put this in your CSS file:
2
3
4
5
6
7
8
9
10
11
12
border:1px solid #cccccc;
display: block;
text-align: center ;
text-decoration: none;
color: #FC6401;
float: left;
font-size: 11px;
font-weight: bold;
padding: 4px;
color: #ff6600;
}
This is the HTML code:
2
3
4
5
6
7
8
9
<a href="#" onclick="showElement('closethemall');hideElement('openthemall');showElement('antwoord11');showElement('antwoord12');showElement('antwoord13');showElement('antwoord14');showElement('antwoord19');hideElement('vraag11');hideElement('vraag12');hideElement('vraag13');hideElement('vraag14');hideElement('vraag19');return
false;">
+</a>
</div>
<div id="closethemall" style="display: none;" class="buttonopenclose">
<a href="#" onClick="window.location.reload()">-</a>
</div>
February 16th, 2009 at 12:23 pm
Once again, great article! I was actually looking for a clean and easy way of doing something like this with JavaScript, and this is exactly what I needed. I will implement it later, when I need to. Thanks a bunch!