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

Базовая модель отображения опций

Внутренняя логика отображения списка опций в Tom Select строится вокруг трёх источников данных: исходного массива опций, текущего поискового запроса и состояния инстанса. Каждый элемент проходит через цепочку фильтрации перед тем, как попасть в выпадающий список.

Ключевое поведение:

  • опции хранятся в options
  • отображение формируется через getSearchOptions()
  • результат зависит от введённого текста и настроек поиска

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


Фильтрация через searchField и встроенный поиск

Основной механизм скрытия опций — настройка поля поиска:

new TomSelect("#select", {
  searchField: ["title", "code"]
});

Каждая опция сравнивается с запросом пользователя по указанным полям. Если совпадений нет, элемент не попадает в результат.

Особенности поведения:

  • поиск нечувствителен к регистру (по умолчанию)
  • поддерживается частичное совпадение
  • можно задавать несколько полей одновременно
  • логика расширяется через кастомный score

Кастомизация видимости через score-функцию

Механизм ранжирования позволяет не просто скрывать, а управлять приоритетом отображения:

new TomSelect("#select", {
  score: function(search) {
    return function(item) {
      if (item.type === "disabled_group") return 0;
      return item.title.includes(search) ? 10 : 1;
    };
  }
});

Принцип работы:

  • чем выше score, тем выше позиция
  • нулевой score фактически убирает опцию из выдачи
  • можно реализовать условное скрытие через возврат 0

Это даёт гибкость, аналогичную фильтрам в UI-компонентах высокого уровня.


Полное исключение опций через фильтрацию данных

Вместо визуального скрытия возможно управление самим набором данных:

const select = new TomSelect("#select", {
  options: [
    { value: "1", text: "A", visible: true },
    { value: "2", text: "B", visible: false }
  ],
  load: function(query, callback) {
    const filtered = this.options;
    const result = Object.values(filtered).filter(o => o.visible);
    callback(result);
  }
});

Суть подхода:

  • опции заранее помечаются флагом
  • загрузчик возвращает только допустимые элементы
  • список полностью контролируется внешней логикой

Динамическое управление через onType

Поведение списка может зависеть от текущего ввода:

new TomSelect("#select", {
  onType: function(str) {
    if (str.length < 3) {
      this.clearOptions();
      return;
    }
  }
});

Механизм позволяет:

  • скрывать все опции при недостаточной длине запроса
  • включать фильтрацию только после определённого порога
  • полностью заменять набор данных на лету

Условное скрытие через render.option

Визуальная часть может быть отделена от логики:

new TomSelect("#select", {
  render: {
    option: function(data, escape) {
      if (data.hidden) {
        return "";
      }

      return `<div>${escape(data.text)}</div>`;
    }
  }
});

Особенности:

  • пустая строка фактически убирает отображение элемента
  • логика скрытия переносится в слой представления
  • подходит для UI-условий без изменения данных

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

Опции могут оставаться видимыми, но становиться недоступными:

new TomSelect("#select", {
  options: [
    { value: "1", text: "Active" },
    { value: "2", text: "Locked", disabled: true }
  ]
});

Поведение:

  • disabled-элементы отображаются в списке
  • не могут быть выбраны
  • могут участвовать в кастомной визуализации

Дополнительно возможно динамическое переключение состояния через API:

const control = select.tomselect;
control.updateOption("2", { disabled: true });

Условная видимость через load и remote-фильтрацию

При асинхронной загрузке логика полностью переносится на сервер:

new TomSelect("#select", {
  load: function(query, callback) {
    fetch(`/api/items?q=${query}`)
      .then(res => res.json())
      .then(data => {
        callback(data.filter(x => x.allowed));
      });
  }
});

Модель поведения:

  • сервер возвращает полный или частичный набор
  • клиент применяет финальную фильтрацию
  • возможна реализация сложных бизнес-правил

Оптимизация через shouldLoad

Контроль загрузки снижает лишние запросы и скрывает опции до выполнения условий:

new TomSelect("#select", {
  shouldLoad: function(query) {
    return query.length > 2;
  }
});

Эффект:

  • список не запрашивается до выполнения условия
  • отсутствует промежуточное отображение пустых опций
  • усиливается контроль над моментом появления данных

Групповая условная видимость (optgroup)

Опции могут скрываться блоками:

new TomSelect("#select", {
  optgroups: [
    { value: "fruits", label: "Fruits", visible: true },
    { value: "vegetables", label: "Vegetables", visible: false }
  ]
});

Идея:

  • группы фильтруются целиком
  • вложенные опции наследуют состояние группы
  • удобно для контекстных интерфейсов

Контекстное скрытие при выборе значений

Поведение списка может изменяться после выбора:

new TomSelect("#select", {
  onItemAdd: function(value) {
    if (value === "admin") {
      this.clearOptions();
      this.addOption({ value: "restricted", text: "Restricted option" });
    }
  }
});

Механика:

  • выбор изменяет доступный набор
  • опции пересобираются динамически
  • реализуются сценарии зависимых списков

Условные правила через внешний state

Логика видимости часто выносится наружу:

const state = {
  isPremium: false
};

new TomSelect("#select", {
  score: function(search) {
    return function(item) {
      if (item.premium && !state.isPremium) return 0;
      return 1;
    };
  }
});

Принцип:

  • данные обогащаются флагами
  • фильтрация зависит от внешнего состояния
  • UI становится реактивным к бизнес-логике

Комбинирование механизмов фильтрации

В реальных сценариях используется несколько уровней одновременно:

  • searchField для базового поиска
  • score для приоритизации
  • load для серверной фильтрации
  • render для визуального скрытия
  • disabled для ограничения выбора

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