Выбор нескольких элементов

Работа с множественным выбором в Choices.js строится вокруг расширения стандартного поведения HTML-элементов <select multiple> и кастомных текстовых инпутов, превращая их в управляемый компонент с поддержкой тегов, поиска, динамического добавления и удаления значений. Библиотека предоставляет единый API для управления списками выбранных элементов, их синхронизации с исходным полем формы и обработки пользовательского ввода в режиме реального времени.

Режим множественного выбора активируется через атрибут multiple у <select> или соответствующую конфигурацию при работе с текстовыми полями. Основной принцип заключается в том, что каждое выбранное значение представляется отдельной сущностью внутри внутреннего состояния экземпляра Choices.

<select id="cities" multiple>
  <option value="msk">Москва</option>
  <option value="spb">Санкт-Петербург</option>
  <option value="kzn">Казань</option>
</select>
const element = document.getElementById('cities');

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

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

Внутренняя модель данных множественного выбора

Внутренне Choices.js хранит выбранные элементы в структуре, аналогичной списку объектов:

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

Каждый объект содержит:

  • value — фактическое значение, отправляемое в форму
  • label — отображаемый текст
  • selected — состояние выбора
  • disabled — блокировка взаимодействия

Состояние синхронизируется с DOM, где каждому выбранному элементу соответствует скрытое состояние <option selected>.

Добавление элементов в множественный выбор

Добавление новых значений осуществляется через метод setChoiceByValue или setValue. Для мультивыбора характерно накопление значений, а не их замена.

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

Альтернативный вариант с объектами:

choices.setValue([
  { value: 'msk', label: 'Москва' },
  { value: 'kzn', label: 'Казань' }
]);

При добавлении элементов происходит проверка:

  • наличие дубликатов
  • соответствие разрешённым опциям
  • допустимость значения (если включён whitelist режим)

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

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

const choices = new Choices(element, {
  maxItemCount: 3
});

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

Дополнительно используется событие maxItemSelect, позволяющее перехватывать попытки превышения лимита.

Режим удаления элементов

В мультивыборе важную роль играет управление удалением элементов. За это отвечает опция removeItemButton, добавляющая кнопку удаления рядом с каждым выбранным элементом.

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

Удаление элемента приводит к:

  • снятию флага selected у соответствующего option
  • обновлению внутреннего массива значений
  • синхронизации UI

Также доступно программное удаление:

choices.removeActiveItemsByValue('msk');

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

Полная очистка состояния мультивыбора выполняется методом clearStore или removeActiveItems.

choices.removeActiveItems();

После выполнения:

  • все элементы теряют статус selected
  • интерфейс очищается от выбранных тегов
  • поле формы возвращается к начальному состоянию

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

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

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

Особенности:

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

Динамическое добавление новых значений

Choices.js поддерживает режим создания новых элементов пользователем через addItemFilter и addChoices.

const choices = new Choices(element, {
  addItems: true,
  duplicateItemsAllowed: false
});

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

choices.setChoices([
  { value: 'new-york', label: 'Нью-Йорк', selected: false }
], 'value', 'label', true);

При добавлении в мультивыбор:

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

Управление дубликатами

Контроль повторяющихся значений критичен для множественного выбора. Параметр duplicateItemsAllowed определяет поведение при попытке повторного добавления.

const choices = new Choices(element, {
  duplicateItemsAllowed: false
});

Поведение при отключённых дубликатах:

  • повторное добавление игнорируется
  • существующее значение остаётся без изменений
  • предотвращается засорение состояния

Получение текущих выбранных значений

Состояние мультивыбора можно получить через getValue.

const selected = choices.getValue();

Результат представляет массив объектов:

[
  { value: 'msk', label: 'Москва' },
  { value: 'kzn', label: 'Казань' }
]

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

const values = choices.getValue(true);

Отключение отдельных элементов

Choices.js позволяет блокировать конкретные значения внутри мультивыбора:

choices.setChoices([
  { value: 'msk', label: 'Москва', disabled: true },
  { value: 'spb', label: 'Санкт-Петербург' }
], 'value', 'label', true);

Отключённые элементы:

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

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

Мультивыбор сопровождается набором событий, отражающих изменения состояния:

  • addItem — добавление нового значения
  • removeItem — удаление значения
  • change — общее изменение состояния

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

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

Каждое событие содержит:

  • value
  • label
  • id элемента
  • состояние выбора

Синхронизация с формой

Одним из ключевых аспектов является автоматическая синхронизация с HTML-формой. При отправке формы:

  • выбранные значения сериализуются как массив
  • каждый элемент соответствует отдельному <option selected>
  • сервер получает стандартный массив значений
<select name="cities[]" multiple>

Формат cities[] позволяет корректно обработать массив на серверной стороне.

Производительность при большом количестве элементов

При работе с большими списками мультивыбора используется оптимизация:

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

Рекомендуется:

  • отключать сортировку при больших наборах
  • ограничивать глубину поиска
  • использовать предзагруженные данные вместо динамической генерации
const choices = new Choices(element, {
  shouldSort: false,
  searchResultLimit: 10
});

Комбинация тегов и мультивыбора

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

const choices = new Choices(element, {
  removeItemButton: true,
  duplicateItemsAllowed: false
});

Такой режим объединяет:

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

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