1

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.

2
  • Please add relevant JS code also.. Commented Apr 11, 2020 at 13:35
  • 1
    Also, data="Green" is not valid data-* attribute. you need to provide a name to it like data-color="Green" or something. Commented Apr 11, 2020 at 13:35

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. The solution is elegant. I really appreciate your precious time. Your solution saved my googling hours. But sir, if the document has more than one table, it doesn’t work. Could you please help with that?
@Icado If that’s the case you need to iterate through all table elements on the page and then run the same code for every table element you come across.
Got it. Thank you very much sir.
0
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

3 Comments

Thanks for the solution sir. But it doesn’t handle more than one table in the same document. Could you please help me with the loop? If loop, the script can handle all the tables in the same page. Thank you.
Hi, I just edited the solution in order to loop over all the tables
Thank you sir. Now, loop is handling all the tables in the page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.