Фильтрация списка на основе пользовательского ввода с помощью jQuery - PullRequest
2 голосов
/ 09 сентября 2009

У меня есть список песен, и я хочу, чтобы пользователи могли фильтровать их, введя текстовое поле. Вот что я делаю сейчас:

  $("#filter_song_list").keyup(function() {
    var filter = new RegExp($(this).val(), "i");

    $("ul.song_list a").each(function(){
      if (!$(this).text().match(filter)) {
        $(this).hide();
      } else {
        $(this).show();
      }
    });
  });
  1. Это правильный подход?
  2. Так как я интерпретирую ввод пользователя как регулярное выражение, он не может искать песни с (скажем) точкой в ​​названии без предварительного экранирования ("."). Как я могу это исправить, при этом сохраняя регистронезависимость поиска?

Ответы [ 3 ]

2 голосов
/ 09 сентября 2009

Вырвите свое регулярное выражение перед его выполнением :

var pattern = $(this).val().replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
var filter = new RegExp(pattern , "i");

Однако вы просто делаете поиск строки внутри строки без учета регистра. Вам не нужны регулярные выражения для этого. @ ответ mkoryak больше подходит для вас IMO.

Я бы сказал, что встроенный в jQuery селектор pseedo contains идеально подходит для вас, но он чувствителен к регистру.

2 голосов
/ 10 сентября 2009

Прежде всего, сделайте кэшированную ссылку на ваши элементы, чтобы ускорить процесс:

var cache = $("ul.song_list a");

Затем выполните простое сопоставление строк, используя функцию jQuery filter() и hide() сопоставленные элементы:

cache.filter(function ()
{
    return $(this).text().toLower().indexOf( <value from input> ) < 1;
}).hide();

Финальный фрагмент кода:

$(function ()
{
    var cache = $("ul.song_list a");

    $("#filter_song_list").keyup(function ()
    {
        var val = $(this).val();

        cache.filter(function ()
        {
            return $(this).text().toLower().indexOf(val) < 1;
        })
        .hide();
    });
});
2 голосов
/ 09 сентября 2009

Самый простой способ сделать то, что вы просите (не лучше по производительности, чем ваше решение):

изменить фильтр на ввод пользователя, а не на регулярное выражение.

изменить строку фильтрации на:

if ($(this).text().toLowerCase().indexOf($.trim(filter.toLowerCase())) > -1) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...