Внутренняя логика отображения списка опций в Tom Select строится вокруг трёх источников данных: исходного массива опций, текущего поискового запроса и состояния инстанса. Каждый элемент проходит через цепочку фильтрации перед тем, как попасть в выпадающий список.
Ключевое поведение:
optionsgetSearchOptions()Условная видимость реализуется не как отдельная сущность, а как комбинация фильтрации, рендера и динамического управления коллекцией опций.
Основной механизм скрытия опций — настройка поля поиска:
new TomSelect("#select", {
searchField: ["title", "code"]
});
Каждая опция сравнивается с запросом пользователя по указанным полям. Если совпадений нет, элемент не попадает в результат.
Особенности поведения:
scoreМеханизм ранжирования позволяет не просто скрывать, а управлять приоритетом отображения:
new TomSelect("#select", {
score: function(search) {
return function(item) {
if (item.type === "disabled_group") return 0;
return item.title.includes(search) ? 10 : 1;
};
}
});
Принцип работы:
Это даёт гибкость, аналогичную фильтрам в 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);
}
});
Суть подхода:
Поведение списка может зависеть от текущего ввода:
new TomSelect("#select", {
onType: function(str) {
if (str.length < 3) {
this.clearOptions();
return;
}
}
});
Механизм позволяет:
Визуальная часть может быть отделена от логики:
new TomSelect("#select", {
render: {
option: function(data, escape) {
if (data.hidden) {
return "";
}
return `<div>${escape(data.text)}</div>`;
}
}
});
Особенности:
Опции могут оставаться видимыми, но становиться недоступными:
new TomSelect("#select", {
options: [
{ value: "1", text: "Active" },
{ value: "2", text: "Locked", disabled: true }
]
});
Поведение:
Дополнительно возможно динамическое переключение состояния через API:
const control = select.tomselect;
control.updateOption("2", { disabled: true });
При асинхронной загрузке логика полностью переносится на сервер:
new TomSelect("#select", {
load: function(query, callback) {
fetch(`/api/items?q=${query}`)
.then(res => res.json())
.then(data => {
callback(data.filter(x => x.allowed));
});
}
});
Модель поведения:
Контроль загрузки снижает лишние запросы и скрывает опции до выполнения условий:
new TomSelect("#select", {
shouldLoad: function(query) {
return query.length > 2;
}
});
Эффект:
Опции могут скрываться блоками:
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" });
}
}
});
Механика:
Логика видимости часто выносится наружу:
const state = {
isPremium: false
};
new TomSelect("#select", {
score: function(search) {
return function(item) {
if (item.premium && !state.isPremium) return 0;
return 1;
};
}
});
Принцип:
В реальных сценариях используется несколько уровней одновременно:
Так формируется многослойная система условной видимости, где каждый слой отвечает за отдельный аспект поведения списка, а итоговый результат определяется их совокупным действием.