Как выполнить поиск и фильтр в реальном времени в таблице HTML
Я некоторое время гуглил и искал переполнение стека, но я просто не могу обойти эту проблему.
у меня есть стандартная таблица 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
например, оранжевый ряд таблицы исчезнет, оставив Яблоко и виноград. Если они продолжат и напечатают Green Gr
строка яблока должна disapear, выходя только виноград. Надеюсь, это ясно.
и, если пользователь удалит некоторые или все свои запросы из текстового поля, я хотел бы, чтобы все строки, которые теперь соответствуют запросу, снова появились.
хотя я знаю, как удалить строку таблицы в jQuery, у меня мало идей о том, как выполнять поиск и выборочно удалять строки на основе этого. Есть ли простое решение? Или плагин?
Если бы кто-нибудь мог указать мне в правильном направлении, это было бы бриллиант.
спасибо.
8 ответов
Я создал эти примеры.
простой indexOf поиск
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();
});
демо: http://jsfiddle.net/7BUmG/2/
поиск регулярного выражения
расширенные функции с использованием регулярных выражений позволит вам искать слова в любом порядке в строке. Он будет работать так же, если вы наберете apple green
или green 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();
});
демо: http://jsfiddle.net/dfsq/7BUmG/1133/
Debounce
при реализации фильтрации таблиц с поиском по нескольким строкам и столбцам очень важно учитывать производительность и скорость поиска / оптимизацию. Просто говоря, что вы не должны запускать функцию поиска при каждом нажатии клавиши, это не обязательно. Чтобы предотвратить фильтрацию, чтобы работать слишком часто, вы должны ее разоблачить. Выше пример кода станет:
$('#search').keyup(debounce(function() {
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
// etc...
}, 300));
вы можете выбрать любой debounce реализации, например, от Lodash _.debounce, или вы можете использовать что-то очень простое, как я использую в следующих демонстрациях (debounce from здесь): 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
});
вот лучшее решение для поиска внутри таблицы HTML при покрытии весь стол (все тд, ТР в таблице), чистый javascript и short как можно:
<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>
спасибо @dfsq за очень полезный код!
Я сделал некоторые корректировки и, возможно, некоторые другие тоже. Я гарантировал, что вы можете искать несколько слов, не имея строгого соответствия.
пример строки:
- яблоки и груши
- яблоки и бананы
- яблоки и апельсины
- ...
вы можете найти "ap pe", и он распознает первую строку
Вы можете искать для "бананового яблока" и он узнал бы второй ряд
демо: 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();
});
я нашел ответ dfsq его комментарии чрезвычайно полезными. Я сделал некоторые незначительные изменения, применимые ко мне (и я размещаю его здесь, если он может быть полезен другим).
- используя
class
как крючки, а не элементы таблицыtr
- Поиск/сравнение текста в детей
class
при показе / скрытии родителя - что делает его более эффективным, сохраняя
$rows
текстовые элементы в массив только один раз (и избегая$rows.length
раз вычисление)
var $rows = $('.wrapper');
var rowsTextArray = [];
var i = 0;
$.each($rows, function() {
rowsTextArray[i] = $(this).find('.fruit').text().replace(/\s+/g, ' ').toLowerCase();
i++;
});
$('#search').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/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>
объект DataTable с JS плагин также является одной хорошей альтернативой для accomedate функции поиска для таблицы 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
Чистое Решение 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>