Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter a html table using simple javascript?

Tags:

I have a code to filter a table. It will filter only based on first column. How to make it filter second column alone. Also how to filter complete table?

I am not able to figure out the method to do it. I trying to get help to do it without any other external libraries.

<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>    <script>  function myFunction() {    var input, filter, table, tr, td, i;    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) {        if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {          tr[i].style.display = "";        } else {          tr[i].style.display = "none";        }      }           }  }  </script>

JS Fiddle

like image 593
qwww Avatar asked Jul 05 '18 09:07

qwww


People also ask

How do you add a filter in HTML?

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">


2 Answers

Filter all Html Table:

const myFunction = () => {   const trs = document.querySelectorAll('#myTable tr:not(.header)')   const filter = document.querySelector('#myInput').value   const regex = new RegExp(filter, 'i')   const isFoundInTds = td => regex.test(td.innerHTML)   const isFound = childrenArr => childrenArr.some(isFoundInTds)   const setTrStyleDisplay = ({ style, children }) => {     style.display = isFound([       ...children // <-- All columns     ]) ? '' : 'none'    }      trs.forEach(setTrStyleDisplay) }
input#myInput { width: 220px; } table#myTable { width: 100%; } table#myTable th { text-align: left; padding: 20px 0 10px; }
<input    type="text"    id="myInput"    onkeyup="myFunction()"    placeholder="Search for names or countries.."    title="Type in a name or a country">  <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>

Filter only specific Html Table Columns

  • Countries, in this case it is the column with index 1

const myFunction = () => {   const columns = [     { name: 'Name', index: 0, isFilter: false },     { name: 'Country', index: 1, isFilter: true }   ]   const filterColumns = columns.filter(c => c.isFilter).map(c => c.index)   const trs = document.querySelectorAll(`#myTable tr:not(.header)`)   const filter = document.querySelector('#myInput').value   const regex = new RegExp(escape(filter), 'i')   const isFoundInTds = td => regex.test(td.innerHTML)   const isFound = childrenArr => childrenArr.some(isFoundInTds)   const setTrStyleDisplay = ({ style, children }) => {     style.display = isFound([       ...filterColumns.map(c => children[c]) // <-- filter Columns     ]) ? '' : 'none'   }      trs.forEach(setTrStyleDisplay) }
input#myInput { width: 220px; } table#myTable { width: 100%; } table#myTable th { text-align: left; padding: 20px 0 10px; }
<input    type="text"    id="myInput"    onkeyup="myFunction()"    placeholder="Search for names or countries.."    title="Type in a name or a country">  <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>
like image 167
Yosvel Quintero Arguelles Avatar answered Sep 17 '22 23:09

Yosvel Quintero Arguelles


You are almost there. All you needed to do was to create another for loop and iterate over all td elements in the row, and filter using them. By doing so, if you add any columns in future, the filter will continue to work.

In the snippet below, I have done that, and slightly modified the hiding logic. I am hiding all the rows to begin with, and if a match is found, I unhide it.

for (i = 1; i < tr.length; i++) {     // Hide the row initially.     tr[i].style.display = "none";      td = tr[i].getElementsByTagName("td");     for (var j = 0; j < td.length; j++) {       cell = tr[i].getElementsByTagName("td")[j];       if (cell) {         if (cell.innerHTML.toUpperCase().indexOf(filter) > -1) {           tr[i].style.display = "";           break;         }        }     } } 

function myFunction() {    var input, filter, table, tr, td, cell, i, j;    input = document.getElementById("myInput");    filter = input.value.toUpperCase();    table = document.getElementById("myTable");    tr = table.getElementsByTagName("tr");    for (i = 1; i < tr.length; i++) {      // Hide the row initially.      tr[i].style.display = "none";          td = tr[i].getElementsByTagName("td");      for (var j = 0; j < td.length; j++) {        cell = tr[i].getElementsByTagName("td")[j];        if (cell) {          if (cell.innerHTML.toUpperCase().indexOf(filter) > -1) {            tr[i].style.display = "";            break;          }         }      }    }  }
<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>

Note: I would suggest using innerText instead of innerHTML for filtering. If you have HTML content in the cells, innerHTML might interfere with the filtering.

like image 25
Nisarg Shah Avatar answered Sep 20 '22 23:09

Nisarg Shah