Предзаполненные значения

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

Choices.js опирается на исходный HTML-элемент <select> или переданные данные для формирования внутреннего состояния. Предзаполненные значения могут задаваться двумя основными способами:

  • через атрибут selected в HTML-разметке
  • через программное API при инициализации или после неё

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

Предзаполнение через HTML-атрибут selected

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

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

После инициализации Choices.js автоматически распознаёт отмеченные элементы и отображает их как выбранные:

const element = document.querySelector('#city-select');

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

Особенности поведения

  • все option[selected] автоматически становятся выбранными
  • поддерживается множественный выбор (multiple)
  • одиночный select принимает только первое найденное значение при конфликте
  • значения синхронизируются с DOM-элементом

Важно учитывать, что Choices.js считывает состояние один раз при инициализации. Последующие изменения HTML не будут автоматически отражены без вызова API.

Программное предзаполнение через setChoiceByValue

Одним из наиболее надёжных способов программного управления начальными значениями является метод setChoiceByValue. Он позволяет явно задать выбранные элементы после инициализации компонента.

const element = document.querySelector('#city-select');

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

choices.setChoiceByValue('msk');

Для множественных значений передаётся массив:

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

Поведение метода

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

Этот способ считается предпочтительным при работе с данными, полученными с сервера.

Использование setChoiceByValue до загрузки UI

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

const choices = new Choices('#city-select');

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

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

Предзаполнение через setValue

Помимо setChoiceByValue, существует метод setValue, который работает с объектами выбора и используется при более сложных сценариях:

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

Отличия от setChoiceByValue

  • setValue принимает полные объекты
  • позволяет задавать label вручную
  • полезен при динамически загруженных данных без <option>
  • требует корректного соответствия структуры Choices.js

Этот метод часто применяется в AJAX-режимах, когда список опций формируется программно.

Предзаполнение через addItem

Метод addItem используется для добавления выбранного значения как элемента:

choices.addItem('msk');

или с объектом:

choices.addItem({
  value: 'msk',
  label: 'Москва',
  selected: true
});

Особенности использования

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

Этот метод часто применяется в ситуациях, когда пользовательский ввод превращается в выбранный элемент (например, тегирование).

Предзаполненные значения в режиме createItem

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

const choices = new Choices('#tags', {
  createItem: true
});

можно заранее задать нестандартные значения:

choices.setValue([
  { value: 'custom-1', label: 'Пользовательский тег' }
]);

Если значение отсутствует в списке, Choices.js создаёт его как пользовательский элемент.

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

При наличии нескольких источников начальных данных применяется следующая логика:

  1. selected в HTML
  2. данные, переданные при инициализации через конфигурацию (если используются кастомные адаптеры)
  3. вызовы API (setChoiceByValue, setValue, addItem)

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

Синхронизация с оригинальным select

Choices.js всегда поддерживает двустороннюю синхронизацию:

  • выбор в UI обновляет <option selected>
  • изменения через DOM отражаются в состоянии только при пересоздании экземпляра или явном обновлении

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

const element = document.querySelector('select');
const choices = new Choices(element);

element.value = 'msk';
// UI не обновится автоматически

Для корректного обновления требуется:

choices.setChoiceByValue('msk');

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

При работе с AJAX-источниками данных предзаполнение часто выполняется после получения ответа:

fetch('/api/cities')
  .then(res => res.json())
  .then(data => {
    const choices = new Choices('#city-select', {
      choices: data
    });

    choices.setChoiceByValue(['msk', 'spb']);
  });

Здесь важно соблюдать порядок:

  1. инициализация компонента
  2. загрузка данных
  3. установка выбранных значений

Обработка некорректных значений

Если в метод предзаполнения передаётся значение, которого нет в списке опций:

  • оно игнорируется
  • ошибка не выбрасывается
  • состояние остаётся консистентным
choices.setChoiceByValue(['unknown', 'msk']);

Результат: будет выбрано только msk.

Особенности работы с disabled элементами

Если выбранный элемент имеет атрибут disabled, поведение зависит от способа предзаполнения:

  • через HTML: элемент может отображаться, но не быть удаляемым
  • через API: disabled-статус сохраняется при добавлении
choices.setValue([
  { value: 'msk', label: 'Москва', disabled: true }
]);

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

Предзаполнение в одиночных select

В режиме без multiple Choices.js допускает только одно значение:

choices.setChoiceByValue('msk');

Если передан массив:

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

будет выбрано только первое корректное значение.

Влияние search и фильтрации на предзаполнение

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

Состояние при reset формы

При использовании стандартного сброса формы:

<form>
  <select id="city-select" multiple>
    <option value="msk" selected>Москва</option>
    <option value="spb">СПб</option>
  </select>

  <button type="reset">Reset</button>
</form>

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

form.addEventListener('reset', () => {
  choices.destroy();
  new Choices('#city-select');
});

или повторное применение значений из DOM.

Итоговая модель поведения предзаполнения

Логика предзаполненных значений в Choices.js строится на трёх уровнях:

  • начальное состояние HTML
  • программное состояние API
  • динамическое состояние пользовательского взаимодействия

Каждый уровень может модифицировать предыдущий, но итоговое состояние всегда контролируется внутренним store библиотеки, который синхронизирует UI и исходный элемент формы.