Filtering table multiple columns

前端 未结 14 1676
闹比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:10

    Here is correct function

    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[i].textContent.toUpperCase().indexOf(filter) > -1) {
                tr[i].style.display = "";
            } else {
                tr[i].style.display = "none";
            }      
        }
    }
    

    Should be tr[i].textContent

    0 讨论(0)
  • 2020-12-09 14:12

    You just need to add another loop to go over the cells, so:

    table = document.getElementById("myTable");
    //  tr = table.getElementsByTagName("tr");
    // Easier to use the rows collection:
    var tr = table.rows;
    
    for (i = 0; i < tr.length; i++) {
    
      // Easier to use the cells collection
      // td = tr[i].getElementsByTagName("td")[0];
      cells = row.cells;
    
      // Loop over all the cells
      for (var j=0, jLen=cells.length; j<jLen; j++) {
        td = cells[j];
    
        // Existing loop
        if (td) {
          if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
          } else {
            tr[i].style.display = "none";
          }
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-09 14:13

    Your code is fine. To add multiple columns you need to add || condition (in if clause).

    The problem with Rob's answer is it will filter out table headings if you use tr.

    Here is extension to code:

    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]; // for column one
         td1 = tr[i].getElementsByTagName("td")[1]; // for column two
    /* ADD columns here that you want you to filter to be used on */
        if (td) {
          if ( (td.innerHTML.toUpperCase().indexOf(filter) > -1) || (td1.innerHTML.toUpperCase().indexOf(filter) > -1) )  {            
            tr[i].style.display = "";
          } else {
            tr[i].style.display = "none";
          }
        }
      }
    } 
    
    0 讨论(0)
  • 2020-12-09 14:13

    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);
    <input id="myInput" type="text" />
    <table id="myTable">
     <thead>
      <tr class="header">
        <th style="width:60%;">Name</th>
        <th style="width:40%;">Country</th>
      </tr>
     </thead>
     <tbody>
      <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>
     </tbody>
    </table>

    0 讨论(0)
  • 2020-12-09 14:18

    Code that works for filtering multiple columns dynamically. No changes needed.

        function myFunction(elem) {
            var input, filter, table, tr, td, i, txtValue;
            input = elem;
            filter = input.value.toUpperCase();
            table = document.getElementById("YourTableId");
            tr = table.getElementsByTagName("tr");
            for (i = 1; i < tr.length; i++) {
                tds = tr[i].getElementsByTagName("td");
                var matches = false;
    
                for (j = 0; j < tds.length; j++) {
                    if (tds[j]) {
                        txtValue = tds[j].textContent || tds[j].innerText;
                        if (txtValue.toUpperCase().indexOf(filter) > -1) {
                            matches = true;
                        } 
                    }
                }
    
                if(matches == true)
                {
                    tr[i].style.display = "";
                }
                 else {
                        tr[i].style.display = "none";
                    }
    
                }
            }
    
    0 讨论(0)
  • 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);
    <input id="myInput" type="text" />
    <table id="myTable">
     <thead>
      <tr class="header">
        <th style="width:60%;">Name</th>
        <th style="width:40%;">Country</th>
      </tr>
     </thead>
     <tbody>
      <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>
     </tbody>
    </table>

    0 讨论(0)
提交回复
热议问题