Условная видимость опций

Механизм условной видимости опций в 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

В сценариях, где условие изменяется во время работы интерфейса, используется метод setData. Он полностью заменяет текущий набор опций.

select.setData(allCities.filter(item => item.region === 'central'));

Изменение набора данных приводит к перерисовке списка без необходимости пересоздания экземпляра компонента.

Управление видимостью через disabled-логику

Частично альтернативный подход — сохранение опций в 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([]);
  }
};

В данном случае видимость опций второго списка полностью определяется состоянием первого.

Условное скрытие через обновление DOM через destroy/reinit

В редких случаях используется полное пересоздание экземпляра, когда логика видимости слишком сложна для setData.

select.destroy();

new SlimSelect({
  select: '#city-select',
  data: complexFilteredData
});

Такой подход применяется при радикальной смене контекста, например при переключении режимов интерфейса.

Приоритеты видимости и конфликтующие условия

При одновременном применении disabled, фильтрации и поиска важно учитывать порядок обработки данных:

  1. Фильтрация массива data
  2. Применение пользовательского search-алгоритма
  3. Применение состояния disabled
  4. Рендер списка

Это означает, что опция может существовать в данных, но не попасть в итоговый список из-за фильтра, либо быть видимой, но недоступной для выбора.

Комбинированные сценарии условной видимости

На практике чаще всего используется комбинация нескольких подходов:

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 как слой визуализации без бизнес-логики.