Skip to content
Advertisement

pure javascript table checkbox filter

Table filter value with checkbox

I want to match all checkboxes conditions.

Problem : when uncheck and checked again. it compared last value

example: I uncheck robot and re-check james It should not display robot

enter image description here

What I need #

enter image description here

function filter(event, filterCol) {
  let element = event.target;
  let condt1 = document.getElementsByClassName(filterCol);
  var table = document.getElementById("listingTable");
      
    for (let i = 0; i < condt1.length; i++) {
      if (condt1[i].innerHTML.toLocaleUpperCase() == element.value.toLocaleUpperCase()) {
        if (element.checked == true) {
           condt1[i].parentElement.closest('tr').style = "display:table-row"

        } else {
           condt1[i].parentElement.closest('tr').style = "display:none"
        }
      }

  }
}

document.querySelectorAll('.option1').forEach(input => input.addEventListener('input', ()=>filter(event,"check1")));
document.querySelectorAll('.option3').forEach(input => input.addEventListener('input', ()=>filter(event,"check3")));
<div id="input">
<label>Filter Name </label><br>
<label>Adison<input class="option1" type="checkbox" value="Adison" checked/></label>
<label>James<input class="option1" type="checkbox" value="James" checked/></label><br><br>

<label>Filter Race </label><br>
<label>human<input class="option3" type="checkbox" value="human" checked/></label>
<label>robot<input class="option3" type="checkbox" value="robot" checked/></label>
</div><br>


<table id="listingTable">
  <tr>
    <th>Name</th>
    <th>Country</th>
    <th>Race</th>
  </tr>
  <tr>
    <td class="check1">Adison</td>
    <td >Sweden</td>
    <td class="check3">robot</td>
  </tr>
   <tr>
    <td class="check1">Adison</td>
    <td >UK</td>
    <td class="check3">human</td>
  </tr>
   <tr>
    <td class="check1">James</td>
    <td >Sweden</td>
    <td class="check3">human</td>
  </tr>
   <tr>
    <td class="check1">James</td>
    <td>Germany</td>
    <td class="check3">robot</td>
  </tr>
   <tr>
    <td class="check1">Adison</td>
    <td>Italy</td>
    <td class="check3">robot</td>
  </tr>
 
</table>

Or I should modified filter function. Can anyone advise with my code ?

Thank.

Advertisement

Answer

The reason this happens is that you are evaluating if the element causing the event is “checked”. In the case of “James” well that is true when you check that. So every column in your table which has “James” in it, will be visible according to your current logic. To accomplish what you want, you need to check every input element, not just the one triggering the event.

You also have to make sure that you don’t show a hidden row if a checkbox hides it. Your algorithm will toggle visibility on and off for each checkbox individually, not combined. By running the algorithm for each row, rather than for every cell in the table you mitigate that and end up with what you want.

So the algorithm is: Loop over each row Loop over each checkbox Loop over all filtered columns Check if text matches checkbox and if the checkbox is unchecked Hide the row

Like this:

function filter(event, tableId, filterCol) {
    let checkboxes = document.getElementsByTagName("input");
    let rows = document.getElementById(tableId).getElementsByTagName("tr");
    for(let r = 0;r<rows.length;r++){
      let cols = rows[r].querySelectorAll(filterCol);
      rows[r].style = "display: table-row";
      for(let i = 0;i<checkboxes.length;i++){
        let value = checkboxes[i].value.toLocaleUpperCase();
        for(let c= 0; c<cols.length;c++){
          let cvalue = cols[c].innerText.toLocaleUpperCase();
          if(cvalue === value && checkboxes[i].checked === false){
            rows[r].style = "display: none";
          }
        }
      }
    }
  }
  
  document.querySelectorAll([".option1",".option3"]).forEach(input => input.addEventListener('input', ()=>filter(event,"listingTable",[".check1",".check3"])));
  <div id="input">
    <label>Filter Name </label><br>
    <label>Adison<input class="option1" type="checkbox" value="Adison" checked/></label>
    <label>James<input class="option1" type="checkbox" value="James" checked/></label><br><br>
    
    <label>Filter Race </label><br>
    <label>human<input class="option3" type="checkbox" value="human" checked/></label>
    <label>robot<input class="option3" type="checkbox" value="robot" checked/></label>
    </div><br>
    
    

<table id="listingTable">
  <tr>
    <th>Name</th>
    <th>Country</th>
    <th>Race</th>
  </tr>
  <tr>
    <td class="check1">Adison</td>
    <td >Sweden</td>
    <td class="check3">robot</td>
  </tr>
   <tr>
    <td class="check1">Adison</td>
    <td >UK</td>
    <td class="check3">human</td>
  </tr>
   <tr>
    <td class="check1">James</td>
    <td >Sweden</td>
    <td class="check3">human</td>
  </tr>
   <tr>
    <td class="check1">James</td>
    <td>Germany</td>
    <td class="check3">robot</td>
  </tr>
   <tr>
    <td class="check1">Adison</td>
    <td>Italy</td>
    <td class="check3">robot</td>
  </tr>
 
</table>
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement