Merge Equal Table Cells With JQuery
Solution 1:
If I get what you mean here, this my edited version: http://jsfiddle.net/djhU7/4/
So instead of $(this).text('')
I did this:
$($this.parent().prev().children()[index]).attr('rowspan', 2);
$this.hide();
What I did, was the I set the rowspan
of first cell to 2. This attribute "will indicates for how many rows the cell extends." which will make the above cell twice bigger, and I hid the cell with the duplicate information so the extra cell will go away. Note that removing the cell will ruin the index check for the next cell. This was a just a quick and dirty solution but rowspan
attribute has to be used somewhere to achieve it.
Here's another version, that sets rowspan on the time when inserting the cells into the table, beside the fact that it works with 3 duplicate cells and more, it's also faster, because it avoids re-rendering of the table(though it can be optimized more, but I don't think at this moment you wanna care about it, premature optimization is the root of all evil!): http://jsfiddle.net/g7uY9/1/
for (var i = 0; i < obj.length; i++) {
tr = $('<tr/>');
addColumn(tr, 'columnA', i);
addColumn(tr, 'columnB', i);
addColumn(tr, 'columnC', i);
$('#testTable').append(tr);
}
function addColumn(tr, column, i) {
var row = obj[i],
prevRow = obj[i - 1],
td = $('<td>' + row[column] + '</td>');
if (prevRow && row[column] === prevRow[column]) {
td.hide();
} else {
var rowspan = 1;
for (var j = i; j < obj.length - 1; j++) {
if (obj[j][column] === obj[j + 1][column]) {
rowspan++;
} else {
break;
}
}
td.attr('rowspan', rowspan);
}
tr.append(td);
}
Solution 2:
Please find the improved answer for your query with row expand/collapse. Here is my fiddle:
function MergeGridCells()
{
var dimension_cells = new Array();
var dimension_col = null;
var i = 1;
// First, scan first row of headers for the "Dimensions" column.
$("#mytable").find('th').each(function () {
if ($(this).text() == 'Id') {
dimension_col = i;
}
i++;
});
// first_instance holds the first instance of identical td
var first_instance = null;
var rowspan=1;
// iterate through rows
$("#mytable").find('tr.parent-grid-row').each(function () {
// find the td of the correct column (determined by the dimension_col set above)
var dimension_td = $(this).find('td.parent-grid-column:nth-child(' + dimension_col + ')');
if (first_instance == null) {
// must be the first row
first_instance = dimension_td;
} else if (dimension_td.text() == first_instance.text()) {
// the current td is identical to the previous
// remove the current td
dimension_td.remove();
++rowspan;
// increment the rowspan attribute of the first instance
first_instance.attr('rowspan', rowspan);
} else {
// this cell is different from the last
first_instance = dimension_td;
rowspan=1;
}
});
}
Solution 3:
Here's a runnable version of carla's answer:
function SummerizeTable(table) {
$(table).each(function() {
$(table).find('td').each(function() {
var $this = $(this);
var col = $this.index();
var html = $this.html();
var row = $(this).parent()[0].rowIndex;
var span = 1;
var cell_above = $($this.parent().prev().children()[col]);
// look for cells one above another with the same text
while (cell_above.html() === html) { // if the text is the same
span += 1; // increase the span
cell_above_old = cell_above; // store this cell
cell_above = $(cell_above.parent().prev().children()[col]); // and go to the next cell above
}
// if there are at least two columns with the same value,
// set a new span to the first and hide the other
if (span > 1) {
// console.log(span);
$(cell_above_old).attr('rowspan', span);
$this.hide();
}
});
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="SummerizeTable('#table1')">Summerize</button>
<table id="table1" border="1" cellspacing="0" >
<thead>
<tr>
<th>State</th>
<th>City</th>
<th>Street</th>
</tr>
</thead>
<tbody>
<tr>
<td>VT</td>
<td>Burlington</td>
<td>Elm</td>
</tr>
<tr>
<td>NY</td>
<td>Manhattan</td>
<td>Main</td>
</tr>
<tr>
<td>NY</td>
<td>Manhattan</td>
<td>Oak</td>
</tr>
<tr>
<td>NY</td>
<td>Albany</td>
<td>State</td>
</tr>
</tbody>
</table>
Solution 4:
I really liked Farid first solution, but I needed to select the range of lines and which columns it would be applied, so I made a few modifications (including the possiblity of more than 2 cells merge). http://jsfiddle.net/djhU7/72/
function Merge_cells($id_table,$lin_ini,$lin_fim,$array_col=array()){
$colunas="";
for($k=0;$k<count($array_col);$k++) $colunas=$colunas . " col =='$array_col[$k]' ||";
if(count($array_col)>0) $colunas="(".substr($colunas,0,-3).") &&";
echo "<script>
$('#$id_table td').each(function()
{
var \$this = $(this);
var col = \$this.index();
var txt = \$this.text();
var row = $(this).parent()[0].rowIndex;
//define the interval of lines and columns it will look at
if((col==0 || col==1 || col==2) row>=firstRow && row<=lastRow){
span=1;
cell_above = $(\$this.parent().prev().children()[col]);
//look for cells one above another with the same text
while(cell_above.text()=== txt){ //if the text is the same
span+=1; //increase the span
cell_above_old = cell_above; //store this cell
cell_above = $(cell_above.parent().prev().children()[col]); //and go to the next cell above
}
//if there are at least two columns with the same value, set a new span to the first and hide the other
if(span>1) {
console.log(span);
$(cell_above_old).attr('rowspan',span);
\$this.hide();
}
}
});
</script>";
}
Solution 5:
I extended carla's solution. With two functions, we can merge horizontally or vertically and exclude or include cells to merge. try the working sample. https://jsfiddle.net/bn3u63pe
/*
* merge horizontally
* ex) autoMergeByCol('theTable', 2, 0, 0);
*/
function autoMergeByCol(tableId
, rowStartIndex // zero or positive
, colStart // zero or positive
, colEnd // equals to colStart or greater than colStart or negative to go to the end of cols
) {
/*
console.log('autoMergeByCol tableId=' + tableId
+ ', rowStartIndex=' + rowStartIndex
+ ', colStart=' + colStart
+ ', colEnd=' + colEnd
);
*/
var trArr = $('#' + tableId).find('tr'); // rows array
for(var rowIndex = rowStartIndex ; rowIndex < trArr.length ; rowIndex++) {
var tdArr = $(trArr[rowIndex]).find('td'); // cols array of the row
if(colEnd < 0) colEnd = tdArr.length - 1; // if colEnd is negative, process at the end of the cols;
for(var colIndex = colStart ; colIndex < tdArr.length && colIndex <= colEnd ; colIndex++) {
var span = 1;
var theCell = $(tdArr)[colIndex];
if($(theCell).attr('rowspan')) {continue;}
var cellNext = $($(theCell).parent().children()[colIndex + span]);
while(cellNext != undefined
&& $(theCell).text() == $(cellNext).text()
&& colIndex + span <= colEnd ) {
span++;
cellNext.hide();
cellNext = $($(cellNext).parent().children()[colIndex + span]);
}
if(span > 1) $(theCell).attr('colspan', span);
}
}
}
/*
* merge vertically
* ex) autoMergeByCol('theTable', 2, 0, 0);
*/
function autoMergeByRow(tableId
, rowStartIndex // zero or positive
, colStart // zero or positive
, colEnd // equals to colStart or greater than colStart or negative
) {
/*
console.log('autoMergeByRow tableId=' + tableId
+ ', rowStartIndex=' + rowStartIndex
+ ', colStart=' + colStart
+ ', colEnd=' + colEnd
);
*/
var trArr = $('#' + tableId).find('tr'); // rows array
for(var rowIndex = rowStartIndex ; rowIndex < trArr.length ; rowIndex++) {
var tdArr = $(trArr[rowIndex]).find('td'); // cols array of the row
if(colEnd < 0) colEnd = tdArr.length - 1; // if colEnd is negative, process at the end of the cols;
for(var colIndex = colStart ; colIndex < tdArr.length && colIndex <= colEnd ; colIndex++) {
var span = 1;
var theCell = $(tdArr)[colIndex];
if($(theCell).attr('colspan')) {continue;}
var cellBelow = $($(theCell).parent().next().children()[colIndex]);
while(cellBelow != undefined
&& $(theCell).text() == $(cellBelow).text()) {
span++;
cellBelow.hide();
cellBelow = $($(cellBelow).parent().next().children()[colIndex]);
}
if(span > 1) $(theCell).attr('rowspan', span);
}
}
}
Post a Comment for "Merge Equal Table Cells With JQuery"