简体   繁体   English

过滤表多列

[英]Filtering table multiple columns

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.我为我的页面使用了 w3School 代码,它工作正常,但它只过滤一列,不知道如何创建循环,但跳到那里是更简单的解决方案。

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

changing here 0 to 1 changes the column, could find anything so tried many different thing but not the programmer have no idea if there any other properties that allows multiple columns, spent so much searching, please help在这里将 0 更改为 1 更改了列,可以找到任何尝试过很多不同的东西,但程序员不知道是否还有其他允许多列的属性,花了很多时间搜索,请帮助

 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"; } } } }
 * { box-sizing: border-box; } #myInput { background-image: url('/css/searchicon.png'); background-position: 10px 10px; background-repeat: no-repeat; width: 100%; font-size: 16px; padding: 12px 20px 12px 40px; border: 1px solid #ddd; margin-bottom: 12px; } #myTable { border-collapse: collapse; width: 100%; border: 1px solid #ddd; font-size: 18px; } #myTable th, #myTable td { text-align: left; padding: 12px; } #myTable tr { border-bottom: 1px solid #ddd; } #myTable tr.header, #myTable tr:hover { background-color: #f1f1f1; }
 <h2>My Customers</h2> <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>

There are significantly better resources on the web than W3 Schools, you really should avoid that website IMO.网络上有比 W3 Schools 更好的资源,您真的应该避免使用该网站 IMO。 That being said, you just need to look at tr rather than one of the td s if you want to match the whole row:话虽如此,如果您想匹配整行,您只需要查看tr而不是td之一:

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:如果要过滤多列而不是整行,只需在条件中使用 OR ( || ):

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.本教程不是很好的一些原因:您应该避免使用innerHTML而应该使用textContent因为您的单元格可能包含 HTML 并且用户在尝试搜索可见文本时可能会输入标签名称并被什么内容混淆匹配。 You should give your functions names that indicate what they do (eg filterTable instead of myFunction ).您应该为您的函数命名以表明它们的作用(例如filterTable而不是myFunction )。 Additionally, there are easier ways to access table data (eg tr.cells ).此外,还有更简单的方法来访问表数据(例如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.如果您向#myInput添加一个keyup事件侦听器,您将不需要在每次调用该函数时查找该 DOM 节点。 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>

Adding ||添加 || and adding the new condition under if statements totally worked.并在 if 语句下添加新条件完全有效。

 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"; } } } }
 * { box-sizing: border-box; } #myInput { background-image: url('/css/searchicon.png'); background-position: 10px 10px; background-repeat: no-repeat; width: 100%; font-size: 16px; padding: 12px 20px 12px 40px; border: 1px solid #ddd; margin-bottom: 12px; } #myTable { border-collapse: collapse; width: 100%; border: 1px solid #ddd; font-size: 18px; } #myTable th, #myTable td { text-align: left; padding: 12px; } #myTable tr { border-bottom: 1px solid #ddd; } #myTable tr.header, #myTable tr:hover { background-color: #f1f1f1; }
 <h2>My Customers</h2> <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>

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";
      }
    }
  }
}

Add this JQuery in the head tag of the file.将此 JQuery 添加到文件的 head 标记中。 The #myinput is the id search box which is an input element of type text. #myinput是 id 搜索框,它是文本类型的输入元素。 The #tab-id is the id of the tbody, so you should explicitly divide the table into thead and tbody #tab-id是 tbody 的 id,所以你应该明确地将 table 划分为 thead 和 tbody

<script>
    $(document).ready(function(){
        $("#myInput").on("keyup", function() {
            var value = $(this).val().toLowerCase();
            $("#tab-id tr").filter(function() {
                $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
            });
        });
    });
</script>

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应该是tr[i].textContent

Your code is fine.你的代码没问题。 To add multiple columns you need to add ||要添加多列,您需要添加|| condition (in if clause).条件(在if子句中)。

