loop over table to set the background css - javascript

My HTML table has some classes and table tag is used
Want to retain the classes as is, but all my table and tr , th or td are using td bgcolor which is an old technique.
I want to loop over the table and find if that bgcolor is defined, use the same color and convert it to a css based background color so i can print it in IE
function setBackground() {
var table = document.getElementById("table1");
//i found this in a previous stack overflow answer and tried it
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
//this is for debugging purposes... I can't even get this to work
alert(table.rows[i].cells[j]);
table.rows[i].cells[j].style.background = "orange"; //just an example
}
}
}
because IE is not able to print the background lines and colors for some reason using the webkit property

I cleaned up the for loops a little. You can read the attribute with getAttribute and set the style.
var table = document.getElementById("table1");
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i]
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j]
var bgc = cell.getAttribute('bgcolor')
if (bgc) {
cell.style.background = bgc
}
}
}
td {
width: 30px; height: 30px;
}
<table id="table1">
<tr>
<td bgcolor="red"></td>
<td></td>
<td bgcolor="blue"></td>
</tr>
<tr>
<td></td>
<td bgcolor="green"></td>
<td></td>
</tr>
<tr>
<td bgcolor="yellow"></td>
<td></td>
<td></td>
</tr>
<tr>
<td bgcolor="silver"></td>
<td></td>
<td></td>
</tr>
</table>
You can just do it with one loop with getElementsByTagName
var tds = document.getElementById("table1").getElementsByTagName("td");
for (var i = 0; i < tds.length; i++) {
var cell = tds[i]
var bgc = cell.getAttribute('bgcolor')
if (bgc) {
cell.style.background = bgc
}
}
td {
width: 30px; height: 30px;
}
<table id="table1">
<tr>
<td bgcolor="red"></td>
<td></td>
<td bgcolor="blue"></td>
</tr>
<tr>
<td></td>
<td bgcolor="green"></td>
<td></td>
</tr>
<tr>
<td bgcolor="yellow"></td>
<td></td>
<td></td>
</tr>
<tr>
<td bgcolor="silver"></td>
<td></td>
<td></td>
</tr>
</table>

Get the color if found and then do with it whatever needed...
function setBackgroundColor(colorValue) {
const table = document.getElementById("table1");
const rows = table.children[0].rows
for (let i = 0; i < rows.length; i++) {
const tds = rows[i].children;
for (let j = 0; j < tds.length; j++) {
if (tds[j].bgColor === colorValue) {
console.log('Color found, do action')
}
}
}
}
setBackgroundColor('red')
<table id="table1">
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td bgcolor="red">January</td>
<td bgcolor="green">$100</td>
</tr>
</table>

You can do this:
var cells = $("#targetTable td");
for(i in cells){
color = $(cells[i]).attr('bgcolor');
console.log(color);
$(cells[i]).css({background: color});
}

as Taplar mentioned in the comment :
Use document.querySelectorAll('td[bgcolor]') to get the td that have bgcolor, loop through them and set the background to that color :
document.querySelectorAll('td[bgcolor]').forEach(e => {
const bgColor = e.getAttribute('bgcolor');
e.removeAttribute('bgcolor'); // optional, if you want to remove the attribute
e.style.background = bgColor;
})
<table id="table1">
<thead>
<th>A</th>
<th>B</th>
<th>C</th>
</thead>
<tbody>
<tr>
<td bgcolor="red">1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td bgcolor="green">5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td bgcolor="blue">9</td>
</tr>
</tbody>
</table>

Related

Using jQuery or javascript, I'd like to get that how many element 500 in each column (1-4) of an html table is ? How should I do it?

