Help - Search - Members - Calendar
Full Version: Creating collapsible elements using JavaScript,CSS
CyberiaPC.com Community > Community Forums > Papers and Articles
usr.c
Creating collapsible elements using JavaScript and CSS
Fancy version: http://www.cyberiapc.com/writings/2006_1.php

I woke up from a long sleep, had a stretch, rubbed my eyes and looked at the computer screen. “Damn”, I thought, I need to learn some of that cool stuff that Web developers are doing these days. It’s still a long way to Ajax-nirvana, so I’m hoping to take things one step at a time.

This article will show you how I created a simple collapsible table for a project that I work on in my free time.

What you need: An editor and a browser
How long will it take: Less than 10 minutes
Skill level: Beginner

The goal is to create a search box that allows the user to choose whether or not to show advanced search options. Search boxes in some desktop applications work this way. It’s a nice concept because it reduces on-screen clutter.

There are three parts to the implementation:
  • A CSS rule
  • A JavaScript function
  • An HTML file
1. The CSS rule uses the display property to determine whether the element implementing it is displayed or hidden. It is set to none by default meaning that the element is hidden when it’s first loaded.

CODE
#search_options { display: none }

2. The HTML file displays the table and binds the CSS formatting and JavaScript logic to it.

CODE
<form name='frmSearch' action='' method='post'>
  <table style='width:700px;border:1px solid #000000' cellpadding='3' cellspacing='3'>
     <tr><td width='100%'>
        <input type='text' name='searchterm' maxlength='128' style='width:99%' />
     </td>
     <td>
        <a href='#' onclick="return hidify_showify('search_options','search_arrow','Less','More');">
        <img src='images/arrow_down.gif' alt='Advanced Options' border='0' id='search_arrow' />
        </a>
     </td></tr>
     <tr><td width='100%' id='search_options'>
        <br />__Advanced stuff goes here__<br />
     </td></tr>
     <tr><td width='100%' align='center'>
     <input type='submit' name='submit' value='Search' />
     </td></tr>
  </table>
</form>

Notice that the table has three rows. The first shows a text box for typing the query and a button for switching between the table’s collapsed and expanded states. The second row contains the advanced options that will be shown or hidden on demand. The third shows our submit button. The interesting parts are shown in bold.

Clicking on the More/Less image calls the JavaScript function hidify_showify(). More about that later. The second table row has search_options as its ID, which is defined in the CSS as being hidden by default. The More/Less image is also given an ID, though it's just so that we can refer to it later on and change its source and alt tag depending on whether the table is collapsed or expanded.

3. The JavaScript function contains the logic that manipulates the CSS rule and switches its display property. It also checks the browser type and uses the value for display that is supported by that browser. Firefox doesn’t support the value table-cell, but IE does. If block or table-cell is always used then the contents of the table won't look too good in one of the browsers. You can surely optimize the code shown below by reducing its redundent parts, but I think the way it looks now is intuitive to understand.

CODE
<script type="text/javascript">
function hidify_showify(e_table, e_img, alt_less, alt_more) {
  if(document.getElementById) {
     var id_table = document.getElementById(e_table).style;
     var id_img = document.getElementById(e_img);

     //Set the object to table-cell if the browser is
     //Firefox and block if it's anything else.
     if(navigator.userAgent.indexOf("Firefox") != -1){
        if(id_table.display == "table-cell") {
           id_table.display = "none";
           id_img.src = "images/arrow_down.gif";
           id_img.alt = alt_more;
        }
        else {
           id_table.display = "table-cell";
           id_img.src = "images/arrow_up.gif";
           id_img.alt = alt_less;
        }
     }
     else {
        if(id_table.display == "block") {
           id_table.display = "none";
           id_img.src = "images/arrow_down.gif";
           id_img.alt = alt_more;
        }
        else {
           id_table.display = "block";
           id_img.src = "images/arrow_up.gif";
           id_img.alt = alt_less;
        }
     }
     return false;
  }
  else {
     return true;
  }
}
</script>

Note that because we're passing IDs to this function, we use document.getElementById() to get the actual elements that we can then manipulate.

That’s it. Clicking on the More/Less image invokes the JavaScript function, which then looks at the elements identified as search_options and search_arrow and decides what to set their CSS properties to.

This file contains all the code mentioned here with the CSS, JavaScript and HTML defined seperately. You can take a look at http://cyberiapc.com/zenith_demo/search.php to see this code in action.
binary
ali, thank you but interesting issue with mozilla.

