Программное добавление опций

Библиотека Choices.js предоставляет программный интерфейс для управления списками выбора, позволяя динамически изменять доступные опции без пересоздания компонента. Основной сценарий использования — добавление элементов в уже инициализированный список на основе данных, полученных из API, пользовательского ввода или внутренних событий приложения.

Работа с программным добавлением опций начинается с создания экземпляра Choices. Именно этот объект становится точкой управления всеми дальнейшими изменениями:

const element = document.querySelector('#sel ect');
const choices = new Choices(element, {
  removeItemButton: true,
  searchEnabled: true
});

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

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

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

Метод addChoice как базовый инструмент добавления

Основной метод для добавления одной опции — setChoiceByValue в старых версиях и addChoice / setChoices в современных реализациях Choices.js. На практике чаще используется setChoices для пакетного добавления, однако логика единичного добавления остаётся через внутренние механизмы.

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

choices.setChoices([{
  value: '1',
  label: 'Первый элемент',
  selected: false,
  disabled: false
}], 'value', 'label', false);

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

При таком подходе библиотека выполняет несколько операций:

  • создаёт внутренний объект выбора
  • добавляет его в коллекцию choices
  • обновляет DOM-отображение списка
  • синхронизирует состояние с оригинальным select-элементом

Массовое добавление опций через setChoices

Наиболее производительный способ наполнения списка — передача массива данных:

const items = [
  { value: 'ru', label: 'Русский' },
  { value: 'en', label: 'Английский' },
  { value: 'de', label: 'Немецкий' }
];

choices.setChoices(items, 'value', 'label', true);

Четвёртый параметр true указывает, что существующие данные должны быть очищены перед добавлением новых. Это поведение удобно при работе с динамическими источниками данных, например:

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

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

Программное добавление с источником данных (async сценарии)

Одним из ключевых сценариев является загрузка данных из API и последующее добавление в Choices:

fetch('/api/options')
  .then(response => response.json())
  .then(data => {
    choices.setChoices(
      data.map(item => ({
        value: item.id,
        label: item.name
      })),
      'value',
      'label',
      true
    );
  });

Такая модель позволяет отделить UI-слой от бизнес-логики, делая компонент универсальным. Choices.js не накладывает ограничений на формат источника данных, что позволяет адаптировать его под REST, GraphQL или локальные структуры.

Добавление опций без очистки текущего списка

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

choices.setChoices([
  { value: 'es', label: 'Испанский' }
], 'value', 'label', false);

Этот режим важен для сценариев:

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

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

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

Choices.js позволяет не только добавлять опции, но и сразу задавать состояние выбора. Это реализуется через свойство selected:

choices.setChoices([
  { value: 'fr', label: 'Французский', selected: true }
], 'value', 'label', true);

При этом происходит автоматическая синхронизация:

  • значение устанавливается в скрытый input
  • обновляется визуальное отображение выбранных тегов
  • активируются события изменения состояния

Это поведение критично для сценариев восстановления состояния формы, например:

  • редактирование сохранённых данных
  • восстановление черновиков
  • предзаполнение профиля пользователя

Работа с уникальностью значений

При программном добавлении важно учитывать механизм уникальности. Choices.js использует значение value как ключ идентификации. Повторное добавление элемента с тем же value приводит к:

  • игнорированию дубликата
  • либо обновлению существующего элемента (в зависимости от версии и настроек)

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

const uniqueItems = Array.fr om(
  new Map(data.map(item => [item.id, item])).values()
);

Это предотвращает засорение списка повторяющимися элементами и снижает нагрузку на DOM.

Динамическое обновление списка через очистку

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

choices.clearStore();

choices.setChoices([
  { value: '1', label: 'Новый элемент 1' },
  { value: '2', label: 'Новый элемент 2' }
], 'value', 'label', true);

Очистка полностью удаляет внутреннее состояние, включая:

  • список доступных элементов
  • выбранные значения
  • связанные DOM-ноды

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

Добавление пользовательских опций (user-generated)

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

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

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

  • валидацию строки
  • проверку на дубликаты
  • добавление в store
  • обновление интерфейса

Синхронизация добавленных значений с внешними системами

При программном добавлении часто требуется синхронизация с сервером. Choices.js предоставляет события изменения состояния:

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

Это позволяет отслеживать:

  • добавление новых значений
  • изменение выбора
  • удаление элементов

Такая модель особенно полезна при интеграции с формами, где каждое изменение должно фиксироваться на стороне приложения.

Оптимизация массовых операций добавления

При работе с большими наборами данных (1000+ элементов) важно учитывать производительность. Основные рекомендации:

  • использовать setChoices вместо многократного addChoice
  • отключать рендеринг во время загрузки (через временное скрытие UI)
  • передавать уже нормализованные данные

Пример пакетной загрузки:

choices.disable();

choices.setChoices(largeDataset, 'value', 'label', true);

choices.enable();

Такой подход снижает количество перерисовок и ускоряет инициализацию интерфейса.

Обновление уже добавленных опций

Choices.js не предоставляет прямого метода редактирования элемента, однако обновление реализуется через пересборку списка:

const updated = choices.getChoices().map(item => {
  if (item.value === '1') {
    return { ...item, label: 'Обновлённый текст' };
  }
  return item;
});

choices.setChoices(updated, 'value', 'label', true);

Это поведение отражает концепцию библиотеки: состояние рассматривается как единый источник истины, который пересобирается при изменении данных.

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

Добавленные программно элементы автоматически попадают в индекс поиска Choices.js. Это означает, что:

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

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

Управление состоянием после добавления

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

choices.setChoiceByValue('ru');

Этот метод активирует элемент без необходимости взаимодействия с DOM. Он используется для:

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

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