Using jquery or javascript, I'd like to get that how many element 500 in each column (1-4) of an html table is ? How should I do it ?
<html>
<table>
<thead>
<tr>
<th>Column-1</th>
<th>Column-2</th>
<th>Column-3</th>
<th>Column-4</th>
</tr>
</thead>
<tbody>
<tr>
<td>500</td>
<td>200</td>
<td>500</td>
<td>200</td>
</tr>
<tr>
<tr>
<td>501</td>
<td>500</td>
<td>500</td>
<td>200</td>
</tr>
</tbody>
</table>
</html>
The table is look like this format:
Column-1 Column-2 Column-3 Column-4
500 200 500 200
501 500 500 500
... ... .... ...
I would like to get : column-1: 1, column-2:1, column-3:2 column-4: 1
automatic display the numbers of "500" of each column .
Solution
filter the 's in row out
Store the column when the text of a td is 500
Count how often the column occurs
let trArr = $("table tr")
let res = [];
for (let i = 0; i < trArr.length; i++) {
let childs = trArr[i].children;
for (let j = 0; j < childs.length; j++) {
if(childs[j].tagName !== "TH"){
if (childs[j].textContent === "500" ) {
res.push({
"column": j+1
});
}
}
}
}
let result = new Set();
for (let i = 0; i < res.length; i++) {
let counter = 0;
for (let j = 0; j < res.length; j++) {
if (res[i].column === res[j].column) {
counter++;
}
}
result.add(`Column ${[res[i].column]}: ${counter} x 500`);
}
let resString = "";
for(let i of result){
resString += i + "\n";
}
document.getElementById("BLA").innerHTML = resString;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<table>
<thead>
<tr>
<th>Column-1</th>
<th>Column-2</th>
<th>Column-3</th>
<th>Column-4</th>
</tr>
</thead>
<tbody>
<tr>
<td>500</td>
<td>200</td>
<td>500</td>
<td>200</td>
</tr>
<tr>
<tr>
<td>501</td>
<td>500</td>
<td>500</td>
<td>200</td>
</tr>
</tbody>
</table>
<p id="BLA"></p>
</html>

Collapsing tables within tables

I am attempting to collapse a table when the onclick event occurs. I iterate through the rows of a table and either set their visibility to collapse or to visible. If there is a table in one of the table data elements, setting the visibility of the row to visible doesn't affect the visibility of the table within. I tried to make the center loop recursive and call it on any inner table nodes, but that doesn't fix it. How can I fix this issue?
main.html
<html>
<head>
<title>Hello World</title>
</head>
<body>
<table class="collapsible" cellpadding="2" cellspacing="0" border="2" bgcolor="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 1</td>
<td style="word-wrap: break-word;">datum 2</td>
</tr>
<tr>
<td>
<table CELLPADDING="2" CELLSPACING="0" BORDER="2" BGCOLOR="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 3</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 4</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 5</td>
<td style="word-wrap: break-word;">datum 6</td>
</tr>
</table>
<script>
var tbls = document.getElementsByClassName("collapsible");
var tblCnt = tbls.length;
init();
function init() {
var i;
for (i=0; i<tblCnt; i++) {
tbls[i].addEventListener("click", collapse);
}
}
function collapse() {
collapseAlg(this,1)
}
// start=0 -> collapse all rows, start=1 -> collapse all except the first row (assume no th)
function collapseAlg(tbl, start) {
console.log("called", tbl);
var rows = tbl.getElementsByTagName("tr");
var i;
var j;
var datum;
for (i = start; i < rows.length; i++) {
if (window.getComputedStyle(rows[i]).visibility === "collapse") {
rows[i].style.visibility = "visible";
tblss = rows[i].getElementsByTagName("table");
for (j=0; j < tblss.length; j++) {
collapseAlg(tblss[j],0);
}
} else {
rows[i].style.visibility = "collapse";
}
}
}
</script>
</body>
</html>
Great question. The issue is with this code:
var rows = tbl.getElementsByTagName("tr");
That retrieves all the table's TR elements, including those within sub-tables.
You want only the .collapsible table's rows. This is a little tricky, because tables automatically add TBODY elements if you haven't done so explicitly.
This gives the rows you need:
var rows = tbl.querySelectorAll(":scope > tbody > tr");
And you can get rid of this code:
tblss = rows[i].getElementsByTagName("table");
for (j=0; j < tblss.length; j++) {
collapseAlg(tblss[j],0);
}
Snippet:
var tbls = document.getElementsByClassName("collapsible");
var tblCnt = tbls.length;
init();
function init() {
var i;
for (i = 0; i < tblCnt; i++) {
tbls[i].addEventListener("click", collapse);
}
}
function collapse() {
collapseAlg(this, 1)
}
// start=0 -> collapse all rows, start=1 -> collapse all except the first row (assume no th)
function collapseAlg(tbl, start) {
console.log("called", tbl);
var rows = tbl.querySelectorAll(":scope > tbody > tr");
var i;
var j;
var datum;
for (i = start; i < rows.length; i++) {
if (window.getComputedStyle(rows[i]).visibility === "collapse") {
rows[i].style.visibility = "visible";
} else {
rows[i].style.visibility = "collapse";
}
}
}
<table class="collapsible" cellpadding="2" cellspacing="0" border="2" bgcolor="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 1</td>
<td style="word-wrap: break-word;">datum 2</td>
</tr>
<tr>
<td>
<table CELLPADDING="2" CELLSPACING="0" BORDER="2" BGCOLOR="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 3</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 4</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 5</td>
<td style="word-wrap: break-word;">datum 6</td>
</tr>
</table>

