Collapsing tables within tables - javascript

I am attempting to collapse a table when the onclick event occurs. I iterate through the rows of a table and either set their visibility to collapse or to visible. If there is a table in one of the table data elements, setting the visibility of the row to visible doesn't affect the visibility of the table within. I tried to make the center loop recursive and call it on any inner table nodes, but that doesn't fix it. How can I fix this issue?
main.html
<html>
<head>
<title>Hello World</title>
</head>
<body>
<table class="collapsible" cellpadding="2" cellspacing="0" border="2" bgcolor="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 1</td>
<td style="word-wrap: break-word;">datum 2</td>
</tr>
<tr>
<td>
<table CELLPADDING="2" CELLSPACING="0" BORDER="2" BGCOLOR="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 3</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 4</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 5</td>
<td style="word-wrap: break-word;">datum 6</td>
</tr>
</table>
<script>
var tbls = document.getElementsByClassName("collapsible");
var tblCnt = tbls.length;
init();
function init() {
var i;
for (i=0; i<tblCnt; i++) {
tbls[i].addEventListener("click", collapse);
}
}
function collapse() {
collapseAlg(this,1)
}
// start=0 -> collapse all rows, start=1 -> collapse all except the first row (assume no th)
function collapseAlg(tbl, start) {
console.log("called", tbl);
var rows = tbl.getElementsByTagName("tr");
var i;
var j;
var datum;
for (i = start; i < rows.length; i++) {
if (window.getComputedStyle(rows[i]).visibility === "collapse") {
rows[i].style.visibility = "visible";
tblss = rows[i].getElementsByTagName("table");
for (j=0; j < tblss.length; j++) {
collapseAlg(tblss[j],0);
}
} else {
rows[i].style.visibility = "collapse";
}
}
}
</script>
</body>
</html>

Great question. The issue is with this code:
var rows = tbl.getElementsByTagName("tr");
That retrieves all the table's TR elements, including those within sub-tables.
You want only the .collapsible table's rows. This is a little tricky, because tables automatically add TBODY elements if you haven't done so explicitly.
This gives the rows you need:
var rows = tbl.querySelectorAll(":scope > tbody > tr");
And you can get rid of this code:
tblss = rows[i].getElementsByTagName("table");
for (j=0; j < tblss.length; j++) {
collapseAlg(tblss[j],0);
}
Snippet:
var tbls = document.getElementsByClassName("collapsible");
var tblCnt = tbls.length;
init();
function init() {
var i;
for (i = 0; i < tblCnt; i++) {
tbls[i].addEventListener("click", collapse);
}
}
function collapse() {
collapseAlg(this, 1)
}
// start=0 -> collapse all rows, start=1 -> collapse all except the first row (assume no th)
function collapseAlg(tbl, start) {
console.log("called", tbl);
var rows = tbl.querySelectorAll(":scope > tbody > tr");
var i;
var j;
var datum;
for (i = start; i < rows.length; i++) {
if (window.getComputedStyle(rows[i]).visibility === "collapse") {
rows[i].style.visibility = "visible";
} else {
rows[i].style.visibility = "collapse";
}
}
}
<table class="collapsible" cellpadding="2" cellspacing="0" border="2" bgcolor="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 1</td>
<td style="word-wrap: break-word;">datum 2</td>
</tr>
<tr>
<td>
<table CELLPADDING="2" CELLSPACING="0" BORDER="2" BGCOLOR="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 3</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 4</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 5</td>
<td style="word-wrap: break-word;">datum 6</td>
</tr>
</table>

Related

loop over table to set the background css

