Инициализация множественного select

Множественный выбор в HTML-элементах <sel ect multiple> в библиотеке Choices.js строится вокруг расширения стандартного поведения нативного селекта и превращения его в управляемый компонент с тегами, поиском и API-методами управления состоянием.

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


Подготовка HTML-разметки

Базовая структура для множественного выбора опирается на атрибут multiple, без которого Choices.js не активирует режим мультиселекта.

<select id="cities" multiple>
  <option value="msk">Москва</option>
  <option value="spb">Санкт-Петербург</option>
  <option value="nsk">Новосибирск</option>
  <option value="ekb">Екатеринбург</option>
</select>

Ключевым моментом является именно наличие multiple, так как библиотека определяет режим работы на этапе инициализации.


Базовая инициализация множественного выбора

Подключение экземпляра Choices.js к множественному селекту выполняется через конструктор Choices.

import Choices fr om 'choices.js';

const element = document.getElementById('cities');

const choices = new Choices(element);

При такой инициализации библиотека автоматически:

  • скрывает нативный интерфейс select
  • создаёт кастомный контейнер
  • преобразует выбранные значения в теги
  • добавляет поле поиска (если не отключено)

Явное включение режима множественного выбора

Хотя multiple в HTML является основным триггером, поведение можно дополнительно контролировать через параметры конфигурации.

const choices = new Choices('#cities', {
  removeItemButton: true,
  searchEnabled: true,
  shouldSort: false
});

Параметры, критически влияющие на UX множественного выбора:

  • removeItemButton — добавляет кнопку удаления у каждого тега
  • searchEnabled — включает поиск по списку
  • shouldSort — отключает автоматическую сортировку выбранных элементов

Внутреннее представление выбранных значений

В режиме multiple Choices.js хранит состояние в виде массива значений. Каждый выбранный элемент соответствует одному option.

Пример внутреннего состояния:

[
  { value: 'msk', label: 'Москва', selected: true },
  { value: 'spb', label: 'Санкт-Петербург', selected: true }
]

Синхронизация происходит автоматически между:

  • DOM <select>
  • внутренним store Choices
  • визуальными тегами

Предустановленные значения

Для множественного select можно задавать выбранные элементы через HTML:

<select id="cities" multiple>
  <option value="msk" selected>Москва</option>
  <option value="spb">Санкт-Петербург</option>
  <option value="nsk" selected>Новосибирск</option>
</select>

Choices.js при инициализации считывает selected и сразу формирует соответствующие теги.

Альтернативный способ — программная установка:

const choices = new Choices('#cities');

choices.setChoiceByValue(['msk', 'nsk']);

Метод setChoiceByValue полностью заменяет текущее состояние выбора.


Добавление элементов программно

В множественном режиме часто требуется динамическое расширение списка.

choices.setChoices([
  { value: 'kzn', label: 'Казань', selected: false },
  { value: 'sochi', label: 'Сочи', selected: false }
], 'value', 'label', false);

Четвёртый параметр управляет тем, будут ли новые элементы сразу выбраны.

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

choices.setChoiceByValue('kzn');

Удаление выбранных значений

Удаление элементов осуществляется через API или пользовательский интерфейс.

Программное удаление:

choices.removeActiveItemsByValue('msk');

Удаление всех выбранных значений:

choices.removeActiveItems();

В множественном режиме это особенно важно при реализации фильтров и сброса формы.


Ограничение количества выбранных элементов

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

const choices = new Choices('#cities', {
  maxItemCount: 3
});

Поведение при достижении лимита:

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

Отключение повторного выбора

Choices.js автоматически предотвращает повторное добавление одинаковых значений, однако поведение можно дополнительно контролировать через:

{
  duplicateItemsAllowed: false
}

Это особенно важно при динамическом обновлении списка.


Работа с поиском в множественном select

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

const choices = new Choices('#cities', {
  searchEnabled: true,
  searchResultLimit: 10,
  searchFields: ['label']
});

Поведение поиска:

  • фильтрует доступные элементы
  • не затрагивает выбранные теги
  • обновляет список в реальном времени

События в множественном режиме

Choices.js предоставляет события, которые особенно важны для multi-select логики.

Добавление элемента

element.addEventListener('addItem', (event) => {
  console.log(event.detail.value);
});

Удаление элемента

element.addEventListener('removeItem', (event) => {
  console.log(event.detail.value);
});

Изменение состояния

element.addEventListener('change', (event) => {
  console.log(event.target.value);
});

Эти события позволяют синхронизировать состояние с сервером или внешними компонентами.


Работа с disabled элементами

В множественном select можно отключать отдельные опции:

<option value="msk">Москва</option>
<option value="spb" disabled>Санкт-Петербург</option>

Choices.js визуально блокирует такие элементы и исключает их из выбора.

Также можно программно отключить весь компонент:

choices.disable();

И включить обратно:

choices.enable();

Очистка состояния и пересоздание

Для полного сброса состояния используется:

choices.clearStore();

При необходимости можно уничтожить экземпляр:

choices.destroy();

После destroy() компонент возвращается к нативному <select>.


Частые ошибки при инициализации множественного select

Неправильная конфигурация чаще всего связана с нарушением базовых условий работы:

Отсутствие атрибута multiple

<select id="cities"></select>

В этом случае Choices.js работает в режиме single select, даже при попытке мультивыбора.


Несогласованность значений value

Если значения value не уникальны, состояние становится некорректным:

<option value="1">Москва</option>
<option value="1">СПБ</option>

Choices.js будет воспринимать их как один и тот же элемент.


Попытка вручную управлять DOM

Прямое изменение <option selected> после инициализации приводит к рассинхронизации. Все изменения должны выполняться через API библиотеки.


Поведение при больших списках

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

  • отключение сортировки (shouldSort: false)
  • ограничение поиска (searchResultLimit)
  • ленивое добавление через setChoices

Взаимодействие с формами

Choices.js сохраняет нативное поведение формы. Все выбранные значения отправляются как массив:

cities=msk&cities=nsk

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