Create a row using group off arrays

Lets say we have an Array that looks like this
(example)
Array1 = [Data_A,Data_B];
Array2 = [Data_1,Data_2,Data_3];
and I have a table that looks like this
How can I achieve this?
For now I can retreive the data in row order using for loop and this is my code
for (i = 0; i < Array1 .length; i++) {
for (x in Array1 [i]) {
console.log(data from array);
}
}
My target here is for every array is I need to make it as a row for every col. for example Array1 is fol Col1 and also note that my arrays are fixed for each col. col3 and 4 are for ex. only
Because the data in table columns don't usually change unlike they do in rows, I highly discourage managing table data by columns. It is best to do it by rows.
What I mean is to have Row1 = [Data_A, Data_1]; and Row2 = [Data_B, Data_2]; and so on, rather than how you had it set up.
function CreateRow(data) {
var tr = "<tr>"
for (var i = 0; i < data.length; i++) {
tr += "<td>" + data[i] + "</td>";
}
tr += "</tr>"
$('#table').append(tr);
}
function EditRow(data, rowIdx) {
var tr = $('#table').children().eq(0);
for (var i = 0; i < data.length; i++) {
tr.children().eq(i).text(data[i]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
<th>Col4</th>
</tr>
</thead>
<tbody id="table">
<tr>
<td>Data 0</td>
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
</tr>
</tbody>
</table>
<button type="button" onclick="CreateRow(['A','B','C','D'])">Create Row</button>
<button type="button" onclick="EditRow(['EditedData1','EditedData2', 'EditedData3', 'EditedData4'], 0)">Edit First Row</button>
(Pure Javascript snippet for those who are interested)
function CreateRow(data) {
var table = document.getElementById("table");
var tr = document.createElement("tr");
for (var i = 0; i < data.length; i++) {
var td = document.createElement("td");
td.appendChild(document.createTextNode(data[i]));
tr.appendChild(td);
}
table.appendChild(tr);
}
function EditRow(data, rowIdx) {
var tr = document.getElementById("table").getElementsByTagName("tr")[rowIdx];
for (var i = 0; i < data.length; i++) {
tr.getElementsByTagName("td")[i].innerHTML = data[i];
}
}
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
<th>Col4</th>
</tr>
</thead>
<tbody id="table">
<tr>
<td>Data 0</td>
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
</tr>
</tbody>
</table>
<button type="button" onclick="CreateRow(['A','B','C','D'])">Create Row</button>
<button type="button" onclick="EditRow(['EditedData1','EditedData2', 'EditedData3', 'EditedData4'], 0)">Edit First Row</button>

Loop through elements in a HTML table

I am learning Javascript, in a school assignment we have to by using a loop count how many games was made in 2014.
It does not return anything in the console, where have I gone wrong?
var allGames = document.getElementsByTagName('td');
var array = Array.prototype.slice.call(allGames, 0)
var games14 = 0;
for (var i = 0; i < array.length; ++i) {
if (array[i] == 2014) {
games14++;
console.log(games14)
}
}
<table id="games">
<thead>
<tr>
<th>Titel</th>
<th>Genre</th>
<th>Årstal</th>
</tr>
</thead>
<tbody id="games_tbody">
<tr class="horror">
<td class="title">Outlast</td>
<td>Horror</td>
<td>2013</td>
</tr>
<tr class="rpg">
<td class="title">Dragon Age: Inquisition</td>
<td>Role-playing Game</td>
<td>2014</td>
</tr>
<tr class="rpg">
<td class="title">Skyrim</td>
<td>Role-playing Game</td>
<td>2011</td>
</tr>
<tr class="horror">
<td class="title">Amnesia: The Dark Descent</td>
<td>Horror</td>
<td>2010</td>
</tr>
<tr class="simulator">
<td class="title">Scania Truck Driving Simulator</td>
<td>Simulator</td>
<td>2012</td>
</tr>
<tr class="horror">
<td class="title">Five Nights at Freddy’s</td>
<td>Horror</td>
<td>2014</td>
</tr>
<tr class="simulator">
<td class="title">Sims 4</td>
<td>Simulator</td>
<td>2014</td>
</tr>
<tr class="rts" id="last">
<td class="title">Warcraft III: Reign of Chaos</td>
<td>Real-time Strategy</td>
<td>2002</td>
</tr>
</tbody>
</table>
You need to check for its text:
var allGames = document.getElementsByTagName('td');
...
if (array[i].innerHTML == '2014') {
OR,
if(array[i].innerText == '2014' || array[i].textContent == '2014'){
No need to do Loop through elements in a HTML table.. You can simply use regular expressions to count all occurrences within the games_tbody:
var games14 = document
.getElementById('games_tbody')
.innerText
.match(/2014/g)
.length;
console.log('Games made in 2014:', games14);
<table id="games">
<thead>
<tr><th>Titel</th><th>Genre</th><th>Årstal</th></tr>
</thead>
<tbody id="games_tbody">
<tr class="horror"><td class="title">Outlast</td><td>Horror</td><td>2013</td></tr>
<tr class="rpg"><td class="title">Dragon Age: Inquisition</td><td>Role-playing Game</td><td>2014</td></tr>
<tr class="rpg"><td class="title">Skyrim</td><td>Role-playing Game</td><td>2011</td></tr>
<tr class="horror"><td class="title">Amnesia: The Dark Descent</td><td>Horror</td><td>2010</td></tr>
<tr class="simulator"><td class="title">Scania Truck Driving Simulator</td><td>Simulator</td><td>2012</td></tr>
<tr class="horror"><td class="title">Five Nights at Freddy’s</td><td>Horror</td><td>2014</td></tr>
<tr class="simulator"><td class="title">Sims 4</td><td>Simulator</td><td>2014</td></tr>
<tr class="rts" id="last"><td class="title">Warcraft III: Reign of Chaos</td><td>Real-time Strategy</td><td>2002</td></tr>
</tbody>
</table>
array[i] == 2014
Everything in the array will be an HTML Table Data Cell Element object.
Nothing in the array will be the Number 2014.
You need to read the text content from the element and then compare that.
I think this is a better way.
var table = document.getElementById("games");
count = 0;
for (let i = 0; row = table.rows[i]; i++) {
if (row.cells[2].innerHTML === "2014"){
count++;
}
/*
for (let j = 0; col = row.cells[j]; j++) {
if (col.innerHTML === "2014"){
count++;
}
}
*/
}
console.log(count);
The commented code is for checking every item on a single row.

JS - Compare first row to other rows in table

I'm a completely newbie and looking for help.
Given the following table:
<table id="table">
<thead>
# FIRST ROW
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
</tr>
<tbody>
# SECOND ROW
<tr>
<td>Apple</td> --> should end with 'success' class
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td> --> should end with 'success' class
</tr>
# THIRD ROW
<tr>
<td>Pizza</td> --> should end with 'success' class
<td>Chicken</td>
</tr>
</tbody>
</table>
I would like to add class 'success' to every td in SECOND and THIRD rows whenever it matches any td in FIRST row (and only in FIRST ROW).
For now I came up with adding <td> values of first row to array and I'm not sure what steps should I take next (filter? for loop and '===' comparison?):
function myFunction() {
var tHeadersValues = [];
var tHeaders = document.getElementById("table").rows[0].cells;
for (var i = 0; i < tHeaders.length; i++) {
tHeadersValues.push(tHeaders[i].textContent);
}
return tHeadersValues;
}
Object.keys(tHeaders).map(key => tHeaders[key].textContent) transforms the td objects to an array with the containing text. The rest is straight forward:
function toValues(tHeaders) {
return Object.keys(tHeaders).map(function(key){
return tHeaders[key].textContent;
});
}
function myFunction() {
var rows = document.getElementById("results-table").rows;
var tHeadersValues = toValues(rows[0].cells);
for (var i = 1; i < rows.length; i++) {
var rowCells = rows[i].cells;
var values = toValues(rowCells);
for(var j=0;j<values.length;j++) {
if(values[j].length > 0 && tHeadersValues.indexOf(values[j]) > -1) {
rowCells[j].className = "success";
}
}
}
}
myFunction();
<style>
.success {
background-color: green;
}
</style>
<table id="results-table">
<thead>
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td>
</tr>
<tr>
<td>Pizza</td>
<td>Chicken</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
function myFunc(){
var tds = document.getElementsByTagName("td");
var hds = document.getElementsByTagName("th");
for(var i=0; i<tds.length; i++) {
var tdContent = tds[i].innerHTML;
if(tdContent.length > 0){
for(var j = 0; j<hds.length; j++) {
if(tdContent === hds[j].innerHTML) {
document.getElementsByTagName("td")[i].className = "success";
}
}
}
}
}
myFunc();
<style>
.success {
background-color: green;
}
</style>
<table id="results-table">
<thead>
<tr>
<th>Apple</th>
<th>Pizza</th>
<th>Eggs</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Juice</td>
<td>Lettuce</td>
<td>Oranges</td>
<td>Eggs</td>
</tr>
<tr>
<td>Pizza</td>
<td>Chicken</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>

Categories

Resources