The problem with Rob's answer is it will filter out table headings if you use tr . Rob 的答案的问题是,如果您使用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";
      }
    }
  }
} 

Based on probably the same tutorial that you followed, to take in three different text inputs and sort all 's in the row accordingly:基于您遵循的可能相同的教程,接收三个不同的文本输入并相应地对行中的所有 's 进行排序:

 function SortByMultiple() { //Declare needed variables var dateInput, nameInput, locationInput, dateFilter, nameFilter, locationFilter, table, tr, tdN, tdD, tdL, i; //Set inputs by getElementById nameInput = document.getElementById('nameInput'); dateInput = document.getElementById('dateInput'); locationInput = document.getElementById('locationInput'); //Set filters nameFilter = nameInput.value.toUpperCase(); dateFilter = dateInput.value.toUpperCase(); locationFilter = locationInput.value.toUpperCase(); //Set the table and tr variables table = document.getElementById("UL"); tr = document.getElementsByTagName("tr"); //Loop through items and hide those that don't match the query --> for (i = 0; i < tr.length; i++) { //Name is at index 0 tdN = tr[i].getElementsByTagName("td")[0]; //Date is at index 2 tdD = tr[i].getElementsByTagName("td")[2]; //Location is at index 1 tdL = tr[i].getElementsByTagName("td")[1]; if (tdN.innerHTML.toUpperCase().indexOf(nameFilter) > -1 && tdD.innerHTML.toUpperCase().indexOf(dateFilter) > -1 && tdL.innerHTML.toUpperCase().indexOf(locationFilter) > -1) { tr[i].style.display = ""; } else { tr[i].style.display = "none"; } } }

By setting the conditions after each others with AND they will all be taken into account in the filter!通过使用 AND 设置彼此之后的条件,它们都将在过滤器中被考虑在内!

This solution is for multi column filter with multiple values此解决方案适用于具有多个值的多列过滤器

The empty text boxes is to type your value to filter空文本框是输入您要过滤的值

Class name for all the text boxes are '.filter_rep'所有文本框的类名都是“.filter_rep”

  $(document).on('keyup','.filter_rep',function () {
    var $this = $(this).val();
    var val_array = [];
    var id_array = [];

    $('.filter_rep').each(function () {
        thisval = $(this).val();
        id = '.'+$(this).attr('id');
        if (thisval){
            id_array.push(id);
            val_array.push(thisval);
        }
    });
    // using val_array to check all the columns and hide
    if(val_array.length > 0){
        $('tr').each(function () {
            $(this).show();
        });
        for (i=0;i<val_array.length;i++){
            $(id_array[i]).each(function () {
                if (!($(this).text().toLowerCase().indexOf(val_array[i]) > -1)){
                    $(this).parent().hide();
                }
            });
        }
    }else{
        $('tr').each(function () {
          $(this).show();
        });
    }
})

}); });

If any clarifications ping me!如果有任何澄清ping我!

I just used the same W3 code that you started with, and I found this fairly elegant solution -- which should work for large numbers of columns我只是使用了与您开始时相同的 W3 代码,我发现了这个相当优雅的解决方案——它应该适用于大量列

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

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";
                }

            }
        }

Enhanced Rob.M's answer to suit multi-column search with below code.使用以下代码增强 Rob.M 的答案以适应多列搜索。

function filterTable(event) {
//Convert search value to uppercase and assign the value to variable 'filter'
var filter = event.target.value.toUpperCase();
//Find total rows in the table's body
var rows = document.querySelector("#table tbody").rows;
//Start looping rows
for (var i = 0; i < rows.length; i++) {
    //Count the columns in current row
    var colCount = $("#table th").length;
    //Assign a variable 'res' for result counting
    var res = 1;
    //Start looping columns in current row
    for (let j = 0; j < colCount; j++) {
        //Iterate single cell and convert the contents to uppercase, assign the content to variable 'x'
        var x = "col_" + j;
        var x = rows[i].cells[j].textContent.toUpperCase();
        //find the position of first index of the search value.
        //If search value found ADD 1 to 'res' else LESS 1
        x.indexOf(filter) > -1 ? res++ : res--;
    }
    //Convert the colCount variable to absolute value
    colCount = -Math.abs(colCount - 1);
    //Display or hide the row, based on result condition
    res > colCount || filter == "" ? (rows[i].style.display = "") : (rows[i].style.display = "none");
}

} }

