javascript - select nodes and all their child nodes inside tbody - javascript

I want to select all elements inside < tbody > and all their sub-elements so i can change a class using javascript.
For example, i want to change the class cl1 into cl2 in the following example
<table>
<thead>
....
</thead>
<tbody id="my-table">
<tr class="cl1 other-class">
<td>Some value</td>
<td class="cl1 other-class">Some value</td>
<td>Some value</td>
</tr>
<tr class="cl1 other-class">
<td class="cl1 other-class">Some value</td>
<td>Some value</td>
<td>
<a class="cl1 link" href="#">Some link</a>
</td>
</tr>
</tbody>
I want to use javascript for this, no jQuery
i managed to select all elements inside < tbody > like this :
document.getElementById("my-table").tBodies.item(0)
but i didn't know how to select each of their sub-elements or their sub-sub-elements.
for changing the class, i know i can use regular expressions to replace the class

Possible duplicate How to select all children of an element with javascript and change CSS property?
try (add an id to your tbody to make this work)
var descendants = document.getElementById('tbody').getElementsByTagName("*");
for(var i = 0; i < descendants.length; i++) {
descendants[i].classList.remove('cl1');
descendants[i].classList.add('cl2');
}

You said you managed to select <tbody> element, but you wanted to know how to select it's sub-elements or their sub-sub-elements. You do that with the children property which each element has. So this line gives you all children of <tbody> which are the <tr> (rows):
document.getElementById("my-table").tBodies.item(0).children;
Then if you get the children of each row, you get the cells. Example:
var tbody = document.getElementById("my-table").tBodies.item(0);
var rows = tbody.children;
var row1cells = rows[0].children;
var row2cells = rows[1].children;

Related

innerHTML to Attribute value Plain JavaScript

Here is my html
<table><thead>
<tr>
<th>Green</th>
<th>Orange</th>
</tr>
</thead>
<tbody>
<tr>
<td>First Stage A</td>
<td>First Stage B</td>
</tr>
<tr>
<td>Second Stage A</td>
<td>Second Stage B</td>
</tr>
</tbody></table>
Expected output
<table><thead>
<tr>
<th>Green</th>
<th>Orange</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Green">First Stage A</td>
<td data-label="Orange">First Stage B</td>
</tr>
<tr>
<td data-label="Green">Second Stage A</td>
<td data-label="Orange">Second Stage B</td>
</tr>
</tbody></table>
Here is the script
var _th = document.querySelectorAll("table th")[0];
var _th_value = _th.innerHTML;
var _td = document.querySelectorAll("table td")[0];
_td.setAttribute("basevalue", _th_value);
How could this to be done through plain JavaScript loop. I tried to figure this out for several hours by my existing JavaScript knowledge. But I couldn’t. Could someone please take a look and give me a hint? Advance thanks.
Step 1: You can first create a mapped array that contains the color values you can collect from the table thead th selector. You need to first convert a HTMLCollection to an array using ES6 Array.prototype.from, and then perform the mapping using Array.prototype.map:
const table = document.querySelector('table');
const colors = Array.from(table.querySelectorAll('thead th')).map(th => th.innerText);
p/s: The reason why innerText is used is so that we don't include any HTML tags, even though in your example innerHTML works just as fine. This is just a personal preference.
Step 2: Then, you simply iterate through all the table tbody tr elements. In each iteration you then iterate through all the td elements you can find, and with their index, use dataset to assign the corresponding color by index:
table.querySelectorAll('tbody tr').forEach(tr => {
tr.querySelectorAll('td').forEach((td, i) => {
td.dataset.color = colors[i];
});
});
See proof-of-concept below, where the cells are colored based on the data-color attribute for ease of visualisation (you can also inspect the DOM to see the correct HTML5 data- attributes are added):
const table = document.querySelector('table');
// Collect colors into an array
const colors = Array.from(table.querySelectorAll('thead th')).map(th => th.innerText);
// Iterate through all `<tr>` elements in `<tbody>
table.querySelectorAll('tbody tr').forEach(tr => {
// Iterate through all `<td>` in a particular row
tr.querySelectorAll('td').forEach((td, i) => {
// Assign color to HTML5 data- attribute
td.dataset.color = colors[i];
});
});
tbody td[data-color="Green"] {
background-color: green;
}
tbody td[data-color="Orange"] {
background-color: orange;
}
<table>
<thead>
<tr>
<th>Green</th>
<th>Orange</th>
</tr>
</thead>
<tbody>
<tr>
<td>First Stage A</td>
<td>First Stage B</td>
</tr>
<tr>
<td>Second Stage A</td>
<td>Second Stage B</td>
</tr>
</tbody>
</table>
var tables = document.getElementsByTagName('table');
for (let table of tables) {
var thead = table.children[0];
var tbody = table.children[1];
var index = 0;
for (let th of thead.children[0].cells) {
var color = th.innerHTML;
for (let tr of tbody.children) {
tr.children[index].setAttribute('data-label', color);
}
index++;
}
}
I had to handle the index outside the for loop because the children elements aren't simple arrays but HTMLCollections, and have different way to iterate over them.
edit: Added loop to iterate over all the tables in the page

