views:

1589

answers:

4

I'd like to have tables that can dynamically collapse some rows in a web page, such as:

    |   Title   |   Foo   |   Bar   |
    ---------------------------------
    | + My First Section            |
    ---------------------------------
    | + My Second Section           |
    ---------------------------------

can dynamically expand to

    |   Title   |   Foo   |   Bar   |
    ---------------------------------
    | - My First Section            |
    ---------------------------------
    | 1st Title |    42   |  $10.00 |
    ---------------------------------
    | 2nd Title |    74   |  $12.00 |
    ---------------------------------
    | + My Second Section           |
    ---------------------------------

when I press on the + sign.

Are there any JavaScript libraries that could help me do such a thing, or is there some magic native command that could do it for my easily?

+2  A: 

Put each section in a different tbody element, each with an id attribute. Make the first row of each tbody a single header cell (th with the appropriate colspan) with your section header text and an anchor to #the_tbody_id. Then:

  1. Add CSS:

    tbody[id]:not(:target) > tr:first-child + tr { display: none !important; }

  2. Or, for non-partial-CSS3 browsers, add Javascript to hide the non-first rows in each of those tbodys (eg, loop through tablelement.getElementsByTagName("tbody")), and hook the anchor to toggle their display property on click (eg, loop through tbodyelement.getElementsByTagName("tr")).

Anonymous
Setting display on table rows is tricky. What do you set the display property to when you want to display the tr? block? Heh. A TR is not a block level element.
apphacker
No, you would set it to 'table-row' if you were setting it. But you obviously don't have to. Toggle the .style.display property between the values 'none' and ''.
Anonymous
A: 

You just write a div with display none inside every TR. And on the '+' sign click change the display of the div to block and on '-' click change it again to none.

Assign each div a unique id.

Eg:

<tr>
    <td>
       My Section>
       <div style='display:none'>
          Content goes here
       </div>
   </td>        
</tr>
rahul
I'm pretty sure that having a <div> element as a child of a <tr> is invalid. In the HTML 4.01 specification it states "the TR elements acts as a container for a row of table cells." which limits its children to the <td> and <th> elements.
Zack Mulgrew
edited the post
rahul
Quick test shows that solution almost working. There's no need for a <div> section, though. When the "style" argument is applied to the <tr> tag, I can actually show / hide entire rows. The test was done statically, though. I still have to hook it to some javascript action.
Joce
A: 

Dojo and Jquery both can do this for you, but in case you don't want to use a javascript library this isn't hard with just plain JavaScript. Use an onclick event handler for the +/- toggle, write a function that is executed which sets a block element (one of your sets of rows) to display:none (a css rule). If you're going to use a table to display this, don't try to dynamically hide or show table rows, it doesn't work well.

apphacker
A: 

You could set the display property of those rows as none, and reset it as "table-row" at click.

But I think that IE doesn't render this appropiately though...

SuperIRis