Filtering table multiple columns

前端 未结 14 1702
闹比i
闹比i 2020-12-09 13:31

I used w3School code for my page and it works fine but it only filters one column, don’t know how create loops but hopping there is easier solution.

    td =         


        
14条回答
  •  爱一瞬间的悲伤
    2020-12-09 14:19

    There are significantly better resources on the web than W3 Schools, you really should avoid that website IMO. That being said, you just need to look at tr rather than one of the tds if you want to match the whole row:

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

    If you want to filter multiple columns instead of the whole row, just use OR (||) in your condition:

    function myFunction() {
        var input = document.getElementById("myInput");
        var filter = input.value.toUpperCase();
        var table = document.getElementById("myTable");
        var tr = table.getElementsByTagName("tr");
        var tds = tr.getElementsByTagName('td');
    
        for (var i = 0; i < tr.length; i++) {
            var firstCol = tds[0].textContent.toUpperCase();
            var secondCol = tds[1].textContent.toUpperCase();
            if (firstCol.indexOf(filter) > -1 || secondCol.indexOf(filter) > -1) {
                tr[i].style.display = "";
            } else {
                tr[i].style.display = "none";
            }      
        }
    }
    

    Some reasons why this tutorial isn't great: you should avoid using innerHTML and should instead use textContent since it's possible that your cells will have HTML and the user could type a tag name when trying to search for visible text and be confused by what is matching. You should give your functions names that indicate what they do (e.g. filterTable instead of myFunction). Additionally, there are easier ways to access table data (e.g. tr.cells). If you add a keyup event listener to #myInput you will not need to lookup that DOM node everytime the function is called. Here is an example:

    function filterTable(event) {
        var filter = event.target.value.toUpperCase();
        var rows = document.querySelector("#myTable tbody").rows;
        
        for (var i = 0; i < rows.length; i++) {
            var firstCol = rows[i].cells[0].textContent.toUpperCase();
            var secondCol = rows[i].cells[1].textContent.toUpperCase();
            if (firstCol.indexOf(filter) > -1 || secondCol.indexOf(filter) > -1) {
                rows[i].style.display = "";
            } else {
                rows[i].style.display = "none";
            }      
        }
    }
    
    document.querySelector('#myInput').addEventListener('keyup', filterTable, false);
    
    
    Name Country
    Alfreds Futterkiste Germany
    Berglunds snabbkop Sweden
    Island Trading UK
    Koniglich Essen Germany
    Laughing Bacchus Winecellars Canada
    Magazzini Alimentari Riuniti Italy
    North/South UK
    Paris specialites France

提交回复
热议问题