skip to Main Content

I’m trying to create a product comparison table that users can click a button to show/hide additional specification details.

I read you cannot do this with duplicate ids but I’ve had trouble trying to select by class.

The posted code is my closest attempt thus far.

function toggleTable()
{
 if( document.getElementById("hide").style.display=='none' ){
   document.getElementById("hide").style.display = 'table-row'; // set to table-row instead of an empty string
 }else{
   document.getElementById("hide").style.display = 'none';
 }
}
<h2>Table</h2>
<div>
  <table>
    <tbody>
      <tr>
        <td>Blank</td>
        <td>Info</td>
      </tr>
      <tr>
        <td>Blank</td>
        <td>Info</td>
      </tr>
      <tr id="hide" style="display:none;">
        <td>Show/Hide</td>
        <td>Info</td>
      </tr>
      <tr id="hide" style="display:none;">
        <td>Show/Hide</td>
        <td>Info</td>
      </tr>
    </tbody>
  </table>
</div>
<button type="button" onclick="toggleTable()">Show/Hide ▼</button>

3

Answers


  1. As you mentioned, it is always a good practice not to use the same ID more than once. So I have made a version which replaces your Html tag identifier from ID to using a class.

    Added comments inline with the code for your understanding.In your case, since there are multiple items that you want to select, it is wise to put them in a list and iterate it one by one to apply the properties.

    function toggleTable()
    {
      var list = document.getElementsByClassName("hide"); // Since there are more than one item, lets park it into a list
      for(var i=0;i<list.length;i++) // iterating thru a list and applying properties to individual items
      {
         if( list[i].style.display =='none'){
           list[i].style.display = 'table-row'; // set to table-row instead of an empty string
         }else{
           list[i].style.display = 'none';
         }
       }
    }
    <h2>Table</h2>
    <div>
            <table>
                <tbody>
                    <tr>
                        <td>Blank</td>
                        <td>Info</td>
                    </tr>
                    <tr>
                        <td>Blank</td>
                        <td>Info</td>
                    </tr>
                  <tr class="hide" style="display:none;">
                        <td>Show/Hide</td>
                        <td>Info</td>
                    </tr>
                    <tr Class="hide" style="display:none;">
                        <td>Show/Hide</td>
                        <td>Info</td>
                    </tr>
                </tbody>
            </table>
        </div>
       <button type="button" onclick="toggleTable()">Show/Hide ▼</button>
    Login or Signup to reply.
  2. I prefer using classes to identify the parts that will be manipulated – in your case for their display to be toggled – and I keep styles and code out of the html. No inline "onclick" handlers, and style is always in css.

    I removed the id on the rows because it’s not needed, and it’s illegal to use the same id more than once. I added an id to the button to make it easy to get it in javascript.
    I’ve also done a little styling so it’s easier to see the parts — the table cells.

    I’m using two classes
    hideable marks the rows that can be hidden or shown – things that are hideable
    hidden because I want to start with those rows already hidden

    The code here gets the "toggle" button using the id I added to it, then adds an event listener to the button for the ‘click’ event, and I put the code to be run inline rather than making a separate function.

    When the button is clicked it runs the code, which
    • finds all things marked as .hideable
    • toggles the class hidden on each thing found – so if it already has .hidden that is removed and the element becomes visible; if it isn’t hidden the .hidden class gets added so the css selector .hideable.hidden sets the display to none.

    document.getElementById('toggle')
      ?.addEventListener('click', (e) => {
          document.querySelectorAll('.hideable')
                  .forEach(h => h.classList.toggle('hidden'));
      });
    table {
      border-collapse: collapse;
      border: 1px solid gray;
    }
    
    th, td {
      padding: 6px;
      border: 1px solid gray;
    }
    
    .hideable {
      display: default;
    }
    
    .hideable.hidden {
      display: none;
    }
    <button type="button" id="toggle">Show/Hide ▼</button>
    <h2>Table</h2>
    <div>
      <table>
        <tbody>
          <tr>
            <td>Blank</td>
            <td>Info</td>
          </tr>
          <tr>
            <td>Blank</td>
            <td>Info</td>
          </tr>
          <tr class="hideable hidden">
            <td>Show/Hide</td>
            <td>Info</td>
          </tr>
          <tr class="hideable hidden">
            <td>Show/Hide</td>
            <td>Info</td>
          </tr>
        </tbody>
      </table>
    </div>
    Login or Signup to reply.
  3. I always try and avoid manupulating style directly in jacvascript and leave it to CSS classes to handle the actual style. Then it comes down to just toggling the styles with JavaScript.

    This is very close to Stephens answer, with what I believe is a simpler CSS approach. He beat me to the punch so make sure to give him the accepted tick.

    //Add event listener
    document.getElementById("toggle").addEventListener("click", function(){
      //Get tht toggleable rows
       document.querySelectorAll(".canToggle")
       //For each row
       .forEach(function(row){
          //Toggle the show class
          row.classList.toggle("show");
       });  
    })
    /*Hide the row by default , but no if it has the show class*/
    .canToggle:not(.show) {display:none;}
    <h2>Table</h2>
    <div>
            <table>
                <tbody>
                    <tr>
                        <td>Blank</td>
                        <td>Info</td>
                    </tr>
                    <tr>
                        <td>Blank</td>
                        <td>Info</td>
                    </tr>
                  <tr class="canToggle">
                        <td>Show/Hide</td>
                        <td>Info</td>
                    </tr>
                    <tr class="canToggle">
                        <td>Show/Hide</td>
                        <td>Info</td>
                    </tr>
                </tbody>
            </table>
        </div>
       <button type="button" id="toggle">Show/Hide ▼</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search