when first viewing the page, collapsed table works fine and elements are perfectly aligned however successively pressing the collapse button causes the elements to be distorted.... running 1.7.12
usr.c
hmm...The first block needs to check for Firefox and Mozilla instead of just Firefox. I'm not sure what the argument would be for Mozilla ("Mozilla" perhaps), but I'll look it up.

Thanks for bringing this to my attention.
usr.c
Fixing it is a bit less straightforward than I had hoped.

Can't we just pretend that no one uses Mozilla and Safari whistling.gif
binary
lol , fair enough just out of interest would you know what makes different browsers cause distortions?
usr.c
Don't worry, it'll have to be fixed since the code is used in Zenith.

QUOTE
lol , fair enough just out of interest would you know what makes different browsers cause distortions?

They render things differently and some are less forgiving than others. In this case though, it's because (based on what I've read) that the table-cell and block values of display aren't both supported by all browsers.
usr.c
The demo should work properly now in Mozilla. I'll update the code later today.

Thanks again.
usr.c
I forgot to post the updated code.

This is what I ended up using in Zenith v0.8.8 DEV. The collapsible table now works in Firefox, Mozilla, IE and Opera. Once again, I'm sure this can be simplified, so post a reply if you have a better way of doing it.

Thanks.

The JavaScript file now has:

CODE
//The browser detection code below is courtesy of
//Harald Hope, Tapio Markula, Websites: http://techpatterns.com/
//It is released under the terms of the LGPL
var d, dom, ie, ie4, ie5x, moz, mac, win, lin, old, ie5mac, ie5xwin, op;
d = document;
n = navigator;
na = n.appVersion;
nua = n.userAgent;
win = ( na.indexOf( 'Win' ) != -1 );
mac = ( na.indexOf( 'Mac' ) != -1 );
lin = ( nua.indexOf( 'Linux' ) != -1 );

if ( !d.layers ){
  dom = ( d.getElementById );
  op = ( nua.indexOf( 'Opera' ) != -1 );
  konq = ( nua.indexOf( 'Konqueror' ) != -1 );
  saf = ( nua.indexOf( 'Safari' ) != -1 );
  moz = ( nua.indexOf( 'Gecko' ) != -1 && !saf && !konq);
  ie = ( d.all && !op );
  ie4 = ( ie && !dom );
  /*ie5x tests only for functionality. ( dom||ie5x ) would be default settings.
  Opera will register true in this test if set to identify as IE 5*/
  ie5x = ( d.all && dom );
  ie5mac = ( mac && ie5x );
  ie5xwin = ( win && ie5x );
}
    
function hidify_showify(e_table, e_img, alt_less, alt_more) {
  if(document.getElementById) {
     var id_table = document.getElementById(e_table).style;
     var id_img = document.getElementById(e_img);

     //Set the object to table-cell if the browser is
     //moz (see above) and block if it's anything else.
     if(moz){
        if(id_table.display == "table-cell") {
           id_table.display = "none";
           id_img.src = "images/arrow_down.gif";
           id_img.alt = alt_more;
        }
        else {
           id_table.display = "table-cell";
           id_img.src = "images/arrow_up.gif";
           id_img.alt = alt_less;
        }
     }
     else {
        if(id_table.display == "block") {
           id_table.display = "none";
           id_img.src = "images/arrow_down.gif";
           id_img.alt = alt_more;
        }
        else {
           id_table.display = "block";
           id_img.src = "images/arrow_up.gif";
           id_img.alt = alt_less;
        }
     }
     return false;
  }
  else {
     return true;
  }
}
Guest
Hi, brilliant script, is there any way to add multiple e-tables?
I want to show hide various form elements?
I am using radio buttons to activate the "onClick"
My problem is the following:
i have 3 horizontal blocks
when i press 1, 1 appears
when i press 2, 2 appears below the 1
when i press 1 again, 1 dissapeares and leaves 2
Is there any way of making various e-tables visible/invisible?
thanx
SZ
Guest
QUOTE(Guest @ Feb 6 2006, 08:22 PM) *
Hi, brilliant script, is there any way to add multiple e-tables?
I want to show hide various form elements?
I am using radio buttons to activate the "onClick"
My problem is the following:
i have 3 horizontal blocks
when i press 1, 1 appears
when i press 2, 2 appears below the 1
when i press 1 again, 1 dissapeares and leaves 2
Is there any way of making various e-tables visible/invisible?
thanx
SZ

I have solved the issue by using a blend of: "hidify_showify" combined with "document.getElementById(button1).style.display='none'"
I create a series of buttons which appear and dissapear depending on what elements i want to "dynamically" create. Not very clean...but worx!!!
valid for ie & firefox so far....
Thanx for the original idea
SZ a.k.a MrEnjoy
usr.c
Glad you managed to fix it, and thanks for your comments.
BlueNC
Awesome script, Thank you very much for making it available to the public.
one question though, I am trying to make your script work the opposite way, have the box open and let the user decide to close it.
So far I am failing terribly, it just looks horrible, I tried to first change the CSS property to "display:block" and after that failed, I tried to just "flip" your script, but that isn't working either.
Mind you I am a bloody beginner at this. Maybe I am just overthinking something. Any help is greatly appreciated.

Thank you
usr.c
Thanks for your comments.

How about if you add this to your body tag:

CODE
onLoad=hidify_showify('search_options','search_arrow','Less','More');

so that it looks like this:

CODE
<body onLoad=hidify_showify('search_options','search_arrow','Less','More');>


You might get a short delay before it expands if your page has lots of code, so if that's no good for you, let me know.
BlueNC
QUOTE(usr.c @ Jun 8 2006, 02:20 PM) *
Thanks for your comments.

How about if you add this to your body tag:

CODE
onLoad=hidify_showify('search_options','search_arrow','Less','More');

so that it looks like this:

CODE
<body onLoad=hidify_showify('search_options','search_arrow','Less','More');>


You might get a short delay before it expands if your page has lots of code, so if that's no good for you, let me know.


Thank you for your quick response, I noticed the delay as you said, so I made it as I initially thought, and it works great so far. I just swapped the code around PLUS changed the CSS style to something like: hidestyle {}
this will not validate (as far as I know, but since your little script generates all the required styles on the fly, that was the only way I could make it work in IE and Firefox. Also, since I need to use the both versions (max -> mini and mini -> max) I just made the reverse a new function.

Once again: Thank you for giving us that nice script that was exactly what I needed, I was just wondering if you consider making it work with divs rather than tables for those who do want to try a tableless layout ?
BlueNC
Hi,
one more question and I hope you might be able to help with that. I was wondering if the script could be used to change CSS classes rather than ID's ? Again, I have no Clue about Javascript but since I would like to make a "collapsible Menu" Id's would fill my stylesheet up really quick.

Thank you for any help....
usr.c
Sure. Expect a reply from me during the weekend (sorry about this very late reply)
Matthew
QUOTE(Guest @ Feb 7 2006, 01:03 PM) *
I have solved the issue by using a blend of: "hidify_showify" combined with "document.getElementById(button1).style.display='none'"
I create a series of buttons which appear and dissapear depending on what elements i want to "dynamically" create. Not very clean...but worx!!!
valid for ie & firefox so far....
Thanx for the original idea
SZ a.k.a MrEnjoy

Can you show some of that code? I don't understand. lookaround.gif
Chris-McC
QUOTE(Matthew @ May 11 2007, 06:47 AM) *
Can you show some of that code? I don't understand. lookaround.gif


I'd like to see this code too. I'm trying to create a page with 3 tables, all hidden by default and display on the press of a button.

I'm great at HTML but javascript is something I'm very basic with. But if someone can point me in the direction of a way to do this I'd be thankful.
usr.c
I promise to get back to you on that in a few days once the new ZPG release is out safely. original.gif
usr.c
I should have read your post more closely back when you made it; sorry about that.

If you want the button to simultaneously display and hide your three tables then using the following code should do the trick.

CODE
<div>
    <a href='#' onclick="return hidify_showify('search_options','search_arrow','Less','More');">
    <img src='images/arrow_down.gif' alt='Advanced Options' border='0' id='search_arrow' />
    </a>
</div>

<div id='search_options'>
<!-- PUT YOUR THREE TABLES HERE -->
</div>

It displays your button as before, but now hides and shows the div that contains your three tables. Replace "PUT YOUR THREE TABLES HERE" with your tables and you should be set. If you have any problems please let me know; Hopefully, I won't take as long to reply this time.
Mr Enjoy
QUOTE(Chris-McC @ Jul 6 2007, 03:09 PM) *
I'd like to see this code too. I'm trying to create a page with 3 tables, all hidden by default and display on the press of a button.

I'm great at HTML but javascript is something I'm very basic with. But if someone can point me in the direction of a way to do this I'd be thankful.


http://www.naturemeetings.com/booking/booking_form.html

add & remove elements by clicking on the links!

thanx
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2012 Invision Power Services, Inc.