My HTML table has some classes and table tag is used
Want to retain the classes as is, but all my table and tr , th or td are using td bgcolor which is an old technique.
I want to loop over the table and find if that bgcolor is defined, use the same color and convert it to a css based background color so i can print it in IE
function setBackground() {
var table = document.getElementById("table1");
//i found this in a previous stack overflow answer and tried it
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
//this is for debugging purposes... I can't even get this to work
alert(table.rows[i].cells[j]);
table.rows[i].cells[j].style.background = "orange"; //just an example
}
}
}
because IE is not able to print the background lines and colors for some reason using the webkit property
I cleaned up the for loops a little. You can read the attribute with getAttribute and set the style.
var table = document.getElementById("table1");
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i]
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j]
var bgc = cell.getAttribute('bgcolor')
if (bgc) {
cell.style.background = bgc
}
}
}
td {
width: 30px; height: 30px;
}
<table id="table1">
<tr>
<td bgcolor="red"></td>
<td></td>
<td bgcolor="blue"></td>
</tr>
<tr>
<td></td>
<td bgcolor="green"></td>
<td></td>
</tr>
<tr>
<td bgcolor="yellow"></td>
<td></td>
<td></td>
</tr>
<tr>
<td bgcolor="silver"></td>
<td></td>
<td></td>
</tr>
</table>
You can just do it with one loop with getElementsByTagName
var tds = document.getElementById("table1").getElementsByTagName("td");
for (var i = 0; i < tds.length; i++) {
var cell = tds[i]
var bgc = cell.getAttribute('bgcolor')
if (bgc) {
cell.style.background = bgc
}
}
td {
width: 30px; height: 30px;
}
<table id="table1">
<tr>
<td bgcolor="red"></td>
<td></td>
<td bgcolor="blue"></td>
</tr>
<tr>
<td></td>
<td bgcolor="green"></td>
<td></td>
</tr>
<tr>
<td bgcolor="yellow"></td>
<td></td>
<td></td>
</tr>
<tr>
<td bgcolor="silver"></td>
<td></td>
<td></td>
</tr>
</table>
Get the color if found and then do with it whatever needed...
function setBackgroundColor(colorValue) {
const table = document.getElementById("table1");
const rows = table.children[0].rows
for (let i = 0; i < rows.length; i++) {
const tds = rows[i].children;
for (let j = 0; j < tds.length; j++) {
if (tds[j].bgColor === colorValue) {
console.log('Color found, do action')
}
}
}
}
setBackgroundColor('red')
<table id="table1">
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td bgcolor="red">January</td>
<td bgcolor="green">$100</td>
</tr>
</table>
You can do this:
var cells = $("#targetTable td");
for(i in cells){
color = $(cells[i]).attr('bgcolor');
console.log(color);
$(cells[i]).css({background: color});
}
as Taplar mentioned in the comment :
Use document.querySelectorAll('td[bgcolor]') to get the td that have bgcolor, loop through them and set the background to that color :
document.querySelectorAll('td[bgcolor]').forEach(e => {
const bgColor = e.getAttribute('bgcolor');
e.removeAttribute('bgcolor'); // optional, if you want to remove the attribute
e.style.background = bgColor;
})
<table id="table1">
<thead>
<th>A</th>
<th>B</th>
<th>C</th>
</thead>
<tbody>
<tr>
<td bgcolor="red">1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td bgcolor="green">5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td bgcolor="blue">9</td>
</tr>
</tbody>
</table>

Delete a column

