Can a table row expand and close? [closed]
Asked Answered
S

6

41

Is it possible to make a table row expand and collapse? Can anyone refer me to a script or an example?

I prefer jQuery if possible. I have a drawing concept I would like to achieve:

alt text

Swound answered 9/10, 2010 at 18:42 Comment(10)
Use Jquery slidedown and Slide up. api.jquery.com/slideDownBangka
Can you give an example of the markup used for this? I guess he could just use a list of <div>s, but that doesn't quite seem semantic... :\Unger
mkyong.com/jquery/…Bangka
or slideToggle().Worldweary
@Christian: It would be a OL of DIVs.Predecessor
@Chris - There is nothing wrong with using a table for tabular data. This content looks like it is tabular data. - In this case, if it is a list then the div s in it would not be as semantically meaningful as the td s in a table.Sustentation
I want to thank everyone for there input. It was all very helpful.Swound
Did no one else find it alarming that the OP is selling children?Hymeneal
@AndrewMairose It looked that way to me at first, but if you look closer it's about donating to specific children (which is still weird to me, but whatever). The "add to cart" button could probably be less awkwardly phrased though!Journalese
Check datatables, datatables.net/examples/api/row_details.htmlDanczyk
S
56

Yes, a table row can slide up and down, but it's ugly since it changes the shape of the table and makes everything jump. Instead, put an element in each td, something that makes sense like a p or h2 etc.

As for implementing a table slide toggle...

It's probably simplest to put the click handler on the entire table, .stopPropagation() and check what was clicked.

If a td in a row with a colspan is clicked, close the p in it. If it's not a td in a row with a colspan, then close then toggle the following row's p.

It is essential to wrap all your written content in an element inside the tds, since you never want to slideUp a td or tr or table shape will change!

Something like:

$(function() {
  
      // Initially hide toggleable content
    $("td[colspan=3]").find("p").hide();

      // Click handler on entire table
    $("table").click(function(event) {

          // No bubbling up
        event.stopPropagation();

        var $target = $(event.target);

          // Open and close the appropriate thing
        if ( $target.closest("td").attr("colspan") > 1 ) {
            $target.slideUp();
        } else {
            $target.closest("tr").next().find("p").slideToggle();
        }                    
    });
});​

Try it out with this jsFiddle example.

... and try out this jsFiddle showing implementation of a + - - toggle.

The HTML just has to have alternating rows of several tds and then a row with a td of a colspan greater than 1. You can obviously adjust the specifics quite easily.

The HTML would look something like:

<table>
    <tr><td><p>Name</p></td><td><p>Age</p></td><td><p>Info</p></td></tr>
    <tr><td colspan="3"><p>Blah blah blah blah blah blah blah.</p>
    </td></tr>

    <tr><td><p>Name</p></td><td><p>Age</p></td><td><p>Info</p></td></tr>
    <tr><td colspan="3"><p>Blah blah blah blah blah blah blah.</p>
    </td></tr>
    
    <tr><td><p>Name</p></td><td><p>Age</p></td><td><p>Info</p></td></tr>
    <tr><td colspan="3"><p>Blah blah blah blah blah blah blah.</p>
    </td></tr>    
</table>​
Sustentation answered 9/10, 2010 at 20:42 Comment(7)
@Peter-Ajtai Would you be able to help me with this issue Peter? #23916817Mraz
@peter i have a similar problem like this but my HTML table is totally dynamic if you get some time please help #55919920Cellophane
Hello, I tried this solution and its working perfectly at the moment. However if I click on the bottom most portion of the expanded row (port expand) it will make my expanded row vanish entirely with no way to re-expand without refreshing the page.Brownfield
For your fiddle it seems to behave the same if you click towards the top of the expanded row.Brownfield
Below is a link to my question. The answer provided fixes this solutions bug where you can no longer see an expandable row. #57777225Brownfield
When trying to select text for copy, it will also expand. Small issue, but can be annoying.Ster
This isn't valid HTML and is a terrible experience for screen reader users. Tables need to have headers, so in this case, when you add a row with colspan="3", the expandable/collapsible row would not work with the headersUnderground
B
13

You could do it like this:

HTML

<table>
    <tr>
        <td>Cell 1</td>
        <td>Cell 2</td>
        <td>Cell 3</td>
        <td>Cell 4</td>
        <td><a href="#" id="show_1">Show Extra</a></td>
    </tr>
    <tr>
        <td colspan="5">
            <div id="extra_1" style="display: none;">
                <br>hidden row
                <br>hidden row
                <br>hidden row
            </div>
        </td>
    </tr>
</table>

jQuery

$("a[id^=show_]").click(function(event) {
    $("#extra_" + $(this).attr('id').substr(5)).slideToggle("slow");
    event.preventDefault();
});

