Compare differences between two tables using Javascript [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
const firstTable = document.getElementById('table_1')
const secondTable = document.getElementById('table_2')
const rows1 = firstTable.rows
const rows2 = secondTable.rows
for (let i = 0; i < rows1.length; i++) {
for (let x in rows1[i].cells) {
let col = rows1[i].cells[x]
console.log(col)
}
for (let j = 0; j < rows2.length; j++) {
}
}
table {
border: 1px solid black;
}
td {
border: 1px solid black;
}
<table id="table_1">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
<tr>
<td>1</td>
<td>per</td>
<td style="background-color:red">27</td>
</tr>
<tr>
<td>2</td>
<td>Tom</td>
<td>25</td>
</tr>
<tr>
<td>notexist</td>
<td></td>
<td></td>
</tr>
</table>
<table id="table_2">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
<tr>
<td>1</td>
<td>per</td>
<td style="background-color:green">25</td>
</tr>
<tr>
<td>2</td>
<td>Tom</td>
<td>25</td>
</tr>
<tr>
<td>3</td>
<td>alex</td>
<td>33</td>
</tr>
</table>
I need to compare these two tables dynamically in javascript to get the result like the tables I put in the code. I need to compare every cell in every row if ids are equal. If id doesn't exist in the second table I need to write this not exist. For example, I put age in the first row of the first table not equal age in the second row of the second table. If Not equal, style background color to red or green.

from the DOM table, if they are identical(structure), you can make a loop on the TDs of one of them and compare textContent to the other standing at the same position:
here is an example
const firstTable = document.querySelectorAll("#table1 td");
const secondTable = document.querySelectorAll("#table2 td");
// loop on one of the table if both are of identical structure, else it is pointless
for (let i = 0; i < firstTable.length; i++) {
if (firstTable[i].textContent !== secondTable[i].textContent) {
firstTable[i].classList.add('redbg');// here do what you need to when not equal
}
// else { /* do what you need to if equal*/ }
}
.redbg {
background: red;
}
<table id="table1">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
<tr>
<td>1</td>
<td>per</td>
<td>27</td>
</tr>
<tr>
<td>2</td>
<td>Tom</td>
<td>25</td>
</tr>
<tr>
<td>notexist</td>
<td></td>
<td></td>
</tr>
</table>
<table id="table2">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
<tr>
<td>1</td>
<td>per</td>
<td>25</td>
</tr>
<tr>
<td>2</td>
<td>Tom</td>
<td>25</td>
</tr>
<tr>
<td>3</td>
<td>alex</td>
<td>33</td>
</tr>
</table>
from your array, idea can be the same loop on the first one and check if firstone and second got the same content at the same position, and add the class while building the table.

Related

Adding data-reverse attributes in JavaScript to dynamic HTML table

I am creating a HTML table dynamically and I want the headers to include data-reverse attribute in order to allow reverse sorting by pushing table headers:
<table>
<thead>
<tr>
<th data-reverse="true">Name</th>
<th data-reverse="true">Surname</th>
<th data-reverse="true">Age</th</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Smith</td>
<td>62</td>
</tr>
<tr>
<td>Dylan</td>
<td>Jones</td>
<td>37</td>
</tr>
<tr>
<td>Alan</td>
<td>Shearer</td>
<td>55</td>
</tr>
<tr>
<td>Ringo</td>
<td>Starr</td>
<td>52</td>
</tr>
</tbody>
</table>
The code slice is below. I am wondering what should be corrected in the addRow() function in order to produce the above output with data-reverse="true" attribute?
Or somewhere else.
addRow(thead, "th");
fragment.appendChild(thead);
function addRow(dom, tag) {
for(j=1;j<rowArray.length;j++){
var el = doc.createElement(tag);
el.setAttribute(data-reverse,"true");
el.innerHTML = rowArray[j];
tr.appendChild(el);
dom.appendChild(tr);
}
}

How to get a running sum on HTML table?

I searching a solution for give the running sun to a editable html table, like a spreadsheet:
Hi here is a basic example of what you want using :
The HTML content editable property.
A css class to append a focusout event to the table cell.
A simple loop to sum all values when one value changes.
$('#tbodyTest >tr').on('focusout', 'td.editable', (e) => {
let target = $(e.target),
parent_row = $(e.target).closest('tr'),
previous_row = parent_row.prev();
setTimeout(() => {
if (!isNaN(target.text())) {
$('#tbodyTest').children('tr').each((i,e)=>{
$(e).find('td').last().text(Number($(e).find('td:eq(2)').text()) +Number($(e).prev().find('td').last().text()))
})
}else{
target.text("0");
parent_row.find('td').last().text("0");
$('#tbodyTest').children('tr').each((i,e)=>{
$(e).find('td').last().text(Number($(e).find('td:eq(2)').text()) +Number($(e).prev().find('td').last().text()))
})
}
})
})
.editable {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="test" border=1>
<thead>
<th>date</th>
<th>desc</th>
<th>cost</th>
<th>running sum</th>
</thead>
<tbody id="tbodyTest">
<tr>
<td>01-01-2019</td>
<td>a</td>
<td class="editable" contenteditable='true'>1000</td>
<td>1000</td>
</tr>
<tr>
<td>01-02-2019</td>
<td>a</td>
<td class="editable" contenteditable='true'></td>
<td></td>
</tr>
<tr>
<td>01-03-2019</td>
<td>a</td>
<td class="editable" contenteditable='true'></td>
<td></td>
</tr>
<tr>
<td>01-04-2019</td>
<td>a</td>
<td class="editable" contenteditable='true'></td>
<td></td>
</tr>
</tbody>
</table>
Keep in mind that this is a basic example and you will probably add more stuff according to your needs since your ask is simple as well.
Hope it helps
Anyone still looking to this.
$('tr').each(function(index, el) {
if (index == 0) {
$(this).find('.running-balance').text($(this).find('.amount').text());
} else {
var prevRow = $(this).prev();
var prevBalance = Number(prevRow.find('.running-balance').text());
var currentAmount = Number($(this).find('.amount').text());
var newBalance = prevBalance + currentAmount;
$(this).find('.running-balance').text(newBalance.toFixed(2));
}
});
td,
th {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Description</th>
<th>Amount</th>
<th>Running Balance</th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td class="amount">100</td>
<td class="running-balance"></td>
</tr>
<tr>
<td>b</td>
<td class="amount">150</td>
<td class="running-balance"></td>
</tr>
<tr>
<td>c</td>
<td class="amount">125</td>
<td class="running-balance"></td>
</tr>
<tr>
<td>d</td>
<td class="amount">205</td>
<td class="running-balance"></td>
</tr>
<tr>
<td>e</td>
<td class="amount">50</td>
<td class="running-balance"></td>
</tr>
</tbody>
</table>

Remove specific index child from parent DOM with removeChild() [Vanilla Javascript]

i have a table with this basic structure:
<thead>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
<body>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
and i want to remove the second child from every "tr" tag, so i would like to do something like this:
const rows = document.getElementsByTagName('td')
for (let i = 0; i < rows.length; i++) {
rows[i].removeChild(target the second child here)
}
i'm looking for a solution with pure vanilla javascript (no jquery)
You might select the tds you want to remove via a single selector string, it's probably more elegant:
document.querySelectorAll('td:nth-child(2)')
.forEach(td => td.remove());
<table>
<thead>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
</tr>
</thead>
<tbody>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
</tr>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
</tr>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
</tr>
</tbody>
</table>
If the HTML is valid, the tds will necessarily be children of trs regardless, so you don't need to specify that the td's parent is a tr.
If you want to target a specific table on the page, rather than every td in every table, just put the table identifier in front of the selector string. Eg. if the target table's ID is 'table3', then use the selector string '#table3 td:nth-child(2)' to indicate td which are the second child in their parent, which are descendants of the element with ID table3.
In VanillaJS you can use document.querySelectorAll() and walk over the 2nd td using forEach()
[].forEach.call(document.querySelectorAll('#myTable td:nth-child(2)'), function(td) {
td.remove();
});
//$("#myTable td:nth-child(2)").remove()
[].forEach.call(document.querySelectorAll('#myTable td:nth-child(2)'), function(td) {
td.remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<thead>
<tr>
<td>TD-1</td>
<td>TD-2</td>
<td>TD-3</td>
</tr>
</thead>
<tbody>
<tr>
<td>TD-1</td>
<td>TD-2</td>
<td>TD-3</td>
</tr>
<tr>
<td>TD-1</td>
<td>TD-2</td>
<td>TD-3</td>
</tr>
<tr>
<td>TD-1</td>
<td>TD-2</td>
<td>TD-3</td>
</tr>
</tbody>
</table>
You can use a query selector with nth-child.
const rows = document.getElementsByTagName('tr')
for (let i = 0; i < rows.length; i++) {
rows[i].removeChild(rows[i].querySelector('td:nth-child(2)'));
}
<table>
<thead>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
</table>
<script>
var rows = document.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
var row = rows[i];
var td = row.querySelector('td:nth-child(2)');
row.removeChild(td);
}
</script>

Join table rows

I have an unfinished table structure:
<table>
<tr>
<td>ID</td>
<td>Animal</td>
<td>color</td>
<td>age</td>
</tr>
<tr>
<td rowspan="2">1</td>
</tr>
<tr>
<td rowspan="2">2</td>
</tr>
</table>
I want to append the following rows:
<table>
<tr>
<td>dog</td>
<td>brown</td>
<td>5</td>
</tr>
<tr>
<td>cat</td>
<td>white</td>
<td>3</td>
</tr>
<tr>
<td>cat</td>
<td>black</td>
<td>7</td>
</tr>
<tr>
<td>mouse</td>
<td>grey</td>
<td>2</td>
</tr>
</table>
So that the final table looks like that:
<table>
<tr>
<td>ID</td>
<td>Animal</td>
<td>color</td>
<td>age</td>
</tr>
<tr>
<td rowspan="2">1</td>
<td>dog</td>
<td>brown</td>
<td>5</td>
</tr>
<tr>
<td>cat</td>
<td>white</td>
<td>3</td>
</tr>
<tr>
<td rowspan="2">2</td>
<td>cat</td>
<td>black</td>
<td>7</td>
</tr>
<tr>
<td>mouse</td>
<td>grey</td>
<td>2</td>
</tr>
</table>
I'm creating that table dynamically, in an each-loop, so row by row.
That is my approach:
// 1st iteration
tr = "<tr><td>dog</td><td>brown</td><td>5</td></tr>";
$('table tr:eq(1)').append(tr)
// 2nd iteration
tr = "<tr><td>cat</td><td>white</td><td>3</td></tr>";
$('table tr:eq(1)').append(tr)
But the result doesn't look as intended.
Here is a fiddle.
In the first iteration you should append tr body in existing row (without parent tag).
In the second iteration you should put tr after existing row.
/* The rows to append
<tr><td>dog</td><td>brown</td><td>5</td></tr>
<tr><td>cat</td><td>white</td><td>3</td></tr>
<tr><td>cat</td><td>black</td><td>7</td></tr>
<tr><td>mouse</td><td>grey</td><td>2</td></tr>
*/
// 1st iteration
tr = "<tr><td>dog</td><td>brown</td><td>5</td></tr>";
$('table tr:eq(1)').append($(tr).html())
// 2nd iteration
tr = "<tr><td>cat</td><td>white</td><td>3</td></tr>";
$('table tr:eq(1)').after(tr)
// 3rd iteration
tr = "<tr><td>cat</td><td>black</td><td>7</td></tr>";
$('table tr:eq(3)').append($(tr).html())
// 4th iteration
tr = "<tr><td>mouse</td><td>grey</td><td>2</td></tr>";
$('table tr:eq(3)').after(tr)
table,
tr,
td {
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>ID</td>
<td>Animal</td>
<td>color</td>
<td>age</td>
</tr>
<tr>
<td rowspan="2">1</td>
</tr>
<tr>
<td rowspan="2">2</td>
</tr>
</table>
The first iteration should only include the <td>s and not a <tr> since you are adding it to an existing row. You don't want to append a <tr> to another <tr>
Use after() in the second iteration. Here you should use a <tr>
Try changing it to something like this:
// 1st iteration
tr = "<td>dog</td><td>brown</td><td>5</td>";
$('table tr:eq(1)').append(tr)
// 2nd iteration
tr = "<tr><td>cat</td><td>white</td><td>3</td></tr>";
$('table tr:eq(1)').after(tr)
You need to add row number every odd list item. That way you can add as many
item as possible to your table.
var data = [
'<tr><td>dog</td><td>brown</td><td>5</td></tr>',
'<tr><td>cat</td><td>white</td><td>3</td></tr>',
'<tr><td>cat</td><td>black</td><td>7</td></tr>',
'<tr><td>mouse</td><td>grey</td><td>2</td></tr>',
'<tr><td>dog</td><td>brown</td><td>5</td></tr>',
'<tr><td>cat</td><td>white</td><td>3</td></tr>',
'<tr><td>cat</td><td>black</td><td>7</td></tr>',
'<tr><td>mouse</td><td>grey</td><td>2</td></tr>'
];
var rowNo = 1;
for (var i = 0; i <= data.length; i++) {
var $current = $(data[i]); // Converting data to jQuery item.
// On every odd row add row Number cell to the begining of <tr> tag.
if ((i + 1) % 2 == 1) {
$current.prepend('<td rowspan="2">' + rowNo + '</td>');
rowNo++;
}
$('table').append($current);
}
table,
tr,
td {
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>ID</td>
<td>Animal</td>
<td>color</td>
<td>age</td>
</tr>
</table>
I also updated your JSFiddle. Check this out: JSFiddle

How to Auto fill a column using JavaScript?

I am trying to create a check list. How is it possible to automatically fill the "Check List Status" column using JavaScript?
What I want to do is, for example:
If document type is equal to client agreement than the check list status should be marked automatically as yes
if the document type is equal to blank than the status check list should automatically show up as No.
Code:
<!DOCTYPE html>
<html>
<head>
<title>Asset Management Checklist Mockup</title>
<script type='text/javascript'>
var Check List Status ='checklist';
var Client Agreement = 'client';
var Document type = 'doctype';
if ('doctype'='client')
{
document.getElementById('checklist').innerHTML = 'Yes';
}
</script>
<style>
h1 {color:blue;}
h1 {text-align:center;}
h2 {color:blue;
text-align:center;
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 15px;
}
</style>
</head>
<body>
<h1><em>Asset Management Department</em></h1>
<h2>Preview of automated report generation of <em>Documents Check List</em> on SharePoint.<h2>
<table style="width:100%">
<caption>Asset Management</caption>
<tr>
<th>Client Name</th>
<th>Portfolio Number</th>
<th>Portfolio Type</th>
<th id='doctype'>Document Type</th>
<th>Month</th>
<th>Year</th>
<th id='checklist'>Check List Status</th>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td id='client'>Clinet Agreement</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td id='email'>Email</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td id='passport'>Passport Copy</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td id='nation'>Nationality</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td od='poa'>Proof of Address</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td id='home'>Home Address</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td id='pa'>Postal Address</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td id='visa'>Visa Expiry Date</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
<tr>
<td>Smith</td>
<td>101</td>
<td>ABC</td>
<td id='family'>Family Book</td>
<td>February</td>
<td>2001</td>
<th></th>
</tr>
</table>
</body>
</html>
Javascript variable names cannot contain spaces. Things like var Check List Status ='checklist'; will never work.
The expression if ('doctype'='client') will never be true. You are comparing two literal strings (doctype and client) that are clearly different.
you seemingly try to select the column with the id checklist and then set innerHTML to "yes". Because of 2. that code is never reached, but if it would, it would simply set the column header to "yes".
What you need to do is:
iterate the table row by row (document.querySelectorAll('#assets tr') gives you the rows)
for each row, find the "Document Type" cell (I have given them all the class identifier because classes can be used more than once per HTML page, ids not) and read its text content
If the text content is empty, find the cell in the "Check List Status" column (I have given them all the class check) and set it to "No". If it is "Client Agreement", set it to "Yes".
Here's the code:
var clientAgreement = 'Client Agreement';
var docTable = document.getElementById('assets');
var rows = document.querySelectorAll('#assets tr');
// iterate rows
for (var i = 1; i < rows.length; i++) {
// get cell for class "check"
var checkCell = rows[i].getElementsByClassName("check")[0];
var docTypeCell = rows[i].getElementsByClassName("identifier")[0];
if (docTypeCell.textContent === clientAgreement) {
checkCell.innerHTML = "Yes";
} else if (docTypeCell.textContent.length === 0) {
checkCell.innerHTML = "No";
}
}
And here's a JSBin example that also contains the edited HTML.
This will work;
function init(){
var trs = document.getElementsByTagName('table')[0].children[1].children;
var i;
for (i = 0; i < trs.length; i += 1) {
if (trs[i].children[3].innerHTML.indexOf('Clinet Agreement') > -1) {
trs[i].children[6].innerHTML = 'yes';
}
}
}
if you call it onload (<body onload="init();">) but you should add id and class attributes to your HTML to make it referenceable from JavaScript and thus more robust. Also your table needs a tbody tag.

Categories

Resources