skip to Main Content

I have a HTML document with a table in it

<table>
  <tr>
    <th class="street">Street</th>
    <th class="city">City</th>
    <th class="country">Country</th>
  </tr>
  <tr>
    <td class="street">street-1</td>
    <td class="city">city-1</td>
    <td class="country">country-1</td>
  </tr>
  <tr>
    <td class="street">street-2</td>
    <td class="city">city-2</td>
    <td class="country">country-2</td>
  </tr>
</table>

Now I am looking for a way to implement buttons.
For example

<button id="button_street">TOGGLE STREET</button>
<button id="button_city">TOGGLE CITY</button>
<button id="button_country">TOGGLE COUNTRY</button>

If a button is pressed, the corresponding column in the table should be hidden.
Even better (than hidden) it would be if I could change the css design with the buttons.

My (temporary) solution is quite cumbersome…
It’s a javascript solution that changes one class (visible) to another (hidden).

Spry.Utils.addLoadListener(function() {
    let buttonToggle = document.getElementById('button_street');
    buttonToggle.addEventListener('click', toggleClass);
    
    function toggleClass() {
        let collection = document.getElementsByClassName("street");
        for (var i=0; i<collection.length; i++) {
            collection[i].classList.toggle('street_design2');
        }
    }
}

This javascript must be repeated for each button.

where the css is the following:

.street {
    background-color: blue;
}

.street_design2 {
    background-color: red;
}

If I want to hide the "street-column" I can use display: none

  1. I haven’t found any other javascript solution to address all elements with class street. Maybe there is a better solution?
  2. also it would be good if i could pass the function to an array like this:

const array = ["street", "city", "country"]

instead of repeating it for each button. Maybe there is a solution (a loop?)?

2

Answers


  1. You can use document.querySelectorAll to address all elements with same tagName, class, etc, and then use .forEach() to add the EventListener to all elements at once for your case.

    function toggleClass(collection) {
      document.querySelectorAll('.' + collection).forEach(function(element) {
        element.classList.toggle(collection + '_design2');
      });
    }
    
    document.querySelectorAll('button').forEach(function(button) {
      button.addEventListener('click', function(e) {
        let collection = this.id.split('_').pop();
        
        toggleClass(collection);
      });
    });
    .street {
        background-color: blue;
    }
    
    .street_design2 {
        background-color: red;
    }
    
    .city_design2 {
      background-color: yellow;
    }
    
    .country_design2 {
      background-color: green;
    }
    <table>
      <tr>
        <th class="street">Street</th>
        <th class="city">City</th>
        <th class="country">Country</th>
      </tr>
      <tr>
        <td class="street">street-1</td>
        <td class="city">city-1</td>
        <td class="country">country-1</td>
      </tr>
      <tr>
        <td class="street">street-2</td>
        <td class="city">city-2</td>
        <td class="country">country-2</td>
      </tr>
    </table>
    
    <button id="button_street">TOGGLE STREET</button>
    <button id="button_city">TOGGLE CITY</button>
    <button id="button_country">TOGGLE COUNTRY</button>
    Login or Signup to reply.
  2. You can use the data property to specify which node to target. It will help in avoiding the name conflicts in the future and also callback will only execute for the specific button where data-table-toggle property is specified so it will avoid conflicts with other buttons.

    Code will adds an event listener to all the buttons in a web page that have a custom data attribute "data-table-toggle". When the user clicks on one of these buttons, the tableToggle() function is executed.

    The tableToggle() function first retrieves the value of the "data-table-toggle" attribute of the clicked button using this.getAttribute("data-table-toggle"). It then uses this value to select all the table rows that have a class attribute matching the value of the "data-table-toggle" attribute. This is done using the document.querySelectorAll() method with a CSS selector string that targets all the elements that have a child element with the specified class.

    Finally, the function toggles the class of each selected table row between two different styles: the original class associated with the value of "data-table-toggle" attribute and a new class with "-_design2" appended to it. This is done using the classList.toggle() method.

    Overall, this code dynamically modifies the styles of table rows based on the clicked button, allowing for a simple toggle effect.

    <html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.2/axios.min.js" integrity="sha512-NCiXRSV460cHD9ClGDrTbTaw0muWUBf/zB/yLzJavRsPNUl9ODkUVmUHsZtKu17XknhsGlmyVoJxLg/ZQQEeGA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <script src="script.js"></script>
        <style>
            table .street-_design2 {
                display:none;
            }   
            table .city-_design2 {
                display:none;
            }   
            table .country-_design2 {
                display:none;
            }   
        </style>
    </head>
    <body>
        <table>
            <tr>
              <th class="street">Street</th>
              <th class="city">City</th>
              <th class="country">Country</th>
            </tr>
            <tr>
              <td class="street">street-1</td>
              <td class="city">city-1</td>
              <td class="country">country-1</td>
            </tr>
            <tr>
              <td class="street">street-2</td>
              <td class="city">city-2</td>
              <td class="country">country-2</td>
            </tr>
          </table>
        
            <button data-table-toggle="street">TOGGLE STREET</button>
            <button data-table-toggle="city">TOGGLE CITY</button>
            <button data-table-toggle="country">TOGGLE COUNTRY</button>
    </body>
    
    window.onload = function () {
    Array.from(document.querySelectorAll("button")).forEach(function (element) {
        if (!element.getAttribute("data-table-toggle")) return;
        element.addEventListener('click', tableToggle);
    });
    function tableToggle() {
        const attribute = this.getAttribute("data-table-toggle");
        Array.from(document.querySelectorAll(`tr .${attribute}`)).forEach(function (selector) {
            selector.classList.toggle(`${attribute}-_design2`);
        })
    }
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search