tags:

views:

15570

answers:

6

I have a really long 3 column table. I would like to

<table>
    <tr><td>Column1</td><td>Column2</td></tr>
    <tr><td>Column1</td><td>Column2</td></tr>
    <tr><td>Start</td><td>Hiding</td></tr>
    <tr><td>Column1</td><td>Column2</td></tr>
    <tr><td>Column1</td><td>Column2</td></tr>
    <tr><td>Column1</td><td>Column2</td></tr>
    <tr><td>End</td><td>Hiding</td></tr>
    <tr><td>Column1</td><td>Column2</td></tr>
    <tr><td>Column1</td><td>Column2</td></tr>
</table>

This is the result I'm trying to obtain using jQuery.

Column1  Column2
Column1  Column2
...Show Full Table...
Column1  Column2
Column1  Column2

I would like to use jQuery's show/hide feature to minimize the table but still show part of the top and bottom rows. The middle rows should be replace with text like "Show Full Table" and when clicked will expand to show the full table from start to finish.

What is the best way to do this in jQuery?

BTW I've already tried adding a class "Table_Middle" to some of the rows but it doesn't hide it completely the space it occupied is still there and I don't have the text to give the user a way to expand the table fully.

[EDIT] Added Working Example HTML inspired by Parand's posted answer

The example below is a complete working example, you don't even need to download jquery. Just paste into a blank HTML file.

It degrades nicely to show only the full table if Javascript is turned off. If Javascript is on then it hides the middle table rows and adds the show/hide links.

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
        <title>Example Show/Hide Middle rows of a table using jQuery</title>
        <script src="http://code.jquery.com/jquery-latest.js"&gt;&lt;/script&gt;
        <script type="text/javascript">
            $(document).ready(function() {
             $("#HiddenRowsNotice").html("<tr><td colspan='2'> <a href='#'>>> some rows hidden <<</a></td></tr>");
             $("#ShowHide").html("<tr><td colspan='2'><a href='#'>show/hide middle rows</a></td></tr>");
             $("#HiddenRows").hide();

             $('#ShowHide,#HiddenRowsNotice').click( function() {
                 $('#HiddenRows').toggle(); 
              $('#HiddenRowsNotice').toggle();
             });
            });
        </script>
    </head>
    <body>
        <table>
            <tbody id="ShowHide"></tbody>
                <tr><th>Month Name</th><th>Month</th></tr>
            <tbody>
                <tr><td>Jan</td><td>1</td></tr>    
            </tbody>
            <tbody id="HiddenRowsNotice"></tbody>
            <tbody id="HiddenRows">
                <tr><td>Feb</td><td>2</td></tr>
                <tr><td>Mar</td><td>3</td></tr>
                <tr><td>Apr</td><td>4</td></tr>    
            </tbody>
            <tbody>
                <tr><td>May</td><td>5</td></tr>            
            </tbody>
        </table>
    </body>
</html>

[EDIT] Link my blog post and working example.

+2  A: 

The easiest way is to add a <tbody> in to group the rows and toggle that between none and table-row-group (catch exceptions and set it to block for IE). Not sure about making it specific to jquery but that's the "normal" way of doing things.

Greg
+22  A: 

Something like this could work:

<table>
    <tbody>
      <tr><td>Column1</td><td>Column2</td></tr>
      <tr><td>Column1</td><td>Column2</td></tr>
      <tr class="Show_Rows"><td>Start</td><td>Hiding</td></tr>
    </tbody>
    <tbody class="Table_Middle" style="display:none">
      <tr><td>Column1</td><td>Column2</td></tr>
      <tr><td>Column1</td><td>Column2</td></tr>
      <tr><td>Column1</td><td>Column2</td></tr>
    </tbody>
    <tbody>
      <tr class="Show_Rows"><td>End</td><td>Hiding</td></tr>
      <tr><td>Column1</td><td>Column2</td></tr>
      <tr><td>Column1</td><td>Column2</td></tr>
    </tbody>
</table>


$('#something').click( function() {
    $('.Table_Middle').hide();
    $('.Show_Rows').show();
});

