Jump to content


Photo
- - - - -

Creating collapsible elements using JavaScript,CSS


  • Please log in to reply
20 replies to this topic

#1 usr.c

usr.c

    Boss, my code's compiling (xkcd)

  • Admins
  • 10,440 posts
  • Gender:Male
  • Interests:Software
    Soccer
    Photography
    RC cars
    Electronics

  • Nothing Selected

Posted 05 January 2006 - 07:24 PM

Creating collapsible elements using JavaScript and CSS
Fancy version: http://www.cyberiapc...ings/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...demo/search.php to see this code in action.


Things that I don't suck at: Photography (flickr, JPG Mag), Skydiving, Splitting atoms, Flying a space shuttle
"Don't bail; the best gold is at the bottom of barrels of crap!" -Randy Pausch
I have people-skills goddamnit! What is wrong with you people!!! | www.skyrill.com

#2 binary

binary

    Sarcastic

  • ++Member
  • 224 posts
  • Location:London
  • Interests:Unreality -?

  • United Kingdom

Posted 06 January 2006 - 02:04 PM

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

#3 usr.c

usr.c

    Boss, my code's compiling (xkcd)

  • Admins
  • 10,440 posts
  • Gender:Male
  • Interests:Software
    Soccer
    Photography
    RC cars
    Electronics

  • Nothing Selected

Posted 06 January 2006 - 03:44 PM

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.


Things that I don't suck at: Photography (flickr, JPG Mag), Skydiving, Splitting atoms, Flying a space shuttle
"Don't bail; the best gold is at the bottom of barrels of crap!" -Randy Pausch
I have people-skills goddamnit! What is wrong with you people!!! | www.skyrill.com

#4 usr.c

usr.c

    Boss, my code's compiling (xkcd)

  • Admins
  • 10,440 posts
  • Gender:Male
  • Interests:Software
    Soccer
    Photography
    RC cars
    Electronics

  • Nothing Selected

Posted 06 January 2006 - 09:54 PM

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


Things that I don't suck at: Photography (flickr, JPG Mag), Skydiving, Splitting atoms, Flying a space shuttle
"Don't bail; the best gold is at the bottom of barrels of crap!" -Randy Pausch
I have people-skills goddamnit! What is wrong with you people!!! | www.skyrill.com

#5 binary

binary

    Sarcastic

  • ++Member
  • 224 posts
  • Location:London
  • Interests:Unreality -?

  • United Kingdom

Posted 07 January 2006 - 01:33 PM

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

#6 usr.c

usr.c

    Boss, my code's compiling (xkcd)

  • Admins
  • 10,440 posts
  • Gender:Male
  • Interests:Software
    Soccer
    Photography
    RC cars
    Electronics

  • Nothing Selected

Posted 07 January 2006 - 04:06 PM

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.


Things that I don't suck at: Photography (flickr, JPG Mag), Skydiving, Splitting atoms, Flying a space shuttle
"Don't bail; the best gold is at the bottom of barrels of crap!" -Randy Pausch
I have people-skills goddamnit! What is wrong with you people!!! | www.skyrill.com

#7 usr.c

usr.c

    Boss, my code's compiling (xkcd)

  • Admins
  • 10,440 posts
  • Gender:Male
  • Interests:Software
    Soccer
    Photography
    RC cars
    Electronics

  • Nothing Selected

Posted 08 January 2006 - 05:57 PM

The demo should work properly now in Mozilla. I'll update the code later today.

Thanks again.


Things that I don't suck at: Photography (flickr, JPG Mag), Skydiving, Splitting atoms, Flying a space shuttle
"Don't bail; the best gold is at the bottom of barrels of crap!" -Randy Pausch
I have people-skills goddamnit! What is wrong with you people!!! | www.skyrill.com

#8 usr.c

usr.c

    Boss, my code's compiling (xkcd)

  • Admins
  • 10,440 posts
  • Gender:Male
  • Interests:Software
    Soccer
    Photography
    RC cars
    Electronics

  • Nothing Selected

Posted 12 January 2006 - 04:42 PM

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;
† }
}



Things that I don't suck at: Photography (flickr, JPG Mag), Skydiving, Splitting atoms, Flying a space shuttle
"Don't bail; the best gold is at the bottom of barrels of crap!" -Randy Pausch
I have people-skills goddamnit! What is wrong with you people!!! | www.skyrill.com

#9 Guest_Guest_*

Guest_Guest_*
  • Guests

Posted 06 February 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

#10 Guest_Guest_*

Guest_Guest_*
  • Guests

Posted 07 February 2006 - 01:03 PM

QUOTE(Guest @ Feb 6 2006, 08:22 PM) <{POST_SNAPBACK}>
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

#11 usr.c

usr.c

    Boss, my code's compiling (xkcd)

  • Admins
  • 10,440 posts
  • Gender:Male
  • Interests:Software
    Soccer
    Photography
    RC cars
    Electronics

  • Nothing Selected

Posted 10 February 2006 - 12:53 AM

Glad you managed to fix it, and thanks for your comments.


Things that I don't suck at: Photography (flickr, JPG Mag), Skydiving, Splitting atoms, Flying a space shuttle
"Don't bail; the best gold is at the bottom of barrels of crap!" -Randy Pausch
I have people-skills goddamnit! What is wrong with you people!!! | www.skyrill.com

#12 Guest_BlueNC_*

Guest_BlueNC_*
  • Guests

Posted 08 June 2006 - 03:31 AM

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

#13 usr.c

usr.c

    Boss, my code's compiling (xkcd)

  • Admins
  • 10,440 posts
  • Gender:Male
  • Interests:Software
    Soccer
    Photography
    RC cars
    Electronics

  • Nothing Selected

Posted 08 June 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.


Things that I don't suck at: Photography (flickr, JPG Mag), Skydiving, Splitting atoms, Flying a space shuttle
"Don't bail; the best gold is at the bottom of barrels of crap!" -Randy Pausch
I have people-skills goddamnit! What is wrong with you people!!! | www.skyrill.com

#14 Guest_BlueNC_*

Guest_BlueNC_*
  • Guests

Posted 08 June 2006 - 05:46 PM

QUOTE(usr.c @ Jun 8 2006, 02:20 PM) <{POST_SNAPBACK}>
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 ?

#15 Guest_BlueNC_*

Guest_BlueNC_*
  • Guests

Posted 13 June 2006 - 02:58 AM

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....




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users