Механизм условной видимости опций в Slim Select строится вокруг
динамического управления набором данных, который рендерится в выпадающем
списке. В отличие от нативного <select>, где
управление ограничено атрибутами disabled и
hidden, библиотека предоставляет программный контроль над
тем, какие элементы отображаются, как они фильтруются и при каких
условиях становятся доступными пользователю.
Slim Select оперирует структурой данных, где каждая опция описывается объектом:
{
text: 'Москва',
value: 'moscow',
disabled: false
}
Отображение опций зависит не только от статического набора, но и от текущего состояния компонента. При изменении данных через API происходит полная перерасчётка списка.
const select = new SlimSelect({
select: '#city-select',
data: [
{ text: 'Москва', value: 'moscow' },
{ text: 'Санкт-Петербург', value: 'spb' },
{ text: 'Казань', value: 'kazan' }
]
});
Основной способ управления видимостью — фильтрация массива
data до передачи в компонент. Такой подход обеспечивает
максимальную производительность, поскольку Slim Select не хранит скрытые
элементы внутри DOM.
const allCities = [
{ text: 'Москва', value: 'moscow', region: 'central' },
{ text: 'Иркутск', value: 'irkutsk', region: 'siberia' },
{ text: 'Новосибирск', value: 'novosibirsk', region: 'siberia' }
];
const onlySibe ria = allCities.filter(item => item.region === 'siberia');
new SlimSelect({
select: '#city-select',
data: onlySiberia
});
Такой подход используется при серверной сегментации данных или при необходимости строгой бизнес-логики отображения.
В сценариях, где условие изменяется во время работы интерфейса,
используется метод setData. Он полностью заменяет текущий
набор опций.
select.setData(allCities.filter(item => item.region === 'central'));
Изменение набора данных приводит к перерисовке списка без необходимости пересоздания экземпляра компонента.
Частично альтернативный подход — сохранение опций в DOM, но
блокировка выбора через disabled. Slim Select отображает
такие элементы, но исключает их из интерактивного выбора.
data: [
{ text: 'Москва', value: 'moscow', disabled: false },
{ text: 'Якутск', value: 'yakutsk', disabled: true }
]
Хотя визуально элемент присутствует, он становится неактивным. Это полезно при сохранении контекста, когда важно показать недоступность, но не скрывать данные.
Для сложной логики часто вводятся дополнительные поля, которые не интерпретируются библиотекой напрямую, но используются для фильтрации перед рендером.
const userRole = 'admin';
const options = [
{ text: 'Настройки системы', value: 'settings', role: 'admin' },
{ text: 'Профиль', value: 'profile', role: 'user' }
];
const filtered = options.filter(opt => opt.role === userRole);
select.setData(filtered);
Такой подход позволяет реализовать ролевую модель отображения, где видимость зависит от контекста авторизации.
Slim Select поддерживает встроенный поиск, который можно расширять кастомной логикой фильтрации. При необходимости можно полностью заменить поведение поиска через предварительную обработку данных.
select.search = (search, data) => {
return data.filter(item =>
item.text.toLowerCase().includes(search.toLowerCase()) &&
item.text.length > 3
);
};
В данном случае опции дополнительно скрываются, если не проходят второе условие по длине строки.
При работе с серверными данными фильтрация часто переносится на backend. В этом случае видимость опций зависит от результата запроса.
select.setData([{ text: 'Загрузка...', value: 'loading', disabled: true }]);
fetch('/api/cities?region=siberia')
.then(res => res.json())
.then(data => {
select.setData(data);
});
Промежуточное состояние позволяет контролировать UX без отображения некорректных данных.
При использовании группировки данные могут скрываться на уровне целых категорий. Slim Select не ограничивает структуру, поэтому логика групп полностью контролируется до передачи в компонент.
const grouped = [
{
label: 'Европа',
options: [
{ text: 'Берлин', value: 'berlin' },
{ text: 'Париж', value: 'paris' }
]
},
{
label: 'Азия',
options: [
{ text: 'Токио', value: 'tokyo' }
]
}
];
const onlyEur ope = grouped.filter(group => group.label === 'Европа');
select.setData(onlyEurope);
Таким образом достигается скрытие целых логических блоков без изменения структуры компонентов.
Часто видимость опций зависит от других элементов формы. Slim Select не управляет этим автоматически, поэтому используется внешняя реактивная логика.
const countrySelect = new SlimSelect({ select: '#country' });
const citySelect = new SlimSelect({ select: '#city' });
countrySelect.onCha nge = (info) => {
if (info.value === 'kazakhstan') {
citySelect.setData([
{ text: 'Караганда', value: 'karaganda' },
{ text: 'Астана', value: 'astana' }
]);
} else {
citySelect.setData([]);
}
};
В данном случае видимость опций второго списка полностью определяется состоянием первого.
В редких случаях используется полное пересоздание экземпляра, когда
логика видимости слишком сложна для setData.
select.destroy();
new SlimSelect({
select: '#city-select',
data: complexFilteredData
});
Такой подход применяется при радикальной смене контекста, например при переключении режимов интерфейса.
При одновременном применении disabled, фильтрации и
поиска важно учитывать порядок обработки данных:
datadisabledЭто означает, что опция может существовать в данных, но не попасть в итоговый список из-за фильтра, либо быть видимой, но недоступной для выбора.
На практике чаще всего используется комбинация нескольких подходов:
function getVisibleOptions(user, query) {
return allOptions
.filter(opt => opt.roles.includes(user.role))
.filter(opt => opt.text.toLowerCase().includes(query.toLowerCase()))
.map(opt => ({
...opt,
disabled: opt.isArchived
}));
}
select.setData(getVisibleOptions(currentUser, searchQuery));
Такая модель позволяет централизовать всю логику отображения и отделить её от UI-компонента, сохраняя Slim Select как слой визуализации без бизнес-логики.