0

I have the following HTML table, I need to iterate through the rows and its columns.

<table id="hosts" border="1">
<tbody>
   <tr>
      <td><input type="checkbox" checked=""></td>
      <td>127.0.0.1</td>
      <td>localhost</td>
   </tr>
   <tr>
      <td><input type="checkbox"></td>
      <td>255.255.255.255</td>
      <td>broadcasthost</td>
   </tr>
</tbody>
</table>


<script>
    let table = document.getElementById("hosts");
    for (let row of table.rows) {
      for (let cell of row.cells) {
        if (cell.cellIndex === 0) {
          // I need to to know if the input inside the cell is checked or not
          // I can get the cell.InnerHTML, but how do I check if the checkbox is checked or not?
        }
    } 
</script>

I dont use Jquery

Mosè Raguzzini
  • 15,399
  • 1
  • 31
  • 43
Shobi
  • 10,374
  • 6
  • 46
  • 82

2 Answers2

1

You don't want innerHTML for this, you just want to access the HTMLInputElement within that cell.

You can do it like this, but it's fragile:

cell.firstChild.checked

I'd probably use querySelector to find the first input within the cell:

cell.querySelector("input").checked

Similarly, I probably wouldn't use cellIndex === 0, so I could change the layout without breaking my code. So for instance:

let table = document.getElementById("hosts");
for (let row of table.rows) {
  for (let cell of row.cells) {
    const checkbox = cell.querySelector("input[type=checkbox]");
    if (checkbox && checkbox.checked) {
      // ...this cell has a checked checkbox in it...
    }
}

Side note:

Beware, the HTMLCollection returned by rows and cells is not defined as being iterable, but you're relying on it being iterable by using for-of. Some browsers make it iterable even though it isn't specified, but others don't.

If you're doing this in a page or application (not a library), you can ensure that HTMLCollection is iterable by polyfilling it like this:

if (typeof HTMLCollection !== "undefined" && HTMLCollection.prototype && !HTMLCollection.prototype.forEach) {
    // Yes, there's really no need for `Object.defineProperty` here
    HTMLCollection.prototype.forEach = Array.prototype.forEach;
    if (typeof Symbol !== "undefined" && Symbol.iterator && !HTMLCollection.prototype[Symbol.iterator]) {
        Object.defineProperty(HTMLCollection.prototype, Symbol.iterator, {
            value: Array.prototype[Symbol.itereator],
            writable: true,
            configurable: true
        });
    }
}

See this answer doing that for NodeList (which is defined as iterable) for details.

Alternately, use querySelectorAll on the table and rows instead:

for (let row of table.querySelectorAll("tr")) {
  for (let cell of row.querySelectorAll("td")) {
    // ...
  }
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

You can use querySelectorAll and querySelector

[...document.getElementById("hosts")querySelectorAll('tr')]

This snippet is getting all the tr and converting to array so that array methods can be used

forEach(function(item) {
  let getInput = item.querySelector('input[type="checkbox"]')

forEach is an array method and during each iteration item will tr and from it get the first input[type="checkbox"].querySelector will return the first matched element.

Then use checked to validate the state of the input

let table = [...document.getElementById("hosts")
  .querySelectorAll('tr')
].forEach(function(item) {
  let getInput = item.querySelector('input[type="checkbox"]');
  if (getInput.checked) {
    console.log('checked')
  } else {
    console.log('not checked')
  }
})
<table id="hosts" border="1">
  <tbody>
    <tr>
      <td><input type="checkbox" checked=""></td>
      <td>127.0.0.1</td>
      <td>localhost</td>
    </tr>
    <tr>
      <td><input type="checkbox"></td>
      <td>255.255.255.255</td>
      <td>broadcasthost</td>
    </tr>
  </tbody>
</table>
brk
  • 48,835
  • 10
  • 56
  • 78