Reputation: 10030
I have a set of tabular data that has changed. Now i have both the data rendered side by side in two html tables. Now I want to highlight the columns that have changed just like in svn file diff.
I tried doing it with this but I need to make it recursive but not sure how:
function CompareTables(table1, table2) {
var instHasChange = false;
for (var i = 0; i < table1.rows.length; i++) {
var changes = RowExists(table2, table1.rows[i].cells[0].innerHTML, table1.rows[i].cells[1].innerHTML);
if (!changes[0]) {
table1.rows[i].style.backgroundColor = "yellow";
instHasChange = true;
} else if (changes[1]) {
table1.rows[i].style.backgroundColor = "yellow";
instHasChange = true;
}
}
for (var i = 0; i < table2.rows.length; i++) {
var changes = RowExists(table1, table2.rows[i].cells[0].innerHTML, table2.rows[i].cells[1].innerHTML);
if (!changes[0]) {
table2.rows[i].style.backgroundColor = "yellow";
instHasChange = true;
} else if (changes[1]) {
table2.rows[i].style.backgroundColor = "yellow";
instHasChange = true;
}
}
return instHasChange;
}
function RowExists(table, columnName, columnValue) {
var hasColumnOrChange = new Array(2);
hasColumnOrChange[0] = false;
hasColumnOrChange[1] = false;
for (var i = 0; i < table.rows.length; i++) {
if (table.rows[i].cells[0].innerHTML == columnName) {
hasColumnOrChange[0] = true;
if (table.rows[i].cells[1].innerHTML != columnValue)
hasColumnOrChange[1] = true;
}
}
return hasColumnOrChange;
}
The above code only works if there are no inner tables inside this table(We represent data of db child tables in that way)
Please help! Thanks!
EDIT
I have found some more code that is valid for a single table but am not sure how to make it work for a table within a table. Posting the code here
function highLightDiffList() {
for (var k = 0; k < 8; k++) {
var mkrTname = 'table3' + k;
var actTname = 'table4' + k;
var makerTr = document.getElementById(mkrTname).childNodes;
var actualTr = document.getElementById(actTname).childNodes;
var makerStateLen = makerTr.length;
var actualStateLen = actualTr.length;
var actualState = 1;
var makerState = 1;
if (makerStateLen > 1)
makerState = makerTr.item(1).childNodes.item(0).childNodes;
if (actualStateLen > 1)
actualState = actualTr.item(1).childNodes.item(0).childNodes;
var makerTh = document.getElementById(mkrTname).getElementsByTagName("TH").length;
var minLen;
var maxLen;
var flag;
if (makerStateLen > actualStateLen) {
minLen = actualStateLen;
maxLen = makerStateLen;
flag = 1;
} else {
minLen = makerStateLen;
maxLen = actualStateLen;
flag = 2;
}
for (var i = 1; i < minLen; i++) {
for (var j = 0; j < makerTh; j++) {
if (makerTr.item(i).childNodes.item(0).childNodes.item(j).innerHTML != actualTr.item(i).childNodes.item(0).childNodes.item(j).innerHTML) {
makerTr.item(i).childNodes.item(0).childNodes.item(j).style.backgroundColor = document.getElementById('cColor').value;
actualTr.item(i).childNodes.item(0).childNodes.item(j).style.backgroundColor = document.getElementById('cColor').value;
}
}
}
for (var i = minLen; i < maxLen; i++) {
for (var j = 0; j < makerTh; j++) {
if (flag == 1)
makerTr.item(i).style.backgroundColor = document.getElementById('adColor').value;
if (flag == 2)
actualTr.item(i).style.backgroundColor = document.getElementById('adColor').value;
}
}
}
}
function highLightDiff() {
for (var j = 0; j < 6; j++) {
var mkrTname = 'table1' + j;
var actTname = 'table2' + j;
var makerTr = document.getElementById(mkrTname);
var actualTr = document.getElementById(actTname);
var makerStateLen = makerTr.childNodes.item(1).childNodes.length;
var actualStateLen = actualTr.childNodes.item(1).childNodes.length;
var makerState = makerTr.childNodes.item(1).childNodes;
var actualState = actualTr.childNodes.item(1).childNodes;
for (var i = 1; i < makerStateLen; i++) {
if (makerState.item(i).childNodes.item(1).innerHTML != '' && actualState.item(i).childNodes.item(1).innerHTML == '') {
makerState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('adColor').value;
actualState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('adColor').value;
} else {
if (makerState.item(i).childNodes.item(1).innerHTML == '' && actualState.item(i).childNodes.item(1).innerHTML != '') {
makerState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('adColor').value;
actualState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('adColor').value;
} else {
if (makerState.item(i).childNodes.item(1).innerHTML != actualState.item(i).childNodes.item(1).innerHTML) {
makerState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('cColor').value;
actualState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('cColor').value;
}
}
}
}
}
}
The inner table is created in the following manner:
<table>
<tbody>
<tr>
<td>
<div>
<table>
<tbody>
<tr>
<td>
Upvotes: 2
Views: 3097
Reputation: 1306
function CompareTables(table1, table2) {
var instHasChange = false;
for (var i = 0; i < table1.rows.length; i++) {
if (table1.rows[i].cells[0].innerHTML.indexOf('div') != -1) {
//call CompareTables with inner table
CompareTables(table1.rows[i].cells[0].childNodes[0].childNodes[0], table2);
}
else {
var changes = RowExists(table2, table1.rows[i].cells[0].innerHTML, table1.rows[i].cells[1].innerHTML);
if (!changes[0]) {
table1.rows[i].style.backgroundColor = "yellow";
instHasChange = true;
} else if (changes[1]) {
table1.rows[i].style.backgroundColor = "yellow";
instHasChange = true;
}
}
}
return instHasChange;
}
function RowExists(table, columnName, columnValue) {
var hasColumnOrChange = new Array(2);
hasColumnOrChange[0] = false;
hasColumnOrChange[1] = false;
for (var i = 0; i < table.rows.length; i++) {
if (table.rows[i].cells[0].innerHTML.indexOf('div') != -1) {
//call RowExists with inner table
hasColumnOrChange = RowExists(table.rows[i].cells[0].childNodes[0].childNodes[0], columnName, columnValue);
}
else {
if (table.rows[i].cells[0].innerHTML == columnName) {
hasColumnOrChange[0] = true;
if (table.rows[i].cells[1].innerHTML != columnValue)
hasColumnOrChange[1] = true;
}
}
//finish for loop if name was found
if (hasColumnOrChange[0] == true)
break;
}
return hasColumnOrChange;
}
Not tested but should work. might just have to add or remove another .childNodes[0] (or firstChild) if it is not exactly matching with the inner table.
Then you just have to call CompareTables(table1, table2) twice. Once with (table1, table2) and once with (table2, table1).
Upvotes: 1
Reputation: 4109
You might find it easier to do an actual textual diff on the inner table's HTML, then using the information from that to derive which cells have been changed/added/etc. For example, if you take each table's raw HTML (extract via innerHTML or whatever), make sure each opening tag and closing tag is on it's own line, you can then look for new/modified lines and map them back to cells based on the line number.
There are a few javascript diff implementations. You could also look at Dom-diff which is an implementation of a DOM-level diffing system that you may be able to make use of.
Upvotes: 1