Paramaeleon Paramaeleon - 7 days ago 5
Javascript Question

How to change the visibility of a table row in Javascript?

I am trying to show/hide rows in a HTML table by javascript. Checking the check box shall show the additional rows, unchecking it shall hide them.

<html><body><form><table>
<tr>
<td> This row is always visible. </td>
</tr>
<tr>
<td>
<input id="cbox" type="checkbox" onchange="for(e in document.getElementsByClassName('switchMe')) e.style.display = document.getElementById('cbox').checked ? 'block' : 'none';"/>
<label for="cbox">Show more …</label>
</td>
</tr>
<tr class="switchMe" style="display: none; ">
<td> This row will be shown after the user clicks the check box. </td>
</tr>
<tr class="switchMe" style="display: none; ">
<td> This row too. </td>
</tr>
<tr>
<td> This row is always visible. </td>
</tr>
</table></form></body></html>


However, nothing happens, and I get an
e.style is undefined
error in the console. How do I access the style attribute of the
<tr>
element correctly?

(I first tried putting the rows in question in a
<div>
. That doesn’t give any error, but the rows are always visible, and the
<div>
is absent in Firebug, so it is probably not allowed there.)

Answer
  • First, for..in is ideal for iterating over objects but not on NodeList.
  • Second, its a bad practice to have change event listener in html. Anyone can change markup using dev tools and manipulate behaviour of your system. You should use .addEventListener
  • Third, defining a variable without var will make it global.

Output of for..in

var el_list = document.querySelectorAll('.switchMe');
for(var el in el_list){
  console.log(el)
}
<form>
  <table>
    <tr>
      <td>This row is always visible.</td>
    </tr>
    <tr>
      <td>
        <input id="cbox" type="checkbox" />
        <label for="cbox">Show more …</label>
      </td>
    </tr>
    <tr class="switchMe" style="display: none; ">
      <td>This row will be shown after the user clicks the check box.</td>
    </tr>
    <tr class="switchMe" style="display: none; ">
      <td>This row too.</td>
    </tr>
    <tr>
      <td>This row is always visible.</td>
    </tr>
  </table>
</form>

Sample

JSFiddle

document.querySelector('#cbox').addEventListener('click', function(e) {
  var switchEl = document.querySelectorAll('.switchMe');
  for (var i = 0; i < switchEl.length; i++)
    switchEl[i].style.display = this.checked ? 'block' : 'none';
});
<form>
  <table>
    <tr>
      <td>This row is always visible.</td>
    </tr>
    <tr>
      <td>
        <input id="cbox" type="checkbox" />
        <label for="cbox">Show more …</label>
      </td>
    </tr>
    <tr class="switchMe" style="display: none; ">
      <td>This row will be shown after the user clicks the check box.</td>
    </tr>
    <tr class="switchMe" style="display: none; ">
      <td>This row too.</td>
    </tr>
    <tr>
      <td>This row is always visible.</td>
    </tr>
  </table>
</form>