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:
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.