Javascript 过滤表多列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43622127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Filtering table multiple columns
提问by Rolandas Vizbara
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>
回答by Rob M.
There are significantly betterresources on the web than W3 Schools, you really should avoid that website IMO. That being said, you just need to look at trrather than one of the tds if you want to match the whole row:
有显著更好的网络比W3学校的资源,你真的应该避免网站海事组织。话虽如此,如果您想匹配整行,您只需要查看str而不是其中之一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 innerHTMLand should instead use textContentsince 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. filterTableinstead of myFunction). Additionally, there are easier ways to access table data (e.g. tr.cells). If you add a keyupevent listener to #myInputyou will not need to lookup that DOM node everytime the function is called. Here is an example:
本教程不是很好的一些原因:您应该避免使用innerHTML而应该使用,textContent因为您的单元格可能包含 HTML,并且用户在尝试搜索可见文本时可能会键入标签名称并被匹配的内容混淆。你应该给你的函数命名以表明它们的作用(例如,filterTable而不是myFunction)。此外,还有更简单的方法来访问表数据(例如tr.cells)。如果向其中添加keyup事件侦听器,#myInput则每次调用该函数时都不需要查找该 DOM 节点。下面是一个例子:
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>
回答by Mr Oscar
Add this JQuery in the head tag of the file. The #myinputis the id search box which is an input element of type text.
The #tab-idis the id of the tbody, so you should explicitly divide the table into thead and tbody
将此 JQuery 添加到文件的 head 标记中。的#myinput是id搜索框,其是类型文本的输入元件。该#tab-id是TBODY的ID,所以你应该明确地划分表入里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>
回答by RobG
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";
}
}
}
}
回答by Magda Poppins
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 设置彼此之后的条件,它们都将在过滤器中被考虑在内!
回答by PARTHI RAMESH
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我!
回答by Scott King
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";
}
}
}
}
回答by Nadeem
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";
}
}
}
回答by Nam Le
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>

