jQuery each loop in table row [duplicate] - javascript

This question already has answers here:
How to iterate a table rows with JQuery and access some cell values?
(3 answers)
Closed 3 years ago.
I am having something like:
<table id="tblOne">
<tbody>
<tr>
<td>
<table id="tblTwo">
<tbody>
<tr>
<td>
Items
</td>
</tr>
<tr>
<td>
Prod
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>
Item 1
</td>
</tr>
<tr>
<td>
Item 2
</td>
</tr>
</tbody>
</table>
I have written jQuery to loop through each tr like:
$('#tblOne tr').each(function() {...code...});
But problem is that it loops through the "tr" of "tblTwo" also which I don't want.
Can anyone please suggest something to solve this?

In jQuery just use:
$('#tblOne > tbody > tr').each(function() {...code...});
Using the children selector (>) you will walk over all the children (and not all descendents), example with three rows:
$('table > tbody > tr').each(function(index, tr) {
console.log(index);
console.log(tr);
});
Result:
0
<tr>
1
<tr>
2
<tr>
In VanillaJS you can use document.querySelectorAll() and walk over the rows using forEach()
[].forEach.call(document.querySelectorAll('#tblOne > tbody > tr'), function(index, tr) {
/* console.log(index); */
/* console.log(tr); */
});

Just a recommendation:
I'd recommend using the DOM table implementation, it's very straight forward and easy to use, you really don't need jQuery for this task.
var table = document.getElementById('tblOne');
var rowLength = table.rows.length;
for(var i=0; i<rowLength; i+=1){
var row = table.rows[i];
//your code goes here, looping over every row.
//cells are accessed as easy
var cellLength = row.cells.length;
for(var y=0; y<cellLength; y+=1){
var cell = row.cells[y];
//do something with every cell here
}
}

Use immediate children selector >:
$('#tblOne > tbody > tr')
Description: Selects all direct child elements specified by "child" of
elements specified by "parent".

Related

jQuery highlight text of individual column in table rather than across whole table

