Как выполнить поиск и фильтрацию в реальном времени в таблице 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 яблочный ряд должен исчезнуть, оставив только виноград. Я надеюсь, что это ясно.
и, если пользователь удалит некоторые или все свои запросы из текстового поля, я хотел бы, чтобы все строки, которые теперь соответствуют запросу, снова появились.
хотя я знаю, как удалить строку таблицы в 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 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 при покрытии вся таблица, (все td, tr в таблице), чистый 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>
спасибо @dfsq за очень полезный код!
Я сделал некоторые корректировки и, возможно, некоторые другие тоже. Я гарантировал, что вы можете искать несколько слов, не имея строгого соответствия.
пример строки:
- яблоки и груши
- яблоки и бананы
- яблоки и апельсины
- ...
вы можете найти "ap pe", и он распознает первую строку
Вы можете искать для "бананового яблока" и он узнал бы второй рядDemo: 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 plugin также является одной хорошей альтернативой для размещения функции поиска для 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>
Comments