Как выполнить поиск и фильтр в реальном времени в таблице 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 его комментарии чрезвычайно полезными. Я сделал некоторые незначительные изменения, применимые ко мне (и я размещаю его здесь, если он может быть полезен другим).

  1. используя class как крючки, а не элементы таблицы tr
  2. Поиск/сравнение текста в детей class при показе / скрытии родителя
  3. что делает его более эффективным, сохраняя $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>