Jan 27, 2012

HTML Table Row Grouping with jQuery

It’s easy to group data in SQL statement, but if you have to display it using HTML table, It’s not drag and drop as in reporting environment. One way to group on server side and draw tr td accordingly. But If it is already created with tons of functionality attached, It’s risky to change. Don’t worry, you can do it easily with jQuery.

html table row grouping jquery

HTML:

Let’s take following HTML table as an example:

<table id="myTable" border="1" cellpadding="3" cellspacing="0">
<tr><th>Category</th><th>Product</th><th>Size</th><th>Price</th><th>Shipping</th></tr>
<tr><td>Category-1</td><td>Product-1</td><td>Big</td><td>102</td><td>Free</td></tr>
<tr><td>Category-1</td><td>Product-1</td><td>Big</td><td>132</td><td>Free</td></tr>
<tr><td>Category-1</td><td>Product-2</td><td>Big</td><td>130</td><td>Free</td></tr>
<tr><td>Category-1</td><td>Product-2</td><td>Small</td><td>100</td><td>Free</td></tr>
<tr><td>Category-2</td><td>Product-3</td><td>Big</td><td>130</td><td>Free</td></tr>
<tr><td>Category-2</td><td>Product-3</td><td>Big</td><td>100</td><td>Free</td></tr>
<tr><td>Category-2</td><td>Product-3</td><td>Small</td><td>100</td><td>10</td></tr>
<tr><td>Category-2</td><td>Product-4</td><td>Big</td><td>150</td><td>10</td></tr>
<tr><td>Category-3</td><td>Product-5</td><td>Big</td><td>150</td><td>10</td></tr>
<tr><td>Category-3</td><td>Product-5</td><td>Small</td><td>120</td><td>10</td></tr>
<tr><td>Category-3</td><td>Product-5</td><td>Big</td><td>120</td><td>Free</td></tr>
<tr><td>Category-4</td><td>Product-6</td><td>Big</td><td>120</td><td>10</td></tr>
<tr><td>Category-4</td><td>Product-6</td><td>Small</td><td>120</td><td>10</td></tr>
</table>

Script:

Before using the following method, Make sure the data is sorted. The logic is to check row by row if data is same in next row’s td, remove next row’s td and increase rowspan of current row’s td.

$(function() {	
//Created By: Brij Mohan
//Website: https://techbrij.com
function groupTable($rows, startIndex, total){
if (total === 0){
return;
}
var i , currentIndex = startIndex, count=1, lst=[];
var tds = $rows.find('td:eq('+ currentIndex +')');
var ctrl = $(tds[0]);
lst.push($rows[0]);
for (i=1;i<=tds.length;i++){
if (ctrl.text() ==  $(tds[i]).text()){
count++;
$(tds[i]).addClass('deleted');
lst.push($rows[i]);
}
else{
if (count>1){
ctrl.attr('rowspan',count);
groupTable($(lst),startIndex+1,total-1)
}
count=1;
lst = [];
ctrl=$(tds[i]);
lst.push($rows[i]);
}
}
}
groupTable($('#myTable tr:has(td)'),0,3);
$('#myTable .deleted').remove();
});

groupTable method has 3 arguments:
$rows: jQuery object of table rows to be grouped
startIndex: index of first column to be grouped
total: total number of columns to be grouped

In above code startIndex =0 and total = 3 it means table is grouped by first, second and third column. After grouping, you need to remove deleted class elements like this:
$(‘#myTable .deleted’).remove();

you can use code, but need to keep CREDIT COMMENT. The idea came to implement this just one hour ago. So the code can be optimized. Anyway, let me know if you have any issue.

20 comments

  1. Great Coding.
    However, I am using datatables.net, and after giving filter, its showing abnormal formatting..

    Is there any way to find if we have already implemented Grouping on Table, It its done once, we no need to apply grouping again..

    Any Idea?
    Br,

  2. Hi, The unction is amazing, but I have a question. how I can do if I need rowspan without keep the column before only some column of my grid?

    Thank you

    Adrian

  3. This is a great idea. Horribly inefficient, but exactly what I was trying to do. I’m going to try to impliment your logic a few different ways to see if I can make it fast.

Leave a Reply

Your email address will not be published. Required fields are marked *