See a demo on JSFiddle

Bridle answered 9/10, 2010 at 19:15 Comment(0)
W
3

It depends on your mark-up, but it can certainly be made to work, I used the following:

jQuery

$(document).ready(
  function() {
  $('td p').slideUp();
    $('td h2').click(
      function(){
       $(this).siblings('p').slideToggle();
      }
      );
  }
  );

html

  <table>
  <thead>
    <tr>
      <th>Actor</th>
      <th>Which Doctor</th>
      <th>Significant companion</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><h2>William Hartnell</h2></td>
      <td><h2>First</h2><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></td>
      <td><h2>Susan Foreman</h2><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p></td>
    </tr>
    <tr>
      <td><h2>Patrick Troughton</h2></td>
      <td><h2>Second</h2><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></td>
      <td><h2>Jamie MacCrimmon</h2><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p></td>
    </tr>
    <tr>
      <td><h2>Jon Pertwee</h2></td>
      <td><h2>Third</h2><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></td>
      <td><h2>Jo Grant</h2><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p></td>
    </tr>
  </tbody>
</table>

The way I approached it is to collapse specific elements within the cells of the row, so that, in my case, the row would slideUp() as the paragraphs were hidden, and still leave an element, h2 to click on in order to re-show the content. If the row collapsed entirely there'd be no easily obvious way to bring it back.

Demo at JS Bin


As @Peter Ajtai noted, in the comments, the above approach focuses on only one cell (though deliberately). To expand all the child p elements this would work:

$(document).ready(
  function() {
  $('td p').slideUp();
    $('td h2').click(
      function(){
       $(this).closest('tr').find('p').slideToggle();
      }
      );
  }
  );

Demo at JS Bin

Worldweary answered 9/10, 2010 at 19:16 Comment(5)
Good solution, although @Erik's layout would require that the hidden cell is in a different row altogether since it spans across multiple other cells in the row above.Bridle
True, unfortunately trying to implement this solution with a sibling table-row causes all sorts of unattractive jumping. Possibly with a carefully-nested list it could be done, though.Worldweary
You can use sibling or next and .find("p") so that you never have to collapse a td or tr, and then you can easily implelemnt a colspan solution. - See my solution.Sustentation
Your jsBin example doesn't close the row if the opened row is clicked on. ----- Also it's very confusing that when you click on something, the entire row opens up, but only the information associated with the one cell you clicked on is shown (the other info in the same row remains hidden).Sustentation
@Peter, possibly; but it was more a quick demonstration of intent, rather than a polished, finished implementation.Worldweary
C
2

jQuery

$(function() {
    $("td[colspan=3]").find("div").hide();
    $("tr").click(function(event) {
        var $target = $(event.target);
        $target.closest("tr").next().find("div").slideToggle();                
    });
});

HTML

<table>
    <thead>
        <tr>
            <th>one</th><th>two</th><th>three</th>
        </tr>
    </thead>
    <tbody>

        <tr>
            <td><p>data<p></td><td>data</td><td>data</td>
        </tr>
        <tr>
            <td colspan="3">
                <div>
                    <table>
                            <tr>
                                <td>data</td><td>data</td>
                            </tr>
                    </table>
                </div>
            </td>
        </tr>
    </tbody>
</table>

This is much like a previous example above. I found when trying to implement that example that if the table row to be expanded was clicked while it was not expanded it would disappear, and it would no longer be expandable

To fix that I simply removed the ability to click the expandable element for slide up and made it so that you can only toggle using the above table row.

I also made some minor changes to HTML and corresponding jQuery.

NOTE: I would have just made a comment but am not allowed to yet therefore the long post. Just wanted to post this as it took me a bit to figure out what was happening to the disappearing table row.

Credit to Peter Ajtai

Cowper answered 20/11, 2015 at 14:32 Comment(0)
S
1

To answer your question, no. That would be possible with div though. THe only question is would cause a hazzle if the functionality were done with div rather than tables.

Sicard answered 9/10, 2010 at 18:49 Comment(0)
T
0

Well, I'd say use the DIV instead of table as it would be much easier (but there's nothing wrong with using tables).

My approach would be to use jQuery.ajax and request more data from server and that way, the selected DIV (or TD if you use table) will automatically expand based on requested content.

That way, it saves bandwidth and makes it go faster as you don't load all content at once. It loads only when it's selected.

Tenancy answered 9/10, 2010 at 21:8 Comment(2)
That covers expansion. What about collapse?Sustentation
just add a function to remove the selected DIV element when clicked on. That will "collapse." You will need to add delegate() function to let jQuery bind functions to new elements.Tenancy

© 2022 - 2024 — McMap. All rights reserved.