I have a table and I want to delete the column of a table. I have written a code to delete a particular column.
function deleteColumn(index) {
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(index);
}
}
Now What should do so that I could select a particular column(header) and click on delete so that that particular column gets deleted?
You can refer this link for delete column http://www.mredkj.com/tutorials/tableaddcolumn.html
function deleteColumn(tblId)
{
var allRows = document.getElementById(tblId).rows;
for (var i=0; i<allRows.length; i++) {
if (allRows[i].cells.length > 1) {
allRows[i].deleteCell(-1);
}
}
}
// 2006-08-21 - Created
// 2006-11-05 - Modified - head and body
function addColumn(tblId)
{
var tblHeadObj = document.getElementById(tblId).tHead;
for (var h=0; h<tblHeadObj.rows.length; h++) {
var newTH = document.createElement('th');
tblHeadObj.rows[h].appendChild(newTH);
newTH.innerHTML = '[th] row:' + h + ', cell: ' + (tblHeadObj.rows[h].cells.length - 1)
}
var tblBodyObj = document.getElementById(tblId).tBodies[0];
for (var i=0; i<tblBodyObj.rows.length; i++) {
var newCell = tblBodyObj.rows[i].insertCell(-1);
newCell.innerHTML = '[td] row:' + i + ', cell: ' + (tblBodyObj.rows[i].cells.length - 1)
}
}
function deleteColumn(tblId)
{
var allRows = document.getElementById(tblId).rows;
for (var i=0; i<allRows.length; i++) {
if (allRows[i].cells.length > 1) {
allRows[i].deleteCell(-1);
}
}
}
<form>
<p>
<input type="button" value="add column" onclick="addColumn('tblSample')" />
<input type="button" value="delete column" onclick="deleteColumn('tblSample')" />
</p>
<table id="tblSample" border="1">
<thead>
<tr>
<th>[th] row:0, cell: 0</th>
<th>[th] row:0, cell: 1</th>
<th>[th] row:0, cell: 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>[td] row:0, cell: 0</td>
<td>[td] row:0, cell: 1</td>
<td>[td] row:0, cell: 2</td>
</tr>
<tr>
<td>[td] row:1, cell: 0</td>
<td>[td] row:1, cell: 1</td>
<td>[td] row:1, cell: 2</td>
</tr>
<tr>
<td>[td] row:2, cell: 0</td>
<td>[td] row:2, cell: 1</td>
<td>[td] row:2, cell: 2</td>
</tr>
</tbody>
</table>
</form>
To delete a particular column, you can use the cellIndex of the element (see: TableData cellIndex Property)
function deleteColumn(element) {
var idx = element.cellIndex;
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(idx);
}
}
}
<table id="testBenchTable">
<tr>
<th onclick="deleteColumn(this)">Month</th>
<th onclick="deleteColumn(this)">Savings</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
</table>
function deleteColumn(event) {
var index = event.target.cellIndex;
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(index);
}
}
}
<table style="width:100%" id="testBenchTable">
<tr>
<th onclick="deleteColumn(event)">Firstname</th>
<th onclick="deleteColumn(event)">Lastname</th>
<th onclick="deleteColumn(event)">Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>

Loop through elements in a HTML table

