Некоторое время я гуглил и искал переполнение стека, но я просто не могу обойти эту проблему.
У меня есть стандартная таблица 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
например, оранжевая строка таблицы исчезнет, оставив Apple и Grapes. Если они продолжат и напечатают, Green Gr
строка Apple должна исчезнуть, оставив только виноград. Надеюсь, это понятно.
И, если пользователь удалит часть или весь свой запрос из текстового поля, я хотел бы, чтобы все строки, которые теперь соответствуют запросу, снова появились.
Хотя я знаю, как удалить строку таблицы в jQuery, я мало знаю, как выполнять поиск и выборочно удалять строки на основе этого. Есть ли простое решение этой проблемы? Или плагин?
Если бы кто-нибудь мог указать мне правильное направление, это было бы замечательно.
Спасибо.
источник
Ответы:
Я создал эти примеры.
Простой 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));
Вы можете выбрать любую реализацию отладки , например, из Lodash _.debounce , или вы можете использовать что-то очень простое, как я использую в следующих демонстрациях ( отсюда отладка ): http://jsfiddle.net/7BUmG/6230/ и http: / /jsfiddle.net/7BUmG/6231/ .
источник
#table
наid
мою таблицу? Потребуются дополнительные изменения в работе с<thead>
и<tbody>
тегах? Я включил скрипт и html из ссылки jsfiddle, изменив#id
, но не получаю фильтрации.<tbody>
вы должны изменить наvar $rows = $('#id-of-your-table tbody tr');
.<tr>
DOMElement и строку. Таким образом,keyup()
вы будете искать эти строки (что намного быстрее) и подготовить соответствующие строки для обработки. Эта первая дорогостоящая процедура настройки должна быть выполнена только один раз сразу после загрузки. Все эти изменения - всего лишь мелкие исправления, фактическая центральная часть по-прежнему остается такой, как показано в этом ответе. Этот подход также возможен и довольно прост в реализации без jQuery.$('#table tr:not(:first)')
селектор.у меня есть плагин 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 на свои комментарии чрезвычайно полезным. Я внес некоторые незначительные изменения, применимые ко мне (и размещаю их здесь, на случай, если они пригодятся другим).
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>
источник
Спасибо @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(); });
источник
var $rows = $('#WorldPlayersTable tr');
var $rows = $('#WorldPlayersTable tbody tr');
Чистое решение 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>
источник
Плагин Datatable 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 и данные, вы можете использовать внешние библиотеки, такие как таблицы данных или ту, которую я создал. https://github.com/thehitechpanky/js-bootstrap-tables
Эта библиотека использует функцию нажатия клавиш для перезагрузки табличных данных и, следовательно, похоже, работает как поиск.
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); }); } }
источник