В Slim Select структура данных, доступная внутри шаблонов, строится вокруг нормализованного объекта опции. Любой кастомный рендер (option, selected, group label) получает единый контекст, в котором исходные данные уже преобразованы в предсказуемую форму. Это позволяет строить сложные интерфейсы без необходимости обращаться к DOM или парсить HTML вручную.
Каждая опция внутри Slim Select представляется объектом с набором стандартных полей:
value — значение, отправляемое в формуtext — отображаемый текстhtml — HTML-разметка (если используется кастомный
контент)disabled — состояние недоступностиselected — текущее состояние выбораplaceholder — флаг плейсхолдераdata — произвольные пользовательские данныеКлючевым элементом расширения становится поле data,
через которое передаются любые дополнительные атрибуты.
new SlimSelect({
select: '#select',
data: [
{
text: 'Apple',
value: 'apple',
data: {
color: 'red',
calories: 52,
icon: '?'
}
},
{
text: 'Banana',
value: 'banana',
data: {
color: 'yellow',
calories: 96,
icon: '?'
}
}
]
});
В шаблонах эти данные доступны напрямую через объект опции.
Шаблон option отвечает за отображение элемента в
выпадающем списке. В него передаётся объект с полной структурой
опции.
new SlimSelect({
select: '#select',
settings: {
template: {
option: (option) => {
return `
<div class="option">
<span class="icon">${option.data.icon}</span>
<span class="title">${option.text}</span>
<span class="meta">${option.data.calories} kcal</span>
</div>
`;
}
}
}
});
Доступ к данным происходит через:
option.text — основной текстoption.value — идентификаторoption.data.* — пользовательские поляИспользование data позволяет полностью отделить
визуальное представление от логики данных.
При работе с динамическими источниками данных структура
data может быть неполной. В таких случаях важно учитывать
отсутствие свойств.
template: {
option: (option) => {
const icon = option.data?.icon || '';
const subtitle = option.data?.subtitle || 'Нет описания';
return `
<div class="option">
<span>${icon}</span>
<div>
<div>${option.text}</div>
<small>${subtitle}</small>
</div>
</div>
`;
}
}
Использование optional chaining и fallback-значений предотвращает разрушение шаблона при неполных данных.
Поле data не ограничивается примитивами. В него могут
быть вложенные структуры, включая массивы и объекты.
{
text: 'Product A',
value: 'a',
data: {
stats: {
rating: 4.7,
reviews: 1240
},
tags: ['popular', 'discount'],
availability: {
stock: 15,
warehouse: 'EU'
}
}
}
Доступ в шаблоне:
template: {
option: (option) => {
return `
<div>
<div>${option.text}</div>
<div>Rating: ${option.data.stats.rating}</div>
<div>Reviews: ${option.data.stats.reviews}</div>
<div>Stock: ${option.data.availability.stock}</div>
</div>
`;
}
}
Такой подход превращает Slim Select в слой представления поверх произвольной бизнес-модели.
Поле html может использоваться как альтернативный
источник отображения, когда текст недостаточен для описания опции.
{
text: 'Server 1',
value: 'srv1',
html: '<strong>Server 1</strong> <em>(active)</em>',
data: {
status: 'active'
}
}
В шаблоне можно переключаться между text и
html:
template: {
option: (option) => {
return `
<div class="option">
${option.html || option.text}
</div>
`;
}
}
Важно учитывать, что html уже содержит разметку и
требует аккуратной обработки при комбинировании с дополнительными
полями.
Шаблон выбранного значения (selected) работает с тем же
объектом опции, что и option, но используется для
отображения в закрытом состоянии селекта.
new SlimSelect({
select: '#select',
settings: {
template: {
selected: (option) => {
return `
<div class="selected">
<span>${option.data.icon}</span>
<span>${option.text}</span>
</div>
`;
}
}
}
});
Данные не дублируются и берутся из того же источника, что обеспечивает согласованность отображения.
Частая ошибка при проектировании данных — дублирование информации в
text и data.text. В Slim Select:
text используется системой как основной источник
отображенияdata предназначено для расширения, а не замены базовых
полейКорректная модель:
{
text: 'Москва',
value: 'moscow',
data: {
timezone: 'UTC+3',
population: 12500000
}
}
Некорректная модель:
{
text: 'Москва',
data: {
text: 'Москва'
}
}
Дублирование приводит к избыточной вложенности и усложняет шаблоны.
Поскольку шаблоны представляют собой функции, внутри них допустима любая логика преобразования данных.
template: {
option: (option) => {
const isHighRated = option.data.rating > 4;
return `
<div class="option ${isHighRated ? 'highlight' : ''}">
<span>${option.text}</span>
<span>${option.data.rating}</span>
</div>
`;
}
}
Такой подход позволяет переносить часть UI-логики прямо в слой шаблона без изменения исходных данных.
При работе с API данные редко приходят в форме, удобной для шаблонов. Обычно требуется предварительная нормализация.
const apiData = [
{ name: 'Item 1', id: 1, meta: { score: 10 } },
{ name: 'Item 2', id: 2, meta: { score: 20 } }
];
const normalized = apiData.map(item => ({
text: item.name,
value: item.id,
data: {
score: item.meta.score
}
}));
new SlimSelect({
select: '#select',
data: normalized
});
Такой слой преобразования отделяет API-структуру от UI-структуры, упрощая шаблоны.
Шаблоны Slim Select работают в синхронном контексте и не предназначены для асинхронных операций. Доступные данные должны быть заранее подготовлены.
Недопустимые подходы:
optionШаблон должен оставаться чистой функцией отображения:
(option) => string
Каждая опция обрабатывается независимо. Изменение
option.data внутри одного шаблона не влияет на другие
элементы. Это позволяет безопасно использовать общие структуры данных
без риска побочных эффектов.
template: {
option: (option) => {
option.data.used = true; // нежелательная практика
return `<div>${option.text}</div>`;
}
}
Хотя технически возможно мутировать объект, структура библиотеки предполагает неизменяемость входных данных.
Данные могут напрямую влиять на CSS-классы и визуальное состояние элементов.
template: {
option: (option) => {
return `
<div class="option status-${option.data.status}">
${option.text}
</div>
`;
}
}
Где status может принимать значения active,
disabled, pending, формируя разные визуальные
состояния без изменения логики Slim Select.
При построении сложных селектов (категории, товары, пользователи)
data становится основным инструментом композиции:
Пример структуры для пользователя:
{
text: 'John Doe',
value: 42,
data: {
role: 'admin',
avatar: '/img/john.png',
permissions: ['edit', 'delete'],
activity: {
lastLogin: '2026-05-25',
score: 87
}
}
}
Шаблон превращается в отображение полноценной карточки сущности, а не просто строки списка.