I have the following jquery that allows me to highlight all td across all of my html table that exceeds a threshold, in this case 13:
var table = document.getElementById('my_table');
var tbody = table.getElementsByTagName('tbody')[0];
var cells = tbody.getElementsByTagName('td');
var specificheader = tbody.getElementsByTagName('th');
for (var i=0, len=cells.length; i<len; i++){
if (parseInt(cells[i].innerHTML,10) > 13){
cells[i].className = 'red';
}
else if (parseInt(cells[i].innerHTML,10) < -0.1){
cells[i].className = 'green';}
}
With the corresponding HTML:
<table id="my_table">
<thead>
<tr style="text-align: right;">
<th></th>
<th>Vibration 1</th>
<th>Vibration 2</th>
</tr>
</thead>
<tbody>
<tr>
<th>2018-05-14</th>
<td>0.02</td>
<td>0.09</td>
<td>0.11</td>
<td class="red">13.26</td>
<td>1.72</td>
<td class="red">14.98</td>
</tr>
<tr>
<th>2018-05-15</th>
<td>0.02</td>
<td>0.05</td>
<td>0.07</td>
<td class="red">13.27</td>
<td>1.54</td>
<td class="red">14.82</td>
</tr>
</tbody>
</table>
How would I restrict this to highlight only a on specific th, say Vibration 2?
Thank you in advance.
This might sort of a simple way. You can just change your javascript to select the nth-child() of the tr's:
var cells = tbody.querySelectorAll('td:nth-child(7)');
You could probably do something with that to make it dynamic so you can do what you want to programmatically. I think it actually counts the th cells as a child.
Even though a table presents a 2d table, html nodes hierarchy is only one dimensional, so you can't just highlight a column
A possible solution may be premarking all td tags with a class of column number, say something like
<tr>
<td class="col-1">123</td>
<td class="col-2">4.56</td>
...
</tr>
<tr>
<td class="col-1">1234</td>
<td class="col-2">4.567</td>
...
</tr>
Then adding a condition to the jQuery accordingly
A basic implementation:
for (var i=0, len=cells.length; i<len; i++){ if (parseInt(cells[i].innerHTML,10) > 13){
var colcol = cells[i].getAttribute("class");
var tds = document.getElementsByClassName(colcol);
for (var j = 0;j < tds.length ;j++) {
(tds[j]).addClass('red');
}
Notice that if the td has more than one class, we'll need to get just the column class
Which can be done by using split on the colcol var then taking the 1st class
or using regexp etc.

Javascript get access to inner table only

I have a system that generates a list of nested tables. I can't either modify it nor add any id/tags/classes to any parent tables. I also can add neither jQuery nor any other JS library.
I wish to add highlights on mouseover on a row of the inner table (usually I have 2-3 nested tables).
Could someone help me to adjust that sample to my case? The problem with the code that it grabs <td/> tags of parent tables.
var tds = document.getElementsByTagName( "td" );
for( var i = 0; i < tds.length; i++ ) {
tds[i].addEventListener("mouseover", function(){
var children = this.parentNode.getElementsByTagName("td");
for( var j = 0; j < children.length; j++ )
children[j].style.backgroundColor = "green";
});
tds[i].addEventListener("mouseout", function(){
var children = this.parentNode.getElementsByTagName("td");
for( var j = 0; j < children.length; j++ )
children[j].style.backgroundColor = "initial";
});
}
<table>
<tr>
<td>
<table>
<tr>
<td>cell1,1</td>
<td>cell1,2</td>
<td>cell1,3</td>
</tr>
<tr>
<td>cell2,1</td>
<td>cell2,2</td>
<td>cell2,3</td>
</tr>
</table>
</td>
<td> test </td>
</tr>
</table>
Unfortunately, I'm not good enough in JS yet.
I'd ditch the JavaScript and use a simple CSS selector
table table tr:hover {
background: green;
}
<table>
<tr>
<td>
<table>
<tr>
<td>cell1,1</td>
<td>cell1,2</td>
<td>cell1,3</td>
</tr>
<tr>
<td>cell2,1</td>
<td>cell2,2</td>
<td>cell2,3</td>
</tr>
</table>
</td>
<td> test </td>
</tr>
</table>
The answer mentioned above works if the number of nested tables are always 2. According to the requirements, you mentioned that you usually have 2-3 nested tables so it wouldn't work if there are 3 nested tables or more. You would have to change your CSS selectors.
With the solution below, it makes it more dynamic to always get the row of the inner most table as originally requested.
var tables = document.getElementsByTagName("table");
tables[tables.length - 1].classList.add("highlighter");
.highlighter tr:hover {
background: green;
}
<table>
<tr>
<td>
<table>
<tr>
<td>cell1,1</td>
<td>cell1,2</td>
<td>cell1,3</td>
</tr>
<tr>
<td>cell2,1</td>
<td>cell2,2</td>
<td>cell2,3</td>
</tr>
</table>
</td>
<td> test </td>
</tr>
</table>

get the content of one column of each row in the table and then loop on each content

I have a table structure like this (refer below)
<table>
<thead>
<tr><th>id</th><th>name</th><th>address</th></tr>
</thead>
<tbody>
<tr rowid="1">
<td class="columnid">1</td><td class="columnname">name 1</td><td class="columnaddress">address 1</td>
</tr>
<tr rowid="2">
<td class="columnid">2</td><td class="columnname">name 2</td><td class="columnaddress">address 2</td>
</tr>
<tr rowid="3">
<td class="columnid">3</td><td class="columnname">name 3</td><td class="columnaddress">address 3</td>
</tr>
</tbody>
</table>
Now, I want to get the content from each table row that has attr('columnid') and loop each of it. So the code structure would look like this (refer below)
//We have 3 row, get all present rowid (1,2,3)
//count all the row that has rowid attribute
var rowcount = attr('rowid').length();
var i;
for (i = 0; i < rowcount; i++) //I dont know how to make it but assume in this for statement, I have stored the content from each rowid attribute {
//alert each rowid here
}
how to make it? any help, suggestions, recommendations, ideas, clues would be greatly appreciated. Thank you.
You can use tr[rowid] which will find all tr elements with rowid attribute, then use .has() to filter out trs which do not have td with class columnid like
$('tr[rowid]').has('td.columnid').each(function(){
alert($(this).attr('rowid'))
});
Demo: Fiddle
This code will scan all the td's with class columnidand alert the rowid of the row containing it. I hope this is what you want you code to do.
$("tr td.columnid").each(function(){
alert($(this).parent().attr("rowid"));
});
Fiddle

jQuery: skipping first table row

This is the HTML:
<table id="tblTestAttributes">
<thead>
<tr> <th>Head 1</th> <th>Head 2</th> </tr>
</thead>
<tbody>
<tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
<tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
<tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
</tbody>
</table>
This is the javascript to get the values of each row:
var frequencies = [];
if ($('#tblTestAttributes').length) {
$('#tblTestAttributes tr').each(function () {
var t = $(this).find('td[id^="txtDesc"]').text() + ";" + $(this).find('[id^="ddlFreq"] option:selected').val();
alert(t);
frequencies.push(t);
});
}
I want to avoid the first row, which contains th elements which are just display headers and don't contain any data.
So I changed the selector to this:
#tblTestAttributes tr:not(:first-child)
This is skipping the second tr as well. What is happening here?
Simple you can use below code
$('#tblTestAttributes tr:not(:has(th))').each(function () {
In terms of performance, using .find() will be better than resolving the selector with Sizzle.
$('#tblTestAttributes').find('tbody').find('tr').each(function () { ... });
Here's the jsPerf to show it.
use
#tblTestAttributes tr:gt(0)
or
#tblTestAttributes tbody tr
I would recommend the 2nd, because it may take advantage of querySelectorAll and should be the fastes solution.
your approach didn't work as expected, because the 2nd tr is also a first-child(of tbody)
Use tr + tr selector, which gets all tr that appear after another tr, so the first one is skipped.
Also no need to check if table exists, as in that case $.each wouldn't even get executed.
var frequencies = [];
$('#tblTestAttributes tr + tr').each(function () {
var t = $(this).find('td[id^="txtDesc"]').text() + ";" + $(this).find('[id^="ddlFreq"] option:selected').val();
alert(t);
frequencies.push(t);
});
After your edit:
Simply select only all tr inside tbody:
$('#tblTestAttributes tbody tr').each(function(){
...
}
It happens because the second row is, in fact, the first child of the tbody just like the first row is the first child of the thead.
To only take the elements you need, I'd suggest something nearer from your need :
#tblTestAttributes tr:has(td)
Don't forget to get rid of those duplicate txtDesc id, this is illegal in HTML, use a class instead.

How to get the content of a table rows and columns

Can anyone give me an idea on how I will count the table column and table row and get the id, attribute and the content of a each cell (the cell is contenteditable). What tools do I have to use?
e.g.
<table>
<tbody>
<tr>
<td id='1A' rowspan=2>Rowspan 2</td>
<td id='1B'>22222</td>
<td id='1C'>33333</td>
</tr>
<tr>
<td id='2B' colspan='2'> Colspan2</td>
</tr>
<tr>
<td id='3A' style='color:red'>Whaterver</td>
<td id='3B' style='font-weight:bold'>Askyourmother</td>
<td id='3C'>sigh</td>
</tr>
</tbody>
</table>
I'm using Jquery (Javascript).
You can make use of jQuery to get it and then do whatever you want with it.
In this case I just print it in the console.
//for each TR...
$('table tr').each(function(){
//for each TD....
$(this).find('td').each(function(){
console.log($(this).text()); //do whatever you want with the text
console.log($(this).attr('id'));
console.log($(this).attr('any_other_attribute'));
});
});
you can use jQuery.
To get all tr use it as below.
var count = $('table tr').length;
above will out put count of all the tr inside table.
To get the ID attribut of DOM use .attr()
var tableID = $('table').attr('id');
above will out-put the ID attribute of the DOM.
To get the text inside of DOM use .text() or .html()
var text = $('table tr td').text();
var html = $('table tr td').html();
above will out-put the HTML or TEXT inside of the selected DOM.
use length to count tr and each to get ids and contents.
var table=$('table tr');
var trCount= table.length; //count tr
alert('trcount='+trCount);
$('table tr td').each(function(){
var tdID=$(this).attr('id'); //get id
var tdcontent=$(this).text(); //get content
alert('id='+tdID);
alert('content='+tdcontent);
}) ;
fiddle here

Categories

Resources