Внутри Slim Select каждый пункт списка строится на основе
стандартного HTML <option> или объекта данных, если
используется программная инициализация. Независимо от источника,
библиотека приводит данные к единой структуре, где ключевыми полями
выступают:
HTML-основа:
<select id="mySelect">
<option value="1">Первый элемент</option>
<option value="2" disabled>Второй элемент</option>
<option value="3">Третий элемент</option>
</select>
После инициализации Slim Select преобразует этот список в внутреннее представление, где каждый option становится объектом, используемым для рендеринга.
При программной инициализации структура может задаваться напрямую:
new SlimSelect({
select: '#mySelect',
data: [
{ text: 'Первый элемент', value: '1' },
{ text: 'Второй элемент', value: '2', disabled: true },
{ text: 'Третий элемент', value: '3' }
]
});
Каждый объект в массиве data становится шаблоном option.
Это ключевой слой, на котором строится кастомизация отображения.
В Slim Select шаблон option отвечает за то, как элемент списка визуально представлен в dropdown. Основной механизм заключается в функции рендеринга, которая получает данные option и возвращает HTML-строку.
Типовая форма:
new SlimSelect({
select: '#mySelect',
render: {
option: (data, option) => {
return `<div class="custom-option">${data.text}</div>`;
}
}
});
Использование DOM-элемента позволяет извлекать кастомные атрибуты:
<option value="1" data-icon="star">Первый</option>
render: {
option: (data, option) => {
const icon = option.getAttribute('data-icon');
return `
<div class="option-item">
<span class="icon">${icon}</span>
<span class="label">${data.text}</span>
</div>
`;
}
}
Одним из расширений шаблона option является поддержка
HTML-содержимого. Если innerHTML передаётся явно, Slim
Select может использовать его вместо text.
data: [
{
value: '1',
text: 'Ignored text',
innerHTML: '<strong>Жирный текст</strong>'
}
]
В рендере:
render: {
option: (data) => {
return `<div class="option-html">${data.innerHTML ?? data.text}</div>`;
}
}
Это позволяет строить сложные элементы списка: с иконками, бейджами, описаниями и статусами.
Шаблон option часто расширяется через data-*
атрибуты:
<option value="1" data-price="1200" data-status="available">
Товар 1
</option>
Использование в шаблоне:
render: {
option: (data, option) => {
const price = option.getAttribute('data-price');
const status = option.getAttribute('data-status');
return `
<div class="product-option">
<div class="title">${data.text}</div>
<div class="meta">
<span class="price">${price}</span>
<span class="status">${status}</span>
</div>
</div>
`;
}
}
Такой подход переводит option из простого текста в полноценный UI-компонент.
Внутренний шаблон option часто отличается от отображения выбранного значения. В Slim Select это разделение логически важно: dropdown и поле выбора могут иметь разные представления одного и того же объекта.
new SlimSelect({
select: '#mySelect',
render: {
option: (data) => {
return `<div class="dropdown-item">${data.text}</div>`;
},
selected: (data) => {
return `<div class="selected-item">${data.text}</div>`;
}
}
});
Разделение позволяет:
Шаблон option часто зависит от состояния данных:
render: {
option: (data, option) => {
if (data.disabled) {
return `<div class="option disabled">${data.text}</div>`;
}
if (option?.dataset?.premium === "true") {
return `<div class="option premium">${data.text} ⭐</div>`;
}
return `<div class="option">${data.text}</div>`;
}
}
Таким образом шаблон становится реактивным к данным, а не статическим.
Когда используются группы (optgroup), шаблон option
дополняется структурой группы:
<optgroup label="Фрукты">
<option value="apple">Яблоко</option>
<option value="banana">Банан</option>
</optgroup>
В кастомном рендере можно учитывать контекст группы:
render: {
option: (data, option) => {
const group = option.closest('optgroup')?.label;
return `
<div class="option">
<div class="text">${data.text}</div>
${group ? `<div class="group">${group}</div>` : ''}
</div>
`;
}
}
При работе с большими списками шаблон option становится критическим элементом производительности. В Slim Select важно учитывать:
Пример оптимизации:
const cache = new Map();
function renderOption(data) {
if (cache.has(data.value)) {
return cache.get(data.value);
}
const html = `<div class="option">${data.text}</div>`;
cache.set(data.value, html);
return html;
}
Часто option строится из API-ответов:
fetch('/api/items')
.then(res => res.json())
.then(items => {
new SlimSelect({
select: '#mySelect',
data: items.map(item => ({
text: item.name,
value: item.id,
innerHTML: `<strong>${item.name}</strong>`
}))
});
});
Шаблон option в этом случае становится слоем визуализации над серверной моделью данных.
В Slim Select возможно изменение данных и перерисовка списка без пересоздания экземпляра:
const slim = new SlimSelect({
select: '#mySelect',
data: []
});
slim.setData([
{ text: 'Новый элемент 1', value: '1' },
{ text: 'Новый элемент 2', value: '2' }
]);
При этом шаблон option применяется повторно ко всем новым данным, что делает render-функцию центральной точкой визуальной логики.
Шаблон option в Slim Select выступает слоем между данными и интерфейсом. Он определяет:
Фактически именно шаблон option превращает стандартный
<select> в гибкий компонент интерфейса с управляемой
визуализацией и логикой представления данных.