How to modify a HTML <td> (without any unique properties) element using Javascript

I'm trying to modify a element using JS however this element does not have any unique properties like ID. Also the table in which this element resides does not have a unique class. Also, the HTML page has multiple tables and td elements.
For example:
Existing HTML :
<table border="1">
<tbody>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
<tr>
<td>12334567</td>
<td>BirthName</td>
</tr>
</tbody>
</table>
I'm trying to modify the cell which contains the value "BirthName" to "BirthName (Sidharth)"
Something Like this:
<table border="1">
<tbody>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
<tr>
<td>12334567</td>
<td>BirthName (Sidharth)</td>
</tr>
</tbody>
</table>
You can find all having BirthName by using bellow colde
const allTds = document.querySelectorAll('td')
// Find the td element that contains the text "BirthName"
const birthDateTd = Array.from(allTds).filter(td=>td.textContent==='BirthName')
After that you can target that <td> as you want.
You can do checking the text for all td and change where matches birthname
let element = document.querySelectorAll('td');
for(let i = 0; i<element.length; i++){
if(element[i].innerText == 'BirthName'){
element[i].innerText += '(Sidharth)';
}
}
If the text is unique then you can use Xpath as shown below and change it.
var td = document.evaluate("//td[contains(text(), 'BirthName')]", document, null, XPathResult.ANY_TYPE, null );
var thisTd = td.iterateNext();
thisTd.innerHTML = "BirthName (Sidharth)";
<table border="1">
<tbody>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
<tr>
<td>12334567</td>
<td>BirthName</td>
</tr>
</tbody>
</table>

How to initialize dynamic input with css selector using query selector?

How to initilize dynamic number with in css selector?
Ex-pageUrl.QuerySelector(.attachment-type-table .qa-type-id-label-for-25)
The above line given only one Result Photograph.
I need to get all names with in span tag
( qa-type-id-label-for-26,qa-type-id-label-for-25, qa-type-id-label-for-27 etc)
Use native function yourSpan.attr('class'), and then you can use .Split(" ")
for get individual of class.
Is this what you are trying to do?
I have implemented querySelectAll() matching partially to a class name.
<table id="attachmentTypeTable" class="appconfig-data-table attachment-type-table">
<tbody>
<tr>
<tr id="28RemoveAType">
<tr id="27RemoveAType">
<tr id="26RemoveAType">
<td><span class="qa-type-id-label-for-26">Transfer cover</span></td>
<td>
</tr>
<tr id="25RemoveAType">
<td><span class="qa-type-id-label-for-25">Photograph</span></td>
<td>
</tr>
</tbody>
</table>
<script type="text/javascript">
var x = document.querySelectorAll('[class^="qa-type-id-label-for-"]');
for(var i=0;i< x.length;i++){
document.write('result'+i+':'+x[i].innerHTML+'<br/>');
}
</script>

Javascript change style of td element using tr id

I have one table:
<table>
<tr id="436">
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
Now I need using Javascript to get tr element using id and then in that tr add CSS style of changing text color.
I have try getelementbyid("436") but I don't know how to do next.
So I need to get this:
<table>
<tr id="436">
<td style="color: red">1</td>
<td style="color: red">2</td>
<td style="color: red">3</td>
</tr>
</table>
How about this, if you really want to change the color of the td elements:
var tr = document.getElementById("436");
var tds = tr.getElementsByTagName("td");
for(var i = 0; i < tds.length; i++) {
tds[i].style.color="red";
}
http://jsfiddle.net/UEbCL/
it should be something like this:
document.getElementById("436").style.color="red"

