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
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
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>
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With