如何在 HTML 表上执行实时搜索和过滤

我已经用 Google 搜索 Stack Overflow 有一段时间了,但是我就是无法解决这个问题。

我有一个标准的 HTML 表,包含,比如说,水果。像这样:

<table>
<tr>
<td>Apple</td>
<td>Green</td>
</tr>
<tr>
<td>Grapes</td>
<td>Green</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</table>

在此之上,我有一个文本框,我想搜索作为一个用户类型的表。因此,例如,如果他们键入 Gre,表中的 Orange 行将消失,留下 Apple 和 Grape。如果他们继续输入 Green Gr,苹果行应该消失,只留下葡萄。我希望你明白。

而且,如果用户从文本框中删除一些或全部查询,我希望现在匹配该查询的所有行都重新出现。

虽然我知道如何在 jQuery 中删除表行,但是对于如何基于此进行搜索和有选择地删除行却知之甚少。有简单的解决办法吗?或者插件?

如果有人能给我指明正确的方向,那就太好了。

谢谢你。

276110 次浏览

我创造了这些例子。

简单的 索引搜索

var $rows = $('#table tr');
$('#search').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();


$rows.show().filter(function() {
var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
return !~text.indexOf(val);
}).hide();
});

演示 : < a href = “ http://jsfiddle.net/7BUmG/2/”rel = “ noReferrer”> http://jsfiddle.net/7bumg/2/

正则表达式搜索

使用正则表达式的更高级功能将允许您按照行中的任何顺序搜索单词。如果你输入 apple greengreen apple,它的工作原理是一样的:

var $rows = $('#table tr');
$('#search').keyup(function() {


var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
reg = RegExp(val, 'i'),
text;


$rows.show().filter(function() {
text = $(this).text().replace(/\s+/g, ' ');
return !reg.test(text);
}).hide();
});

演示 : < a href = “ http://jsfiddle.net/dfsq/7BUmG/1133/”rel = “ noReferrer”> http://jsfiddle.net/dfsq/7bumg/1133/

Debounce

在实现对多个行和列进行搜索的表过滤时,考虑性能和搜索速度/优化非常重要。简单地说,你不应该运行搜索功能的每一个键击,这是没有必要的。为了防止过滤运行得太频繁,您应该去除它。以上代码示例将变为:

$('#search').keyup(debounce(function() {
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
// etc...
}, 300));

您可以选择任何一种去噪实现,例如从 Lodash 退出,或者您可以使用一些非常简单的东西,就像我在下一个演示中使用的那样(从 给你去噪) : http://jsfiddle.net/7BUmG/6230/http://jsfiddle.net/7BUmG/6231/

我有一个 jquery 插件。它也使用 jquery-ui。你可以在这里看到一个例子 Http://jsfiddle.net/tugrulorhan/fd8kb/1/

$("#searchContainer").gridSearch({
primaryAction: "search",
scrollDuration: 0,
searchBarAtBottom: false,
customScrollHeight: -35,
visible: {
before: true,
next: true,
filter: true,
unfilter: true
},
textVisible: {
before: true,
next: true,
filter: true,
unfilter: true
},
minCount: 2
});

我发现 dfsq 的回答非常有用。我做了一些适用于我的小修改(我把它张贴在这里,以防它对其他人有用)。

  1. 使用 class作为钩子,而不是表元素 tr
  2. 搜索/比较子 class中的文本,同时显示/隐藏父节点
  3. 通过仅将 $rows文本元素存储到一个数组中一次(并避免 $rows.length次计算) ,提高了效率

var $rows = $('.wrapper');
var rowsTextArray = [];


var i = 0;
$.each($rows, function () {
rowsTextArray[i] = ($(this).find('.number').text() + $(this).find('.fruit').text())
.replace(/\s+/g, '')
.toLowerCase();
i++;
});


$('#search').keyup(function() {
var val = $.trim($(this).val()).replace(/\s+/g, '').toLowerCase();
$rows.show().filter(function(index) {
return (rowsTextArray[index].indexOf(val) === -1);
}).hide();
});
span {
margin-right: 0.2em;
}
<input type="text" id="search" placeholder="type to search" />