$('.Show_Rows').click( function() { 
    $('.Show_Rows').hide();
    $('.Table_Middle').show();
});
Parand
That's not good because you are not allowed a <span> element directly inside a <table> element in HTML or XHTML. I think this would be OK if you used tbody instead of span.
SpoonMeiser
You're right, I was being lazy, changed it to be tbody.
Parand
I'll un-down-vote you then :)
SpoonMeiser
Thanks! I added a complete working example after viewing and understanding your example answer.
Brian Boatright
btw you are missing a closing ) on the first function call.
Brian Boatright
This is similar to what I would have suggested - upvote
belugabob
+1  A: 

I'd probably do it like this:

<table>
    <thead>
        <tr>
            <th>Col1</th>
            <th>Col2</th>
            <th>Col3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>data1</td>
            <td>data1</td>
            <td>data1</td>
        </tr>
        ...
    </tbody>
    <tbody id="hidden-rows">
        <tr>
            <td colspan="3">
                <a href="#" onclick="$('#hidden-rows').hide();$('#extra-rows').show();">
                    Show hidden rows
                </a>
            </td>
        </tr>
    </tbody>
    <tbody id="extra-rows" style="display: none;">
        <tr>
            <td>data1</td>
            <td>data1</td>
            <td>data1</td>
        </tr>
        ...
    </tbody>
    <tbody>
        <tr>
            <td>data1</td>
            <td>data1</td>
            <td>data1</td>
        </tr>
        ...
    </tbody>
</table>

It's not a great method, because it doesn't degrade nicely.

To get it to degrade nicely, you'd have to have all the rows shown initially, and then hide them with your jQuery document ready function, and also create the row with the link in.

Also, your method of giving the rows to hide a particular class should also work. The jQuery would look something like this:

$(document).ready(function() {
    $('tr.Table_Middle').hide();
});

You'd still need to create the row with the link to unhide them though.

SpoonMeiser
+1  A: 

If you give your middle <tr /> tags the "Table_Middle" class it makes it much easier to do. Then it only takes a few lines of jQuery. One to add the "Show Full Table" row, and another to add a click listener for that row. Make sure to change the colspan attribute's "X" value to the number of columns in your table.

 // jQuery chaining is useful here
 $(".Table_Middle").hide()
                   .eq(0)
                   .before('<tr colspan="X" class="showFull">Show Full Table<tr/>');

$(".showFull").click(function() {
    $(this).toggle();
    $(".Table_Middle").toggle();
});

This is useful because it degrades nicely and is accessible across lots of browsers/devices. If JavaScript is turned off, or CSS is disabled (or any other scenario that could cause this code to not be supported), there is no "show full table" row.

Dan Herbert
Have you tested this? I think the get method returns a DOM object, not a jquery object, and I think you're only hiding that first Table_Middle row because hide is called after get. I've not tested it either, but if I'm right, then it needs to be re-arranged slightly to work.
SpoonMeiser
You're right. I can't believe I missed that. "get()" returns a DOM object. I've updated my code sample to acknowledge that.
Dan Herbert
You could just use .eq(0) instead of .get(0) to return jQuery instead of a DOM element. But this is totally the best answer here.
SpoonMeiser
+2  A: 

Here's a solution which doesn't require any extra markup and it degrades nicely.

<table id="myTable">
    <tbody>
        <tr><td>Cell</td><td>Cell</td></tr>
        <tr><td>Cell</td><td>Cell</td></tr>
        <tr><td>Cell</td><td>Cell</td></tr>
        <tr><td>Cell</td><td>Cell</td></tr>
        <tr><td>Cell</td><td>Cell</td></tr>
    </tbody>
</table>

and the jQuery... I've hardcoded in a few things here (like the table identifier, number of rows to show, etc. These could be put into a class attribute on the table if you wanted it to be more reusable. (eg: <table class="hidey_2">)

var showTopAndBottom = 2,
    minRows = 4,
    $rows = $('#myTable tr').length),
    length = $rows.length
;
if (length > minRows) {
    $rows
        .slice(showTopAndBottom, length - showTopAndBottom)
        .hide()
    ;
    $rows
        .eq(showTopAndBottom - 1)
        .after(
            // this colspan could be worked out by counting the cells in another row
            $("<tr><td colspan=\"2\">Show</td></tr>").click(function() {
                $(this)
                    .remove()
                    .nextAll()
                    .show()
                ;
            })
        )
    ;
}
nickf
A: 

Try to use slice() method:

$("#table tr").slice(1, 4).hide();
Elzo Valugi