How to use Javascript to make several rows in an HTML table invisible

I have an HTML table and there are several rows in that table that I want to toggle to either be visible or invisible as a group. Since I can't simply put a <div> around them, what would be a good way to 'group' them together.
try making your html in such a way you can hide/visible and apply your css/js.
<table>
<tr class="visible"><td></td></tr>
<tr class="visible"><td></td></tr>
<tr class="hidden"><td></td></tr>
<tr class="visible"><td></td></tr>
<tr class="visible"><td></td></tr>
<tr class="hidden"><td></td></tr>
<tr class="visible"><td></td></tr>
</table>
You can group them in separate <tbody> elements (since you can't use <div> elements, as you stated).
<table id="mytable">
<tbody>
<!-- some rows to group -->
</tbody>
<tbody>
<!-- some rows to group -->
</tbody>
<tbody>
<!-- some rows to group -->
</tbody>
</table>
Then select the tbody you want.
var table = document.getElementById("mytable");
table.tBodies[1].style.display="none";
You could use the tbody tag. You can set the id attribute on it.
tbody id="customer1"
<table>
<thead>
<tr><th>Customer</th><th>Order</th><th>Month</th></tr>
</thead>
<tbody id="customer1">
<tr><td>Customer 1</td><td>#1</td><td>January</td></tr>
<tr><td>Customer 1</td><td>#2</td><td>April</td></tr>
<tr><td>Customer 1</td><td>#3</td><td>March</td></tr>
</tbody>
<tbody id="customer2">
<tr><td>Customer 2</td><td>#1</td><td>January</td></tr>
<tr><td>Customer 2</td><td>#2</td><td>April</td></tr>
<tr><td>Customer 2</td><td>#3</td><td>March</td></tr>
</tbody>
<tbody id="customer3">
<tr><td>Customer 3</td><td>#1</td><td>January</td></tr>
<tr><td>Customer 3</td><td>#2</td><td>April</td></tr>
<tr><td>Customer 3</td><td>#3</td><td>March</td></tr>
</tbody>
</table>
Then with JQuery you can easily hide/show.
I would recommend a jQuery solution to you. Provide all of your <tr> tags a common class and a unique id (for individual selection). Then you can use jQuery to grab them.
$('tr .commonClass').css("display", "none");
You could also just swap classes with the individual ids
$('#someTR').removeClass("visibleClass");
$('#someTR').addClass("invisibleClass");
Note: For the record I prefer #Yograj Gupta's method, but he beat me to the punch posting.
Pure JavaScript jsfiddle
<table>
<tr class="show"><td></td></tr>
<tr class="show"><td></td></tr>
<tr class="hide"><td></td></tr>
<tr class="show"><td></td></tr>
<tr class="show"><td></td></tr>
<tr class="hide"><td></td></tr>
<tr class="show"><td></td></tr>
</table>
JS:
var trGroup = document.getElementsByClassName("hide");
for(var k=0; k < trGroup.length; k++){
trGroup[k].style.display = "none";
}
Place a common class on the rows which you want to group. than work on that like
or you have some set of rules for visible or hidden, rows group you can simple use css + javascript like
HTML
<table id="myGroupTab">
<tr class="group1"><td> </td></tr>
<tr class="group1"><td> </td></tr>
<tr class="group2"><td> </td></tr>
<tr class="group2"><td> </td></tr>
<tr class="group1"><td> </td></tr>
</table>
you can write some css rules like
CSS
#myGroupTab.showGrp1 .group1{ display:block;}
#myGroupTab.showGrp1 .group2{ display:none;}
#myGroupTab.showGrp2 .group1{ display:none;}
#myGroupTab.showGrp2 .group2{ display:block;}
You can use Javascript like
JS
document.getElementById('myGroupTab').className = "showGrp1"; //To Show Only tr.group1
document.getElementById('myGroupTab').className = "showGrp2"; //To Show Only tr.group2
Its even simple to make display none or block applying a class on parent, instead of looping every tr...
Or by jQuery you can achieve this, make them visible or hidden using jQuery.
$("tr.group1").hide() or $("tr.group2").show()
#user1689607 solution using multiple tbody(s) in table is also a good solution.

Categories