<div class="wrapper"><span class="number">one</span><span class="fruit">apple</span></div>
<div class="wrapper"><span class="number">two</span><span class="fruit">banana</span></div>
<div class="wrapper"><span class="number">three</span><span class="fruit">cherry</span></div>
<div class="wrapper"><span class="number">four</span><span class="fruit">date</span></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

谢谢@dfsq 提供的非常有用的代码!

我做了一些调整,也许其他人也喜欢。我确保您可以搜索多个单词,而无需进行严格匹配。

示例行:

  • 苹果和梨
  • 苹果和香蕉
  • 苹果和橘子
  • ...

你可以搜索“ appe”,它会识别第一行
你可以搜索“香蕉苹果”,它会识别第二行

演示: Http://jsfiddle.net/jeroensormani/xhpkfwgd/1/

var $rows = $('#table tr');
$('#search').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase().split(' ');


$rows.hide().filter(function() {
var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
var matchesSearch = true;
$(val).each(function(index, value) {
matchesSearch = (!matchesSearch) ? false : ~text.indexOf(value);
});
return matchesSearch;
}).show();
});

可数据化 JS 插件 也是支持 html 表搜索特性的一个很好的替代品

var table = $('#example').DataTable();


// #myInput is a <input type="text"> element
$('#myInput').on( 'keyup', function () {
table.search( this.value ).draw();
} );

Https://datatables.net/examples/basic_init/zero_configuration.html

下面是在 HTML 表中搜索的最佳解决方案,同时涵盖 所有表格、(表中的所有 td、 tr)、 < em > 纯 javascript 和尽可能多的 短片:

<input id='myInput' onkeyup='searchTable()' type='text'>


<table id='myTable'>
<tr>
<td>Apple</td>
<td>Green</td>
</tr>
<tr>
<td>Grapes</td>
<td>Green</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</table>


<script>
function searchTable() {
var input, filter, found, table, tr, td, i, j;
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");
for (j = 0; j < td.length; j++) {
if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
found = true;
}
}
if (found) {
tr[i].style.display = "";
found = false;
} else {
tr[i].style.display = "none";
}
}
}
</script>

纯 Javascript 解决方案:

所有列和不区分大小写:工作

function search_table(){
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("search_field_input");
filter = input.value.toUpperCase();
table = document.getElementById("table_id");
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") ;
for(j=0 ; j<td.length ; j++)
{
let tdata = td[j] ;
if (tdata) {
if (tdata.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
break ;
} else {
tr[i].style.display = "none";
}
}
}
}
}

你可以像这样使用本地的 javascript

<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>

如果可以分离 html 和数据,那么可以使用外部库,比如数据表或我创建的那个

这个库使用 keyup 函数重新加载表数据,因此它的工作方式与搜索类似。

function _addTableDataRows(paramObjectTDR) {
let { filterNode, limitNode, bodyNode, countNode, paramObject } = paramObjectTDR;
let { dataRows, functionArray } = paramObject;
_clearNode(bodyNode);
if (typeof dataRows === `string`) {
bodyNode.insertAdjacentHTML(`beforeend`, dataRows);
} else {
let filterTerm;
if (filterNode) {
filterTerm = filterNode.value.toLowerCase();
}
let serialNumber = 0;
let limitNumber = 0;
let rowNode;
dataRows.forEach(currentRow => {
if (!filterNode || _filterData(filterTerm, currentRow)) {
serialNumber++;
if (!limitNode || limitNode.value === `all` || limitNode.value >= serialNumber) {
limitNumber++;
rowNode = _getNode(`tr`);
bodyNode.appendChild(rowNode);
_addData(rowNode, serialNumber, currentRow, `td`);
}
}
});
_clearNode(countNode);
countNode.insertAdjacentText(`beforeend`, `Showing 1 to ${limitNumber} of ${serialNumber} entries`);
}
if (functionArray) {
functionArray.forEach(currentObject => {
let { className, eventName, functionName } = currentObject;
_attachFunctionToClassNodes(className, eventName, functionName);
});
}
}