Семантическая разметка в Choices.js определяет способ представления данных внутри выпадающих списков, мультиселектов и пользовательских инпутов, превращая плоский набор строк в структурированную модель с явным разделением значения, отображаемого текста, группировки и дополнительных метаданных. Именно семантика данных формирует основу для корректной работы поиска, фильтрации, кастомных шаблонов и интеграции с внешними источниками.
В основе работы библиотеки лежит разделение двух ключевых сущностей:
Такое разделение устраняет неоднозначность между отображением и хранением данных.
const choices = new Choices('#select', {
choices: [
{ value: 'ru', label: 'Русский' },
{ value: 'en', label: 'English' },
{ value: 'de', label: 'Deutsch' }
]
});
Семантически важно, что value используется при отправке
формы и сравнении, тогда как label участвует в рендеринге
интерфейса и поиске.
Каждый элемент внутри Choices.js преобразуется во внутреннюю структуру, включающую дополнительные поля:
{
id: 1,
value: 'ru',
label: 'Русский',
selected: false,
disabled: false,
customProperties: {
region: 'EU',
rtl: false
}
}
Наличие customProperties позволяет расширять
семантическую модель без изменения базовой структуры.
HTML-источник часто содержит дополнительную семантику через
data-* атрибуты. При инициализации они могут быть
интерпретированы как расширенные свойства.
<select id="select">
<option value="ru" data-region="EU" data-lang="cyrillic">Русский</option>
<option value="en" data-region="US" data-lang="latin">English</option>
</select>
При обработке данные из data-* преобразуются в объектную
модель:
{
value: 'ru',
label: 'Русский',
customProperties: {
region: 'EU',
lang: 'cyrillic'
}
}
Такой подход позволяет сохранять семантику на уровне DOM без потери при инициализации.
Группировка элементов через optgroup добавляет
иерархическую структуру, которая используется для логического разделения
наборов данных.
<select id="select">
<optgroup label="Европа">
<option value="ru">Россия</option>
<option value="de">Германия</option>
</optgroup>
<optgroup label="Азия">
<option value="jp">Япония</option>
<option value="cn">Китай</option>
</optgroup>
</select>
Внутренняя модель преобразует это в вложенную структуру:
{
label: 'Европа',
choices: [...]
}
Семантика групп влияет не только на отображение, но и на поведение поиска: фильтрация может учитывать или игнорировать заголовки групп в зависимости от конфигурации.
Поисковый механизм в Choices.js строится на нормализации текста
label и, при наличии, дополнительных полей.
Алгоритм обычно включает:
При расширенной конфигурации в поиск включаются:
new Choices('#select', {
searchFields: ['label', 'value', 'customProperties.region']
});
Таким образом, семантика поиска становится многослойной и выходит за пределы отображаемого текста.
Режим создания новых элементов формирует динамическую семантическую модель, где пользовательский ввод преобразуется в полноценный объект выбора.
new Choices('#tags', {
duplicateItemsAllowed: false,
editItems: true,
addItems: true
});
В этом режиме:
valuelabel может совпадать или отличаться от
valueСемантически важным является момент нормализации: введённая строка проходит через тот же pipeline, что и статические данные.
Отображение элементов в DOM отделено от их данных через систему шаблонов. Это обеспечивает независимость визуального слоя от структуры данных.
new Choices('#select', {
callbackOnCreateTemplates: function (template) {
return {
item: (classNames, data) => {
return template(`
<div class="${classNames.item}" data-value="${data.value}">
<span>${data.label}</span>
</div>
`);
}
};
}
});
Семантическая модель при этом сохраняется неизменной, так как шаблон влияет только на представление, а не на структуру данных.
Состояние disabled формирует отдельный семантический
уровень, влияющий на:
{
value: 'ru',
label: 'Русский',
disabled: true
}
Такие элементы сохраняются в модели, но исключаются из интерактивного поведения, что важно для согласованности состояния UI.
В режиме multiple каждый выбранный элемент становится самостоятельной сущностью внутри коллекции.
new Choices('#select', {
removeItemButton: true,
maxItemCount: 5
});
Здесь семантическое значение смещается от одиночного значения к множеству, где:
[
{ value: 'ru', label: 'Русский' },
{ value: 'en', label: 'English' }
]
Исходный <select> элемент сохраняет роль источника
истины. При изменении состояния библиотека синхронизирует:
DOM при этом выступает как отражение внутренней модели, а не как первичная структура.
Расширение модели через customProperties позволяет
внедрять произвольные атрибуты без нарушения базовой схемы.
{
value: 'ru',
label: 'Русский',
customProperties: {
flag: '??',
popularity: 10,
region: 'CIS'
}
}
Эти данные могут использоваться в:
Каждый элемент проходит несколько состояний:
Эти состояния не изменяют саму семантическую сущность, но расширяют её поведенческую модель.
При работе с серверными источниками данные обычно приходят в JSON-формате:
[
{ "id": 1, "name": "Русский" },
{ "id": 2, "name": "English" }
]
Преобразование в модель Choices.js включает маппинг:
choices: data.map(item => ({
value: item.id,
label: item.name
}))
Семантическая консистентность обеспечивается тем, что независимо от источника структура внутри библиотеки остаётся одинаковой.
При конфликте источников данных применяется приоритет:
Такая иерархия предотвращает потерю актуального состояния и сохраняет целостность модели.