Включение поиска

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

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


Механизм работы поиска

Внутренне Slim Select использует строковое сопоставление введённого текста с полями элементов списка. При вводе пользовательского запроса происходит:

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

По умолчанию поиск выполняется по текстовому содержимому option, но может быть расширен через кастомные функции фильтрации.


Базовое включение поиска

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

new SlimSelect({
  select: '#countries'
});

В данном случае поиск будет доступен автоматически, если компонент считает список достаточно большим.


Явное управление поиском

Для управления поиском используется параметр search. Он позволяет включать или отключать функциональность.

Отключение поиска

new SlimSelect({
  select: '#countries',
  search: false
});

В этом режиме поле ввода внутри dropdown не отображается, а пользователь может только прокручивать список.


Включение поиска принудительно

new SlimSelect({
  select: '#countries',
  search: true
});

Такой вариант полезен, если список небольшой, но требуется единый UX для всех селектов.


Настройка поведения поискового поля

Slim Select позволяет управлять отображением и текстами интерфейса поиска.

Placeholder для поиска

new SlimSelect({
  select: '#countries',
  searchPlaceholder: 'Введите название страны'
});

Этот параметр изменяет текст внутри input-поля поиска.


Текст при отсутствии результатов

new SlimSelect({
  select: '#countries',
  searchText: 'Совпадений не найдено'
});

Используется при фильтрации, если ни один элемент не соответствует запросу.


Кастомизация логики поиска

Стандартный поиск можно переопределить через функцию фильтрации. Это позволяет реализовать:

  • поиск по нескольким полям;
  • поиск по идентификаторам;
  • нечёткое сравнение (fuzzy search);
  • поддержку транслитерации.

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

new SlimSelect({
  select: '#countries',
  searchFilter: (option, search) => {
    const text = option.text.toLowerCase();
    const query = search.toLowerCase();

    return text.includes(query);
  }
});

Поиск по нескольким полям данных

new SlimSelect({
  select: '#users',
  searchFilter: (option, search) => {
    const query = search.toLowerCase();

    return (
      option.text.toLowerCase().includes(query) ||
      option.value.toLowerCase().includes(query)
    );
  }
});

Поиск в больших списках

При работе с тысячами элементов стандартный поиск может стать узким местом производительности. Основные проблемы:

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

Оптимизация через debounce

let timeout;

new SlimSelect({
  select: '#bigList',
  searchFilter: (option, search) => {
    clearTimeout(timeout);

    return new Promise(resolve => {
      timeout = setTimeout(() => {
        resolve(option.text.toLowerCase().includes(search.toLowerCase()));
      }, 50);
    });
  }
});

Асинхронный поиск

В случаях, когда данные приходят с сервера, используется внешний источник поиска. Slim Select не ограничивает архитектуру и позволяет обновлять список динамически.

Пример загрузки данных при поиске

const slim = new SlimSelect({
  select: '#remoteSelect',
  search: true,
  placeholder: 'Поиск...'
});

async function searchData(query) {
  const response = await fetch(`/api/search?q=${query}`);
  const data = await response.json();

  slim.setData(
    data.map(item => ({
      text: item.name,
      value: item.id
    }))
  );
}

let timer;

document.querySelector('#remoteSelect').addEventListener('input', (e) => {
  clearTimeout(timer);

  timer = setTimeout(() => {
    searchData(e.target.value);
  }, 300);
});

Такой подход снижает нагрузку на сервер и предотвращает избыточные запросы.


Работа с чувствительностью к регистру

Поиск по умолчанию не всегда учитывает локальные особенности текста. Для улучшения качества фильтрации используется нормализация строк.

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

new SlimSelect({
  select: '#cities',
  searchFilter: (option, search) => {
    return normalize(option.text).includes(normalize(search));
  }
});

Поиск по вложенным данным

При использовании сложных структур данных элементы могут содержать дополнительные поля:

new SlimSelect({
  select: '#products',
  searchFilter: (option, search) => {
    const data = option.data || {};

    return (
      data.title?.toLowerCase().includes(search.toLowerCase()) ||
      data.category?.toLowerCase().includes(search.toLowerCase())
    );
  }
});

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

Если строка поиска пуста, Slim Select отображает весь список. Это поведение можно изменить:

new SlimSelect({
  select: '#items',
  searchFilter: (option, search) => {
    if (!search) return false;
    return option.text.toLowerCase().includes(search.toLowerCase());
  }
});

Управление фокусом и UX поиска

При открытии dropdown фокус автоматически устанавливается в поле поиска, что позволяет сразу вводить текст.

Дополнительно можно управлять этим поведением через события:

new SlimSelect({
  select: '#countries',
  onOpen: () => {
    console.log('Dropdown открыт');
  },
  onClose: () => {
    console.log('Dropdown закрыт');
  }
});

Ограничения встроенного поиска

Несмотря на гибкость, встроенный поиск имеет ряд особенностей:

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

Практические сценарии использования

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

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