Поиск по группам

Группировка опций в выпадающем списке в Slim Select опирается на стандартную HTML-конструкцию <optgroup>, при которой элементы объединяются в логические блоки с собственными заголовками. При включённом поиске фильтрация применяется не только к отдельным пунктам, но и к структуре групп, что влияет на то, какие секции остаются видимыми после ввода строки поиска.

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

HTML-разметка с группами формирует базовую структуру, на основе которой строится индекс поиска:

<select id="countries">
  <optgroup label="Европа">
    <option value="de">Германия</option>
    <option value="fr">Франция</option>
  </optgroup>
  <optgroup label="Азия">
    <option value="jp">Япония</option>
    <option value="cn">Китай</option>
  </optgroup>
</select>

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

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

Фильтрация запускается на событие изменения значения поискового поля. Для каждого ввода выполняется проход по всем опциям:

  • сравнение строки поиска с текстом option
  • проверка соответствия optgroup label (в зависимости от логики фильтрации)
  • принятие решения о видимости элемента

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

Индексация и производительность при работе с группами

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

  • список всех option хранится в памяти
  • DOM не перестраивается полностью при каждом вводе
  • изменяется только состояние видимости элементов

Это особенно важно при списках, содержащих сотни или тысячи элементов, распределённых по десяткам групп.

Настройка поведения поиска через searchFilter

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

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

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

  • код значения (value)
  • текст группы (optgroup label)
  • внешние метаданные, добавленные в dataset

Расширенная логика поиска по группам

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

new SlimSelect({
  select: '#countries',
  searchFilter: (option, search) => {
    const groupText = option.parent?.label || ''
    const text = option.text || ''

    return (
      text.toLowerCase().includes(search.toLowerCase()) ||
      groupText.toLowerCase().includes(search.toLowerCase())
    )
  }
})

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

Скрытие и восстановление групп

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

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

Особенности работы с Unicode и диакритикой

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

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

const normalize = (str) =>
  str.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase()

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

Комбинированные сценарии фильтрации

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

  • динамическая подгрузка опций
  • асинхронный поиск
  • фильтрация по нескольким полям данных

В таких случаях логика поиска расширяется до многокритериальной системы, где optgroup становится дополнительным параметром фильтрации, а не основным элементом структуры.

Пример комбинированной логики:

searchFilter: (option, search) => {
  const data = option.data || {}
  const text = option.text.toLowerCase()
  const group = (option.parent?.label || '').toLowerCase()
  const query = search.toLowerCase()

  return (
    text.includes(query) ||
    group.includes(query) ||
    (data.tags && data.tags.includes(query))
  )
}

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

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

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