简体   繁体   中英

How to filter a html table using simple javascript?

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

You can do:

 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]) ? '' : '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 usinginnerText instead of innerHTML for filtering. If you have HTML content in the cells, innerHTML might interfere with the filtering.

Only change

td = tr[i].getElementsByTagName("td")[0];

to

td = tr[i].getElementsByTagName("td")[1];

should work fine.

Update

Add all columns search.

 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 (var i = 0; i < tr.length; i++) { var tds = tr[i].getElementsByTagName("td"); var flag = false; for(var j = 0; j < tds.length; j++){ var td = tds[j]; if (td.innerHTML.toUpperCase().indexOf(filter) > -1) { flag = true; } } if(flag){ tr[i].style.display = ""; } else { tr[i].style.display = "none"; } } }
 <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>

With

td = tr[i].getElementsByTagName("td")[0];

you're only selecting the first td . Instead, check for if some of the td s have the string in question:

 function myFunction() { const input = document.getElementById("myInput"); const inputStr = input.value.toUpperCase(); document.querySelectorAll('#myTable tr:not(.header)').forEach((tr) => { const anyMatch = [...tr.children] .some(td => td.textContent.toUpperCase().includes(inputStr)); if (anyMatch) tr.style.removeProperty('display'); else tr.style.display = 'none'; }); }
 <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>

Here is the code to create an HTML table with a filter option on each column separately. Trust me it is easy and works for me. Just give it a try. I am applying it to my JSON data.

For this, I give this credit to https://www.jqueryscript.net/table/filter-each-column.html

 function checkval(){1==$("tbody tr:visible").length&&"No result found"==$("tbody tr:visible td").html()?$("#rowcount").html("0"):$("#rowcount").html($("tr:visible").length-1)}$(document).ready(function(){$("#rowcount").html($(".filterable tr").length-1),$(".filterable .btn-filter").click(function(){var t=$(this).parents(".filterable"),e=t.find(".filters input"),l=t.find(".table tbody");1==e.prop("disabled")?(e.prop("disabled",!1),e.first().focus()):(e.val("").prop("disabled",!0),l.find(".no-result").remove(),l.find("tr").show()),$("#rowcount").html($(".filterable tr").length-1)}),$(".filterable .filters input").keyup(function(t){if("9"!=(t.keyCode||t.which)){var e=$(this),l=e.val().toLowerCase(),n=e.parents(".filterable"),i=n.find(".filters th").index(e.parents("th")),r=n.find(".table"),o=r.find("tbody tr"),d=o.filter(function(){return-1===$(this).find("td").eq(i).text().toLowerCase().indexOf(l)});r.find("tbody .no-result").remove(),o.show(),d.hide(),d.length===o.length&&r.find("tbody").prepend($('<tr class="no-result text-center"><td colspan="'+r.find(".filters th").length+'">No result found</td></tr>'))}$("#rowcount").html($("tr:visible").length-1),checkval()})});
 .filterable{margin-top:15px}.filterable .panel-heading .pull-right{margin-top:-20px}.filterable .filters input[disabled]{background-color:transparent;border:none;cursor:auto;box-shadow:none;padding:0;height:auto}.filterable .filters input[disabled]::-webkit-input-placeholder{color:#333}.filterable .filters input[disabled]::-moz-placeholder{color:#333}.filterable .filters input[disabled]:-ms-input-placeholder{color:#333}
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <div class="panel panel-primary filterable"> <table class="table"> <thead> <tr class="filters"> <th><input type="text" placeholder="#"></th> <th><input type="text" placeholder="First Name"></th> <th><input type="text" placeholder="Last Name"></th> <th><input type="text" placeholder="Username"></th> <th><input type="text" placeholder="PhoneNo"></th> </tr> </thead> <tbody> <tr> <td>10</td> <td>Tom</td> <td>Amar</td> <td>@TAmar</td> <td>306-456-7890</td> </tr> <tr> <td>20</td> <td>Dick</td> <td>Akbar</td> <td>@DAkbar</td> <td>456-456-7890</td> </tr> <tr> <td>30</td> <td>Harry</td> <td>Anthony</td> <td>@HAnthony</td> <td>526-456-7890</td> </tr> </tbody> </table> <p>No.of Rows : <span id="rowcount"></span></p> </div>

if you want to make filter to second column alone then a little modification to Yosvel Quintero Arguelles's code is given below

const table = document.getElementById("tableId");  
const trs = table.querySelectorAll('tr:nth-child(n)');  
// Or if you have headers, use line below instead of above
// const trs = document.querySelectorAll('#tableId tr:not(.header)');
const filter = document.querySelector('#myInput').value;
const regex = new RegExp(filter, 'i');
const isFoundInTds = (td) => regex.test(td.innerHTML);
const setTrStyleDisplay = ({ style, children }) => {
    // Here 1 represents second column
    style.display = isFoundInTds(children[1]) ? '' : 'none';
};

trs.forEach(setTrStyleDisplay);

You can also filter a table with js in this way Add a button which is handling click

 <button class="btn btn-secondary mx-2" 
  type="submit" 
  onclick="sortTableyear3()">3</button>

then add this function in your .js file or in the script tag

 function sortTableyear3() {
  var input, filter, table, tr, td, i, txtValue;
  input = 3;  // change this accordingly
  filter = input.value;
  table = document.getElementById("regstud-table");
  tr = table.getElementsByTagName("tr");

// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[2];// 2 is for 3rd column
    if (td) {
        txtValue = td.textContent || td.innerText;
        if (txtValue == input) {
            tr[i].style.display = "";
        } else {
            tr[i].style.display = "none";
        }
    }
}
  }

this will show only those rows in which third column values are 3. And with using greater than and filter in a table

My simple code: (I use bootstrap with class d-none to hide row)

const rows = document.querySelectorAll("tbody tr")
    
document.querySelector('#filter').addEventListener('keyup', (e) => {        // You may want to use any debounce function like the one from Underscore.js
    rows.forEach( row => {
        if(row.innerText.indexOf(e.target.value) == -1) {
            row.classList.add('d-none')
        }
        else {
            row.classList.remove('d-none')
        }
    })
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM