Событие search

Событие search в Choices.js вызывается в момент ввода текста пользователем в поле поиска внутри компонента выбора. Оно формируется каждый раз, когда изменяется строка запроса, и служит ключевой точкой расширения логики фильтрации, интеграции с удалёнными API и кастомной обработки пользовательского ввода.

Поведение события напрямую зависит от конфигурации экземпляра Choices. В базовом сценарии оно активируется при включённой опции поиска (searchEnabled: true) и сопровождается передачей текущего значения строки поиска, а также служебных данных, описывающих состояние инстанса.


Событие инициируется внутри внутреннего обработчика ввода. Каждый ввод символа в search-input приводит к пересчёту строки запроса и последующему вызову событийной системы.

Внутренне процесс можно описать следующим образом:

  • фиксируется значение input-поля;
  • нормализуется строка (в зависимости от настроек, например searchFloor, searchResultLimit);
  • выполняется фильтрация локального массива options (если не используется async-режим);
  • генерируется событие search;
  • передаются данные о текущем запросе и найденных результатах.

Структура данных события

Обработчик search получает объект события, содержащий контекст поиска:

  • value — текущая строка запроса;
  • resultCount — количество найденных элементов после фильтрации;
  • choices — массив текущих отфильтрованных значений;
  • instance — ссылка на текущий экземпляр Choices;
  • id — идентификатор компонента.

Пример структуры:

{
  value: "ap",
  resultCount: 3,
  choices: [
    { value: "apple", label: "Apple" },
    { value: "apricot", label: "Apricot" }
  ],
  instance: ChoicesInstance
}

Подключение обработчика

Подписка на событие выполняется через метод passedElement.element.addEventListener или через внутренний event API, предоставляемый экземпляром.

Пример базовой регистрации:

const element = document.querySelector('#select');

const choices = new Choices(element, {
  searchEnabled: true
});

element.addEventListener('search', (event) => {
  console.log('Поисковый запрос:', event.detail.value);
  console.log('Найдено элементов:', event.detail.resultCount);
});

В Choices.js событие часто проксируется через event.detail, где находится полезная нагрузка.


При использовании локального массива данных search тесно связан с механизмом встроенной фильтрации. Алгоритм сравнения строк зависит от следующих параметров:

  • searchEnabled — включает или отключает обработку;
  • searchFloor — минимальное количество символов для начала поиска;
  • searchResultLimit — ограничение числа возвращаемых совпадений;
  • fuseOptions — параметры fuzzy-поиска, если используется Fuse-алгоритм.

При каждом вводе символа происходит пересборка списка, и событие отражает уже обработанный результат.


Асинхронный режим и удалённый поиск

В сценариях с shouldSort: false и кастомной загрузкой данных событие search используется как триггер для обращения к API. В этом режиме Choices.js не выполняет фильтрацию самостоятельно, а лишь уведомляет внешний код о необходимости обновления данных.

Типичный паттерн интеграции:

const choices = new Choices('#select', {
  searchEnabled: true
});

const element = document.querySelector('#select');

element.addEventListener('search', async (event) => {
  const query = event.detail.value;

  const response = await fetch(`/api/items?q=${encodeURIComponent(query)}`);
  const data = await response.json();

  choices.clearChoices();
  choices.setChoices(data, 'value', 'label', true);
});

В этом сценарии search выступает как сигнал синхронизации между UI и серверной логикой.


Частота вызовов и оптимизация

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

Для снижения нагрузки применяется:

  • debounce (задержка обработки);
  • throttle (ограничение частоты вызовов);
  • кеширование предыдущих запросов.

Пример debounce-обработки:

let timeout;

element.addEventListener('search', (event) => {
  clearTimeout(timeout);

  timeout = setTimeout(() => {
    const query = event.detail.value;
    console.log('Запрос после задержки:', query);
  }, 300);
});

Взаимодействие с пользовательским вводом

Событие тесно связано с состоянием UI. При изменении строки поиска Choices.js одновременно:

  • обновляет выпадающий список;
  • изменяет состояние видимости опций;
  • управляет фокусом внутри dropdown;
  • пересчитывает highlighted-элементы.

Если список пуст, событие search всё равно вызывается, но resultCount становится равным нулю, что позволяет реализовать пользовательские сообщения о пустом результате.


Кастомизация поведения через search callback

Choices.js предоставляет возможность переопределить стандартную логику поиска через конфигурацию callbackOnSearch или через внешнюю фильтрацию данных.

Пример кастомного фильтра:

const choices = new Choices('#select', {
  searchEnabled: true,
  callbackOnSearch: (value, choices) => {
    return choices.filter(item =>
      item.label.toLowerCase().includes(value.toLowerCase())
    );
  }
});

В этом случае событие search отражает уже изменённую логику фильтрации.


Состояния и пограничные случаи

При обработке события важно учитывать ряд особенностей поведения:

  • пустая строка поиска возвращает полный список элементов;
  • ввод пробелов может интерпретироваться как валидный запрос;
  • при отключённом searchEnabled событие не генерируется;
  • при динамическом изменении options список пересчитывается заново, даже без ввода.

Также при программной установке значения через API (setValue, setChoiceByValue) событие search не вызывается, так как отсутствует пользовательский ввод.


Использование для аналитики и UX-логики

Событие часто применяется для:

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

Пример простого логирования:

element.addEventListener('search', (event) => {
  analytics.track('choices_search', {
    query: event.detail.value,
    results: event.detail.resultCount
  });
});

Взаимодействие с другими событиями Choices.js

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

  • change — фиксация выбора значения;
  • highlightItem — подсветка текущего элемента;
  • showDropdown — открытие списка;
  • hideDropdown — закрытие списка.

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


Ограничения и особенности реализации

Событие не предназначено для хранения состояния поиска — оно исключительно сигнальное. Любая долговременная логика должна быть вынесена во внешний слой приложения.

Также следует учитывать:

  • отсутствие гарантированной задержки между событиями;
  • зависимость от производительности DOM;
  • влияние сторонних плагинов, модифицирующих input-поле;
  • различия поведения между мобильными и десктопными браузерами.