skip to Main Content

I have the below code which does a good job in searching for matches in one specific table column, but it would be nice if I could get it to search all columns in the HTML table. I just don’t know how I can modify the existing code to accomplish it. Any help would be appreciated!

I have isolated what part of this code deals with column selection – td = tr[i].getElementsByTagName("td")[0]; – but I don’t know how to modify it to loop through all values in that array as it searches for a match.

HTML

<input type="text" id="searchInput" onkeyup="tableSearch()" placeholder="Search for something ...">

JS

function tableSearch() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("searchInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[0];
    if (td) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }
  }
}

2

Answers


  1. You could add a second for-loop inside the first one that loops over each td element and checks each value. Right now you’re only grabbing the first one of each row (tr[i].getElementsByTagName("td")[0]; note the [0] at the end).

    Something like this should do it:

    function tableSearch() {
      var input, filter, table, tr, td, i, x, txtValue;
      input = document.getElementById("searchInput");
      filter = input.value.toUpperCase();
      table = document.getElementById("myTable");
      tr = table.getElementsByTagName("tr");
      
      for (i = 0; i < tr.length; i++) {
        tr[i].style.display = "none"; // hide by default
        td = tr[i].getElementsByTagName("td");
    
        for (x = 0; x < td.length; x++) { // loop over each "td" within this row(tr)
          txtValue = td[x].textContent || td[x].innerText;
          if (txtValue.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
            break; // don't care about the rest of the columns on this row as it already found a match for us, so we can skip the rest.
          }
        }
      }
    }
    
    Login or Signup to reply.
  2. You can use some() to check if any td in same tr is match the input text.

    const table = document.querySelector("#myTable");
    const tableSearch = (e) => {
      let filter, txtValue, input, tds;
      input = e.target.value.toUpperCase();
      table.querySelectorAll("tr").forEach(tr => {
        tds = [...tr.querySelectorAll("td")]
        if (tds.length !== 0) tr.style.display = tds.some(td => td.innerText.toUpperCase().includes(input)) ? '' : "none";
      });
    }
    document.querySelector("#searchInput").addEventListener('input', tableSearch);
    <input type="text" id="searchInput" placeholder="Search for something ...">
    <table id="myTable">
      <tr>
        <th>a</th>
        <th>b</th>
        <th>c</th>
      </tr>
      <tr>
        <td>abc</td>
        <td>bcd</td>
        <td>cde</td>
      </tr>
      <tr>
        <td>abc</td>
        <td>def</td>
        <td>ghi</td>
      </tr>
      <tr>
        <td>cba</td>
        <td>def</td>
        <td>ijk</td>
      </tr>
    </table>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search