Параметр filter

filter в Awesomplete определяет логику отбора элементов из исходного списка перед отображением выпадающих подсказок. Это ключевой механизм, отвечающий за то, какие значения считаются релевантными текущему вводу пользователя.

Назначение параметра

Основная задача параметра filter — контроль соответствия элементов списка введённому тексту. По умолчанию библиотека использует простую стратегию поиска подстроки, но поведение может быть полностью переопределено.

Ключевые функции параметра:

  • определение релевантности элементов списка;
  • управление логикой поиска;
  • кастомизация поведения автодополнения;
  • реализация сложных алгоритмов фильтрации (по словам, префиксам, токенам, регистру и т.д.).

Сигнатура и структура

Параметр задаётся как функция:

filter: function(text, input) {
    return Boolean;
}

Где:

  • text — значение элемента списка (строка или преобразованный label);
  • input — текущее значение поля ввода;
  • return Boolean — результат проверки (true — элемент отображается, false — исключается).

Стандартное поведение

В базовой конфигурации Awesomplete используется фильтр, основанный на поиске подстроки:

function defaultFilter(text, input) {
    return RegExp(input.trim(), "i").test(text);
}

Особенности стандартного фильтра:

  • нечувствительность к регистру;
  • простое регулярное выражение;
  • совпадение по любой части строки;
  • отсутствие анализа слов или токенов.

Внутренний механизм работы фильтрации

Процесс фильтрации проходит в несколько этапов:

  1. Получение исходного списка элементов.
  2. Приведение каждого элемента к строковому виду.
  3. Передача каждого элемента в функцию filter.
  4. Формирование нового массива совпадений.
  5. Отображение результатов в выпадающем списке.

Фильтрация выполняется синхронно при каждом изменении input-события, что делает её критичной с точки зрения производительности.


Кастомная реализация фильтра

Переопределение filter позволяет реализовать любую логику сравнения.

Пример: строгий префиксный поиск

new Awesomplete(input, {
    list: ["Apple", "Apricot", "Banana", "Blueberry"],
    filter: function(text, input) {
        return text.toLowerCase().startsWith(input.toLowerCase());
    }
});

В этом случае совпадение происходит только если строка начинается с введённого текста.


Пример: поиск по словам

filter: function(text, input) {
    const words = input.toLowerCase().split(/\s+/);
    const target = text.toLowerCase();

    return words.every(word => target.includes(word));
}

Здесь реализована логика, при которой все слова ввода должны присутствовать в элементе списка, независимо от порядка.


Пример: фильтрация по токенам (точное совпадение слов)

filter: function(text, input) {
    const inputTokens = input.toLowerCase().split(/\s+/);
    const textTokens = text.toLowerCase().split(/\s+/);

    return inputTokens.every(t => textTokens.includes(t));
}

Такой подход используется при необходимости строгого совпадения по набору слов.


Работа с регистром

Регистронезависимость реализуется вручную внутри filter, поскольку Awesomplete не навязывает единую стратегию сравнения.

filter: function(text, input) {
    return text.toLowerCase().includes(input.toLowerCase());
}

Типовые стратегии:

  • приведение к lowerCase;
  • использование localeCompare;
  • нормализация строк перед сравнением.

Поддержка диакритики и нормализация текста

Для языков с диакритическими знаками часто требуется нормализация:

function normalize(str) {
    return str
        .toLowerCase()
        .normalize("NFD")
        .replace(/[\u0300-\u036f]/g, "");
}

filter: function(text, input) {
    return normalize(text).includes(normalize(input));
}

Эффект:

  • “café” совпадает с “cafe”;
  • “naïve” совпадает с “naive”.

Фильтрация с учётом производительности

Поскольку filter вызывается при каждом вводе символа, важно учитывать стоимость операций:

Рекомендации по оптимизации логики:

  • избегать сложных регулярных выражений внутри filter;
  • минимизировать создание новых объектов;
  • кешировать нормализованные значения при возможности;
  • использовать простые проверки includes вместо regex.

Интеграция с кастомными объектами списка

Awesomplete поддерживает не только строки, но и объекты:

list: [
    { label: "Apple", value: "apple" },
    { label: "Banana", value: "banana" }
]

В этом случае filter должен учитывать структуру данных:

filter: function(item, input) {
    return item.label.toLowerCase().includes(input.toLowerCase());
}

Поведение при частичных совпадениях

Фильтр определяет, будут ли отображаться:

  • частичные совпадения;
  • полные совпадения;
  • совпадения по началу строки;
  • совпадения по любым словам.

Пример частичного поиска:

filter: function(text, input) {
    return text.indexOf(input) !== -1;
}

Комбинирование фильтра с другими параметрами

filter часто используется совместно с:

  • sort — для упорядочивания результатов после отбора;
  • item — для кастомного отображения;
  • replace — для управления вставкой выбранного значения.

Типовой сценарий:

  1. filter отбирает кандидатов;
  2. sort упорядочивает;
  3. item формирует визуальное представление;
  4. replace подставляет значение в input.

Расширенные стратегии фильтрации

Фаззи-поиск

filter: function(text, input) {
    let ti = 0;

    for (let i = 0; i < text.length && ti < input.length; i++) {
        if (text[i].toLowerCase() === input[ti].toLowerCase()) {
            ti++;
        }
    }

    return ti === input.length;
}

Такой подход позволяет находить совпадения даже при неполном или неточном вводе.


Ограничение по длине ввода

filter: function(text, input) {
    if (input.length < 2) return false;
    return text.toLowerCase().includes(input.toLowerCase());
}

Используется для уменьшения количества результатов при коротком вводе.


Типичные ошибки при реализации filter

  • отсутствие нормализации регистра;
  • использование тяжёлых регулярных выражений;
  • создание новых массивов на каждом вызове без необходимости;
  • игнорирование структуры объектов списка;
  • отсутствие контроля пустого input.

Поведение при пустом вводе

Awesomplete по умолчанию может отображать весь список или скрывать его в зависимости от конфигурации. filter может полностью изменить это поведение:

filter: function(text, input) {
    return input.trim().length > 0 && text.includes(input);
}

Итоговая роль параметра в архитектуре Awesomplete

filter является центральным элементом логики автодополнения, определяющим базовую семантику поиска. Именно он задаёт границу между релевантными и нерелевантными элементами до применения сортировки и отображения, формируя основу пользовательского опыта взаимодействия с подсказками.