Join table rows - javascript

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

Related

Compare differences between two tables using Javascript [closed]

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.

How to get total sum in multiple tables

I have a multiple table and I want to get the total per table. Please see the demo in fiddle.
var total = 0;
$("table").each(function(i){
total += +$('.a', this).text() || 0;
console.log( 'total: '+total );
$("#subtotal", this).text( total );
//console.log( '-'+$('.a', this).text() );
});
https://jsfiddle.net/juandela/6r1g30dx/2/
You need to move var total=0 inside the table loop so it resets for each table
Then you need to loop over each cell to get individual cell's text.
The problem with getting all $('.a', this).text() is it concatenates all elements text into one string which is why you see numbers like "1357" as total in first table
Finally you can't repeat ID's in page so change subtotal to a class
$("table").each(function(i) {
var total = 0;
$('.a', this).each(function() {
total += +$(this).text() || 0;
});
$(".subtotal", this).text(total);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td class="a">1</td>
<td>2</td>
</tr>
<tr>
<td class="a">3</td>
<td>4</td>
</tr>
<tr>
<td class="a">5</td>
<td>6</td>
</tr>
<tr>
<td class="a">7</td>
<td>8</td>
</tr>
<tr>
<td class="subtotal"></td>
</tr>
</table>
<hr>
<table>
<tr>
<td class="a">1</td>
<td>2</td>
</tr>
<tr>
<td class="a">3</td>
<td>4</td>
</tr>
<tr>
<td class="a">5</td>
<td>6</td>
</tr>
<tr>
<td class="a">7</td>
<td>8</td>
</tr>
<tr>
<td class="a">9</td>
<td>10</td>
</tr>
<tr>
<td class="a">11</td>
<td>12</td>
</tr>
<tr>
<td class="subtotal"></td>
</tr>
</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>

Jquery copying the attribute of the the thead tr td to the tbody tr td

Can we copy the data from thead to tbody? I only wanted to get the data-date
<table>
<thead>
<tr>
<td data-date="2017-10-08"></td>
<td data-date="2017-10-09"></td>
<td data-date="2017-10-10"></td>
<td data-date="2017-10-11"></td>
<td data-date="2017-10-12"></td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
Can i copy the attribute of the thead tr td? to the tbody tr td? so it will also become
<table>
<thead>
<tr>
<td data-date="2017-10-08"></td>
<td data-date="2017-10-09"></td>
<td data-date="2017-10-10"></td>
<td data-date="2017-10-11"></td>
<td data-date="2017-10-12"></td>
</tr>
</thead>
<tbody>
<tr>
<td data-date="2017-10-08"></td>
<td data-date="2017-10-09"></td>
<td data-date="2017-10-10"></td>
<td data-date="2017-10-11"></td>
<td data-date="2017-10-12"></td>
</tr>
</tbody>
Note that I cant manully put the attribute coz this is coming from a plugin
You can set header td value in an array then set it using that arraywith jQuery each() function. check updated snippet below..
var xyz = [];
$('table thead td').each(function(){
xyz.push($(this).data('date'));
})
$('table tbody td').each(function(i,el){
$(this).data('date', xyz[i]).html(xyz[i]);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border='1' celpadding="2">
<thead>
<tr>
<td data-date="2017-10-08"></td>
<td data-date="2017-10-09"></td>
<td data-date="2017-10-10"></td>
<td data-date="2017-10-11"></td>
<td data-date="2017-10-12"></td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
Try this solution. Get both tds and iterate over one, use that index and copy the data-date into the tbody tds.
const theadTds = $('thead tr td');
const tbodyTds = $('tbody tr td');
theadTds.each((index, td) => {
const tbodyTd = tbodyTds.eq(index); // Get current tbody td
tbodyTd.data('date', $(td).data('date')); // Set the `data-date` to the `thead td` `data-date`
console.log(tbodyTd.data('date'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td data-date="2017-10-08"></td>
<td data-date="2017-10-09"></td>
<td data-date="2017-10-10"></td>
<td data-date="2017-10-11"></td>
<td data-date="2017-10-12"></td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
No need for any interim variables etc. Just iterate over the columns, this does ALL rows in body, if you just want first one you can do that also.
$('thead').find('tr').find('td').each(function(index){
$('tbody').find('tr').find('td').eq(index).data('date',$(this).data('date')):
});
Only first row in body
$('thead').find('tr').find('td').each(function(index){
$('tbody').find('tr').eq(0).find('td').eq(index).data('date',$(this).data('date')):
});
Alternate syntax if that is more clear to you
$('thead').find('tr').find('td').each(function(index,element){
$('tbody').find('tr').eq(0).find('td').eq(index).data('date',$(element).data('date')):
});

Find immediate children and go no further using jQuery

How do I get the immediate children when searching for a particular element? For example, I want to get the tr elements for the table t1.
<table id="t1" bgcolor="yellow">
<tbody>
<tr>
<td>This is Cell 1</td>
<td>This is Cell 2</td>
</tr>
<tr>
<td>This is Cell 3</td>
<td>
<table id="t2" bgcolor="red">
<tbody>
<tr>
<td>This is Cell 1</td>
<td>This is Cell 2</td>
</tr>
<tr>
<td>This is Cell 3</td>
<td>This is Cell 4</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
I tried this:
'Count = ' + $('#t1 tbody').children('tr').length;
However, I get a count of 4, I don't understand why?
Here is a full example:
Use:
'Count = ' + $('#t1 > tbody').children('tr').length;
// or: $("#t1 > tbody > tr").length
// or: $("#t1")[0].rows.length; // In this case, equal to previous code.
// Warning: This also includes the rows from
// the <thead> and <tfoot> sections.
Your current code shows 4, because you have got two <tbody> elements in the table #t1:
<table id="t1" bgcolor="yellow"> <-- #t1
<tbody> <--- tbody
<tr> ... </tr> <----- Child 1
<tr> ... <----- Child 2
<tbody> <--- tbody (unexpected?)
<tr> ... </tr> <----- Child 3
<tr> ... </tr> <----- Child 4
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
That is because with $('#t1 tbody') you get the tbody from both tables
You could use directly the Child Selector (“parent > child”) docs
$('#t1 > tbody > tr').length;
and here is you updated example: http://jsfiddle.net/SvygZ/1/

Categories

Resources