I uploaded the code here to search table data among two columns我在这里上传代码以在两列之间搜索表数据

 function searching() { var input, filter, table, tr, td1, td2, i, txtValue; input = document.getElementById("search"); filter = input.value.toUpperCase(); table = document.getElementById("table"); tr = table.getElementsByTagName("tr"); for (i = 0; i < tr.length; i++) { td1 = tr[i].getElementsByTagName("td")[0]; td2 = tr[i].getElementsByTagName("td")[1]; if (td1 || td2) { txtValue1 = td1.textContent || td1.innerText; txtValue2 = td2.textContent || td2.innerText; if (txtValue1.toUpperCase().indexOf(filter) > -1 || (txtValue2.toUpperCase().indexOf(filter) > -1)) { tr[i].style.display = ""; } else { tr[i].style.display = "none"; } } } } <input class="form-control my-3" id="search" onkeyup="searching()" type="search" placeholder="Search To-Do items here..." aria-label="Search"> <table class="table my-5"> <thead class="thead-dark"> <tr> <th scope="col ">Sr No.</th> <th scope="col ">Item</th> <th scope="col ">Description</th> <th scope="col ">Manage</th> </tr> </thead> <tbody id="table"> </tbody> </table>

 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>

Borrowing code from this post I am able to filter on 2 columns using the ||从这篇文章中借用代码,我可以使用 || 对 2 列进行过滤(Or) operator. (或)运算符。 However, I'd like to be able to filter using the && (And) operator.但是,我希望能够使用 && (And) 运算符进行过滤。

I have been unsuccessful in my multiple attempts.我多次尝试都没有成功。 I could use some help.我可以使用一些帮助。

<script>
function myFunction() {
  var input0, input1, filter0, filter1, table, tr, td, cell, i, j;
  document.getElementById("myInput0").value = 'Female';
  document.getElementById("myInput1").value = 'Engineering';
  input0 = document.getElementById("myInput0");
  input1 = document.getElementById("myInput1");
  filter0 = input0.value.toUpperCase();
  filter1 = input1.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.textContent.toUpperCase().indexOf(filter0)>-1 || 
    cell.textContent.toUpperCase().indexOf(filter1)>-1) {
          tr[i].style.display = "";
          break;
        } 
      }
    }
  }
}
</script>

<body>
<input type="text" id="myInput0">
<input type="text" id="myInput1">
<input type='button' onclick='myFunction()' value='click me' />

<table id="myTable">
  <thead>
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
    <th>Gender</th>
    <th>Department</th>
  </tr>
  </thead>
  <tbody>
  <tr>
    <td>John</td>
    <td>Doe</td>
    <td>Male</td>
    <td>Sales</td>
  </tr>
  <tr>
    <td>Mary</td>
    <td>Moe</td>
    <td>Female</td>
    <td>Service</td>
  </tr>
  <tr>
    <td>July</td>
    <td>Dooley</td>
    <td>Female</td>
    <td>Service</td>
  </tr>
  <tr>
    <td>Anja</td>
    <td>Ravendale</td>
    <td>Female</td>
    <td>Engineering</td>
  </tr>
  <tr>
    <td>Thomas</td>
    <td>Dubois</td>
    <td>Male</td>
    <td>Sales</td>
  </tr>
  <tr>
    <td>Deidre</td>
    <td>Masters</td>
    <td>Female</td>
    <td>Sales</td>
  </tr>
  <tr>
    <td>Sean</td>
    <td>Franken</td>
    <td>Male</td>
    <td>Engineering</td>
  </tr>
  </tbody>
</table>

</body>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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