Поведение мультиселекта в Choices.js при добавлении элементов определяется логикой проверки уже существующих значений и настройками, управляющими допустимостью повторов. В основе лежит механизм контроля дубликатов, который влияет как на пользовательский ввод, так и на программное добавление элементов через API.
Ключевой параметр, отвечающий за уникальность элементов, —
duplicateItems. Он задаёт стратегию обработки попыток
добавить уже существующее значение в список выбранных элементов.
const choices = new Choices('#select', {
duplicateItems: false
});
При duplicateItems: false библиотека блокирует повторное
добавление идентичного элемента. Идентичность определяется по значению
value опции, а не по отображаемому тексту.
При duplicateItems: true повторы разрешены, и один и тот
же элемент может быть добавлен многократно, что превращает компонент в
поведенчески ближе к «мульти-тегу без ограничений».
Choices.js использует значение value как основной ключ
сравнения. Это означает:
label не считаются дубликатами, если
value различаетсяvalue всегда считаются дубликатами при
включённой проверке уникальностиПример конфигурации:
const choices = new Choices('#select', {
duplicateItems: false,
choices: [
{ value: 'js', label: 'JavaScript' },
{ value: 'ts', label: 'TypeScript' },
{ value: 'js', label: 'JavaScript повтор' }
]
});
Даже если второй и третий элементы различаются по label,
система будет трактовать их как конфликтующие при одинаковом
value.
При включённой проверке уникальности ввод через UI проходит несколько стадий:
value
среди выбранныхВ случае блокировки поведение зависит от версии и настроек отображения, но обычно элемент просто не добавляется без дополнительных сообщений.
При программном добавлении через setValue или
addItem логика уникальности сохраняется.
choices.setValue([
{ value: 'js', label: 'JavaScript' }
]);
choices.setValue([
{ value: 'js', label: 'JavaScript' }
]);
При duplicateItems: false повторная попытка не изменит
состояние компонента.
Метод setValue в этом контексте ведёт себя как
«идемпотентная операция» для уже выбранных значений.
addItem — основной программный способ добавления
элементов в список выбранных значений.
choices.setChoiceByValue('js');
или:
choices.setValue([{ value: 'js', label: 'JavaScript' }]);
При использовании addItem внутренняя логика выполняет
проверку:
valuemaxItemCountЕсли хотя бы одно условие нарушено, добавление игнорируется.
Уникальность значений часто используется вместе с ограничением количества элементов:
const choices = new Choices('#select', {
duplicateItems: false,
maxItemCount: 5
});
При таком сочетании поведение становится детерминированным:
value может существовать только один разЕсли duplicateItems: true, ограничение
maxItemCount перестаёт отражать количество уникальных
значений и начинает учитывать фактические добавления, включая
повторы.
При использовании setChoices или динамической загрузки
данных уникальность влияет только на выбранные элементы, но не на список
доступных опций.
choices.setChoices([
{ value: 'js', label: 'JavaScript' },
{ value: 'js', label: 'JS alias' }
], 'value', 'label', true);
В таком случае:
valueduplicateItemsChoices.js разделяет два уровня:
1. UI-уровень
2. Data-уровень
items внутри экземпляраПри отключённой уникальности визуально могут появляться одинаковые элементы, но внутренний массив будет содержать дубликаты значений.
В режиме тегирования (tagging input) уникальность становится особенно значимой. При вводе нового значения:
const choices = new Choices('#input', {
duplicateItems: false,
addItems: true,
editItems: false
});
Алгоритм обработки:
valueЕсли введённое значение совпадает с уже существующим тегом, оно игнорируется без изменения списка.
Строгий режим
(duplicateItems: false)
valueГибкий режим (duplicateItems: true)
Сравнение выполняется без нормализации:
===){ value: 'JS' }
{ value: 'js' }
Эти значения считаются разными при проверке уникальности.
При использовании объектов с дополнительными полями:
{
value: 'js',
label: 'JavaScript',
customProperties: { level: 'advanced' }
}
уникальность всё равно базируется только на value.
Дополнительные поля не участвуют в сравнении, что упрощает модель
данных, но требует аккуратного проектирования ключей.
Поиск через встроенный фильтр Choices.js не влияет на уникальность напрямую. Однако он косвенно участвует в процессе выбора:
После удаления элемента через API или UI значение снова становится доступным для добавления, если включён режим уникальности.
choices.removeActiveItemsByValue('js');
choices.setChoiceByValue('js');
После удаления:
value исчезает из выбранныхChoices.js хранит выбранные элементы в массиве объектов, где каждый объект содержит:
valuelabelidУникальность контролируется на уровне этого массива перед внесением изменений, что обеспечивает целостность состояния при любом способе добавления данных.