Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

expand/collapse table rows with JQuery

Tags:

html

jquery

css

I want to expand and collapse table rows when header columns is clicked. I only want to expand/collapse rows which are under the specific header (clicked).

Here is my table structure:

 <table border="0">        <tr>          <td colspan="2">Header</td>        </tr>        <tr>          <td>data</td>          <td>data</td>        </tr>        <tr>          <td>data</td>          <td>data</td>        </tr>        <tr>          <td colspan="2">Header</td>        </tr>        <tr>          <td>date</td>          <td>data</td>        </tr>        <tr>          <td>data</td>          <td>data</td>        </tr>        <tr>          <td>data</td>          <td>data</td>        </tr>      </table>

Any thoughts on how can I accomplish this task. Using div this task seems quite simple, but I have tabular data which I want to manipulate.

One idea I can think of is to use css class in every row which distinguish rows in under each header and use JQuery to expand/collapse those rows only when header is clicked. But if my table has 10-15 headers then it seems difficult to keep track of css classes.

Please suggest a suitable way to achieve this.

like image 884
Saqib Avatar asked Jun 04 '13 20:06

Saqib


People also ask

How do you expand a table row?

The expandable table can be achieved by using JavaScript with HTML. By Clicking on a row of the table, it expands and a sub-table pops up. When the user again clicks on that row the content will hide.

How do you expand a table in HTML?

To set the table width in HTML, use the style attribute. The style attribute specifies an inline style for an element. The attribute is used with the HTML <table> tag, with the CSS property width.

How do you expand a table in CSS?

Just set the width and height of your table to 100%.


2 Answers

You can try this way:-

Give a class say header to the header rows, use nextUntil to get all rows beneath the clicked header until the next header.

JS

$('.header').click(function(){     $(this).nextUntil('tr.header').slideToggle(1000); }); 

Html

<table border="0">   <tr  class="header">     <td colspan="2">Header</td>   </tr>   <tr>     <td>data</td>     <td>data</td>   </tr>   <tr>     <td>data</td>     <td>data</td>   </tr> 

Demo

Another Example:

$('.header').click(function(){    $(this).find('span').text(function(_, value){return value=='-'?'+':'-'});     $(this).nextUntil('tr.header').slideToggle(100); // or just use "toggle()" }); 

Demo

You can also use promise to toggle the span icon/text after the toggle is complete in-case of animated toggle.

$('.header').click(function () {     var $this = $(this);     $(this).nextUntil('tr.header').slideToggle(100).promise().done(function () {         $this.find('span').text(function (_, value) {             return value == '-' ? '+' : '-'         });     }); }); 

.promise()

.slideToggle()

Or just with a css pseudo element to represent the sign of expansion/collapse, and just toggle a class on the header.

CSS:-

.header .sign:after{   content:"+";   display:inline-block;       } .header.expand .sign:after{   content:"-"; } 

JS:-

$(this).toggleClass('expand').nextUntil('tr.header').slideToggle(100); 

Demo

like image 62
PSL Avatar answered Sep 21 '22 13:09

PSL


The easiest way to achieve this, without changing the HTML table-based structure, is to use a class-name on the tr elements containing a header, such as .header, to give:

<table border="0">   <tr class="header">     <td colspan="2">Header</td>   </tr>   <tr>     <td>data</td>     <td>data</td>   </tr>   <tr>     <td>data</td>     <td>data</td>   </tr>   <tr class="header">     <td colspan="2">Header</td>   </tr>   <tr>     <td>date</td>     <td>data</td>   </tr>   <tr>     <td>data</td>     <td>data</td>   </tr>   <tr>     <td>data</td>     <td>data</td>   </tr> </table> 

And the jQuery:

// bind a click-handler to the 'tr' elements with the 'header' class-name: $('tr.header').click(function(){     /* get all the subsequent 'tr' elements until the next 'tr.header',        set the 'display' property to 'none' (if they're visible), to 'table-row'        if they're not: */     $(this).nextUntil('tr.header').css('display', function(i,v){         return this.style.display === 'table-row' ? 'none' : 'table-row';     }); }); 

JS Fiddle demo.

In the linked demo I've used CSS to hide the tr elements that don't have the header class-name; in practice though (despite the relative rarity of users with JavaScript disabled) I'd suggest using JavaScript to add the relevant class-names, hiding and showing as appropriate:

// hide all 'tr' elements, then filter them to find... $('tr').hide().filter(function () {     // only those 'tr' elements that have 'td' elements with a 'colspan' attribute:     return $(this).find('td[colspan]').length;     // add the 'header' class to those found 'tr' elements }).addClass('header')     // set the display of those elements to 'table-row':   .css('display', 'table-row')     // bind the click-handler (as above)   .click(function () {     $(this).nextUntil('tr.header').css('display', function (i, v) {         return this.style.display === 'table-row' ? 'none' : 'table-row';     }); }); 

JS Fiddle demo.

References:

  • addClass().
  • click().
  • css().
  • filter().
  • find().
  • hide().
  • nextUntil().
like image 40
David Thomas Avatar answered Sep 23 '22 13:09

David Thomas