Search code examples
javascripthtmlcsshtml-table

Getting multiple tag-name indexes with JS - is it possible?


I am toying around with W3School's table search function, and was wondering if it is possible to grab multiple getElementsByTagName indexes at once, and thus (in this case) make a search for the entire table instead of just the first index? I have been trying to set up if-statements, but nothing seems to be functioning.

The code:

function myFunction() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  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";
      }
    }
  }
}
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 18px;
}

#myTable th,
#myTable td {
  text-align: left;
  padding: 12px;
}

#myTable tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header,
#myTable tr:hover {
  background-color: #f1f1f1;
}
<h2>My Customers</h2>

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

<table id="myTable">
  <tr class="header">
    <th style="width:60%;">Name</th>
    <th style="width:40%;">Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Berglunds snabbkop</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Koniglich Essen</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Italy</td>
  </tr>
  <tr>
    <td>North/South</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Paris specialites</td>
    <td>France</td>
  </tr>
</table>

When changing the index to 1 I am able to search the second row - but what would I do in order to make both searchable simultaneously?


Solution

  • You'll need to iterate over your tds, and determine if some of the tds contain the searched text:

    function myFunction() {
      var input, filter, table, tr, i, txtValue;
      input = document.getElementById("myInput");
      filter = input.value.toUpperCase();
      table = document.getElementById("myTable");
      tr = table.getElementsByTagName("tr");
      for (i = 0; i < tr.length; i++) {
        // Get all tds in the row.
        const tds = [...tr[i].getElementsByTagName("td")]; // Convert the HTMLCollection to Array
    
        // Check if a td in the row contains a search result.
        const hasSearchResult = tds.some(td => {
          txtValue = td.textContent || td.innerText;
          return txtValue.toUpperCase().indexOf(filter) > -1;
        });
    
        // 0 length is the header, skip that.
        if (!tds.length || hasSearchResult) {
          tr[i].style.display = "";
        } else {
          tr[i].style.display = "none";
        }
      }
    }
    * { box-sizing: border-box; }
    #myInput { background-image: url('/css/searchicon.png'); background-position: 10px 10px; background-repeat: no-repeat; width: 100%; font-size: 16px; padding: 12px 20px 12px 40px; border: 1px solid #ddd; margin-bottom: 12px; }
    #myTable { border-collapse: collapse; width: 100%; border: 1px solid #ddd; font-size: 18px; }
    #myTable th, #myTable td { text-align: left; padding: 12px; }
    #myTable tr { border-bottom: 1px solid #ddd; }
    #myTable tr.header, #myTable tr:hover { background-color: #f1f1f1; }
    <h2>My Customers</h2>
    
    <input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
    
    <table id="myTable">
      <tr class="header">
        <th style="width:60%;">Name</th>
        <th style="width:40%;">Country</th>
      </tr>
      <tr><td>Alfreds Futterkiste</td><td>Germany</td></tr>
      <tr><td>Berglunds snabbkop</td><td>Sweden</td></tr>
      <tr><td>Island Trading</td><td>UK</td></tr>
      <tr><td>Koniglich Essen</td><td>Germany</td></tr>
      <tr><td>Laughing Bacchus Winecellars</td><td>Canada</td></tr>
      <tr><td>Magazzini Alimentari Riuniti</td><td>Italy</td></tr>
      <tr><td>North/South</td><td>UK</td></tr>
      <tr><td>Paris specialites</td><td>France</td></tr>
    </table>