I am learning Javascript, in a school assignment we have to by using a loop count how many games was made in 2014.
It does not return anything in the console, where have I gone wrong?
var allGames = document.getElementsByTagName('td');
var array = Array.prototype.slice.call(allGames, 0)
var games14 = 0;
for (var i = 0; i < array.length; ++i) {
if (array[i] == 2014) {
games14++;
console.log(games14)
}
}
<table id="games">
<thead>
<tr>
<th>Titel</th>
<th>Genre</th>
<th>Årstal</th>
</tr>
</thead>
<tbody id="games_tbody">
<tr class="horror">
<td class="title">Outlast</td>
<td>Horror</td>
<td>2013</td>
</tr>
<tr class="rpg">
<td class="title">Dragon Age: Inquisition</td>
<td>Role-playing Game</td>
<td>2014</td>
</tr>
<tr class="rpg">
<td class="title">Skyrim</td>
<td>Role-playing Game</td>
<td>2011</td>
</tr>
<tr class="horror">
<td class="title">Amnesia: The Dark Descent</td>
<td>Horror</td>
<td>2010</td>
</tr>
<tr class="simulator">
<td class="title">Scania Truck Driving Simulator</td>
<td>Simulator</td>
<td>2012</td>
</tr>
<tr class="horror">
<td class="title">Five Nights at Freddy’s</td>
<td>Horror</td>
<td>2014</td>
</tr>
<tr class="simulator">
<td class="title">Sims 4</td>
<td>Simulator</td>
<td>2014</td>
</tr>
<tr class="rts" id="last">
<td class="title">Warcraft III: Reign of Chaos</td>
<td>Real-time Strategy</td>
<td>2002</td>
</tr>
</tbody>
</table>
You need to check for its text:
var allGames = document.getElementsByTagName('td');
...
if (array[i].innerHTML == '2014') {
OR,
if(array[i].innerText == '2014' || array[i].textContent == '2014'){
No need to do Loop through elements in a HTML table.. You can simply use regular expressions to count all occurrences within the games_tbody:
var games14 = document
.getElementById('games_tbody')
.innerText
.match(/2014/g)
.length;
console.log('Games made in 2014:', games14);
<table id="games">
<thead>
<tr><th>Titel</th><th>Genre</th><th>Årstal</th></tr>
</thead>
<tbody id="games_tbody">
<tr class="horror"><td class="title">Outlast</td><td>Horror</td><td>2013</td></tr>
<tr class="rpg"><td class="title">Dragon Age: Inquisition</td><td>Role-playing Game</td><td>2014</td></tr>
<tr class="rpg"><td class="title">Skyrim</td><td>Role-playing Game</td><td>2011</td></tr>
<tr class="horror"><td class="title">Amnesia: The Dark Descent</td><td>Horror</td><td>2010</td></tr>
<tr class="simulator"><td class="title">Scania Truck Driving Simulator</td><td>Simulator</td><td>2012</td></tr>
<tr class="horror"><td class="title">Five Nights at Freddy’s</td><td>Horror</td><td>2014</td></tr>
<tr class="simulator"><td class="title">Sims 4</td><td>Simulator</td><td>2014</td></tr>
<tr class="rts" id="last"><td class="title">Warcraft III: Reign of Chaos</td><td>Real-time Strategy</td><td>2002</td></tr>
</tbody>
</table>
array[i] == 2014
Everything in the array will be an HTML Table Data Cell Element object.
Nothing in the array will be the Number 2014.
You need to read the text content from the element and then compare that.
I think this is a better way.
var table = document.getElementById("games");
count = 0;
for (let i = 0; row = table.rows[i]; i++) {
if (row.cells[2].innerHTML === "2014"){
count++;
}
/*
for (let j = 0; col = row.cells[j]; j++) {
if (col.innerHTML === "2014"){
count++;
}
}
*/
}
console.log(count);
The commented code is for checking every item on a single row.

JS - Compare first row to other rows in table

I'm a completely newbie and looking for help.
Given the following table:
<table id="table">
<thead>
# FIRST ROW
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
</tr>
<tbody>
# SECOND ROW
<tr>
<td>Apple</td> --> should end with 'success' class
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td> --> should end with 'success' class
</tr>
# THIRD ROW
<tr>
<td>Pizza</td> --> should end with 'success' class
<td>Chicken</td>
</tr>
</tbody>
</table>
I would like to add class 'success' to every td in SECOND and THIRD rows whenever it matches any td in FIRST row (and only in FIRST ROW).
For now I came up with adding <td> values of first row to array and I'm not sure what steps should I take next (filter? for loop and '===' comparison?):
function myFunction() {
var tHeadersValues = [];
var tHeaders = document.getElementById("table").rows[0].cells;
for (var i = 0; i < tHeaders.length; i++) {
tHeadersValues.push(tHeaders[i].textContent);
}
return tHeadersValues;
}
Object.keys(tHeaders).map(key => tHeaders[key].textContent) transforms the td objects to an array with the containing text. The rest is straight forward:
function toValues(tHeaders) {
return Object.keys(tHeaders).map(function(key){
return tHeaders[key].textContent;
});
}
function myFunction() {
var rows = document.getElementById("results-table").rows;
var tHeadersValues = toValues(rows[0].cells);
for (var i = 1; i < rows.length; i++) {
var rowCells = rows[i].cells;
var values = toValues(rowCells);
for(var j=0;j<values.length;j++) {
if(values[j].length > 0 && tHeadersValues.indexOf(values[j]) > -1) {
rowCells[j].className = "success";
}
}
}
}
myFunction();
<style>
.success {
background-color: green;
}
</style>
<table id="results-table">
<thead>
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td>
</tr>
<tr>
<td>Pizza</td>
<td>Chicken</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
function myFunc(){
var tds = document.getElementsByTagName("td");
var hds = document.getElementsByTagName("th");
for(var i=0; i<tds.length; i++) {
var tdContent = tds[i].innerHTML;
if(tdContent.length > 0){
for(var j = 0; j<hds.length; j++) {
if(tdContent === hds[j].innerHTML) {
document.getElementsByTagName("td")[i].className = "success";
}
}
}
}
}
myFunc();
<style>
.success {
background-color: green;
}
</style>
<table id="results-table">
<thead>
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td>
</tr>
<tr>
<td>Pizza</td>
<td>Chicken</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>

merging <td> rows in one column of html table

I have a requirement, if i have same data in column1 of 's with same id then i need to merge those cells and show their respective values in column2.
i.e., in fiddle http://jsfiddle.net/7t9qkLc0/12/ the key column have 3rows with data 1 as row value with same id and has corresponding different values in Value column i.e., AA,BB,CC. I want to merge the 3 rows in key Column and display data 1 only once and show their corresponding values in separate rows in value column.
Similarly for data4 and data5 the values are same i.e.,FF and keys are different, i want to merge last 2 rows in Value column and dispaly FF only one time and show corresponding keys in key column. All data i'm getting would be the dynamic data. Please suggest.
Please find the fiddle http://jsfiddle.net/7t9qkLc0/12/
Sample html code:
<table width="300px" height="150px" border="1">
<tr><th>Key</th><th>Value</th></tr>
<tr>
<td id="1">data 1</td>
<td id="aa">AA</td>
</tr>
<tr>
<td id="1">data 1</td>
<td id="bb">BB</td>
</tr>
<tr>
<td id="1">data 1</td>
<td id="cc">CC</td>
</tr>
<tr>
<td id="2">data 2</td>
<td id="dd">DD</td>
</tr>
<tr>
<td id="2">data 2</td>
<td id="ee">EE</td>
</tr>
<tr>
<td id="3">data 3</td>
<td id="ff">FF</td>
</tr>
<tr>
<td id="4">data 4</td>
<td id="ff">FF</td>
</tr>
<tr>
<td id="5">data 5</td>
<td id="ff">FF</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="3" style="padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
</td>
</tr>
</table>
Building on tkounenis' answer using Rowspan:
One option to implement what you need would be to read all the values in your table after being populated, then use a JS object literal as a data structure to figure out what rows/columns are unique.
A JS object literal requires a unique key which you can map values to. After figuring out what rows/columns should be grouped, you can either edit the original table, or hide the original table and create a new table (I'm creating new tables in this example).
I've created an example for you to create a new table either grouped by key or grouped by value. Try to edit the examples provided to introduce both requirements.
Let me know if you need more help. Best of luck.
JSFiddle: http://jsfiddle.net/biz79/x417905v/
JS (uses jQuery):
sortByCol(0);
sortByCol(1);
function sortByCol(keyCol) {
// keyCol = 0 for first col, 1 for 2nd col
var valCol = (keyCol === 0) ? 1 : 0;
var $rows = $('#presort tr');
var dict = {};
var col1name = $('th').eq(keyCol).html();
var col2name = $('th').eq(valCol).html();
for (var i = 0; i < $rows.length; i++) {
if ($rows.eq(i).children('td').length > 0) {
var key = $rows.eq(i).children('td').eq(keyCol).html();
var val = $rows.eq(i).children('td').eq(valCol).html();
if (key in dict) {
dict[key].push(val);
} else {
dict[key] = [val];
}
}
}
redrawTable(dict,col1name,col2name);
}
function redrawTable(dict,col1name,col2name) {
var $table = $('<table>').attr("border",1);
$table.css( {"width":"300px" } );
$table.append($('<tr><th>' +col1name+ '</th><th>' +col2name+ '</th>'));
for (var prop in dict) {
for (var i = 0, len = dict[prop].length; i< len; i++) {
var $row = $('<tr>');
if ( i == 0) {
$row.append( $("<td>").attr('rowspan',len).html( prop ) );
$row.append( $("<td>").html( dict[prop][i] ) );
}
else {
$row.append( $("<td>").html( dict[prop][i] ) );
}
$table.append($row);
}
}
$('div').after($table);
}
Use the rowspan attribute like so:
<table width="300px" height="150px" border="1">
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td id="1" rowspan="3">data 1</td>
<td id="aa">AA</td>
</tr>
<tr>
<td id="bb">BB</td>
</tr>
<tr>
<td id="cc">CC</td>
</tr>
<tr>
<td id="2" rowspan="2">data 2</td>
<td id="dd">DD</td>
</tr>
<tr>
<td id="ee">EE</td>
</tr>
<tr>
<td id="3">data 3</td>
<td id="ff">FF</td>
</tr>
<tr>
<td id="4">data 4</td>
<td id="ff">FF</td>
</tr>
<tr>
<td id="5">data 5</td>
<td id="ff">FF</td>
</tr>
</table>
http://jsfiddle.net/37b793pz/4/
Can not be used more than once the same id. For that use data-id attribute
HTML:
<table width="300px" height="150px" border="1">
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td data-id="key1">data 1</td>
<td data-id="valaa">AA</td>
</tr>
<tr>
<td data-id="key1">data 1</td>
<td data-id="valbb">BB</td>
</tr>
<tr>
<td data-id="key1">data 1</td>
<td data-id="valcc">CC</td>
</tr>
<tr>
<td data-id="key2">data 2</td>
<td data-id="valdd">DD</td>
</tr>
<tr>
<td data-id="key2">data 2</td>
<td data-id="valee">EE</td>
</tr>
<tr>
<td data-id="key3">data 3</td>
<td data-id="valff">FF</td>
</tr>
<tr>
<td data-id="key4">data 4</td>
<td data-id="valff">FF</td>
</tr>
<tr>
<td data-id="key5">data 5</td>
<td data-id="valff">FF</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="3" style="padding-left: 0px; padding-right: 0px; padding-bottom: 0px"></td>
</tr>
</table>
JQ:
//merge cells in key column
function mergerKey() {
// prevents the same attribute is used more than once Ip
var idA = [];
// finds all cells id column Key
$('td[data-id^="key"]').each(function () {
var id = $(this).attr('data-id');
// prevents the same attribute is used more than once IIp
if ($.inArray(id, idA) == -1) {
idA.push(id);
// finds all cells that have the same data-id attribute
var $td = $('td[data-id="' + id + '"]');
//counts the number of cells with the same data-id
var count = $td.size();
if (count > 1) {
//If there is more than one
//then merging
$td.not(":eq(0)").remove();
$td.attr('rowspan', count);
}
}
})
}
//similar logic as for mergerKey()
function mergerVal() {
var idA = [];
$('td[data-id^="val"]').each(function () {
var id = $(this).attr('data-id');
if ($.inArray(id, idA) == -1) {
idA.push(id);
var $td = $('td[data-id="' + id + '"]');
var count = $td.size();
if (count > 1) {
$td.not(":eq(0)").remove();
$td.attr('rowspan', count);
}
}
})
}
mergerKey();
mergerVal();
Use below snippet of javascript. It should work fine for what you are looking.
<script type="text/javascript">
function mergeCommonCells(table, columnIndexToMerge){
previous = null;
cellToExtend = null;
table.find("td:nth-child("+columnIndexToMerge+")").each(function(){
jthis = $(this);
content = jthis.text();
if(previous == content){
jthis.remove();
if(cellToExtend.attr("rowspan") == undefined){
cellToExtend.attr("rowspan", 2);
}
else{
currentrowspan = parseInt(cellToExtend.attr("rowspan"));
cellToExtend.attr("rowspan", currentrowspan+1);
}
}
else{
previous = content;
cellToExtend = jthis;
}
});
};
mergeCommonCells($("#tableId"), 1);
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

Categories

Resources