Группы (optgroup) в Tom Select используются для
логического разделения набора опций на категории. Такой подход особенно
полезен при работе с большими списками данных:
Tom Select поддерживает как работу с обычными HTML-группами
<optgroup>, так и динамическое создание групп через
JavaScript API.
Базовый способ создания групп основан на стандартном HTML-элементе
<optgroup>.
<select id="frameworks" multiple>
<optgroup label="Frontend">
<option value="vue">Vue</option>
<option value="react">React</option>
<option value="svelte">Svelte</option>
</optgroup>
<optgroup label="Backend">
<option value="node">Node.js</option>
<option value="laravel">Laravel</option>
<option value="django">Django</option>
</optgroup>
</select>
Инициализация:
new TomSelect("#frameworks");
После инициализации Tom Select автоматически распознаёт группы и отображает их как отдельные секции выпадающего списка.
Tom Select преобразует HTML-группы в собственную внутреннюю структуру:
<div class="optgroup">
<div class="optgroup-header">Frontend</div>
<div data-value="vue" class="option">
Vue
</div>
<div data-value="react" class="option">
React
</div>
</div>
Это позволяет:
Tom Select поддерживает декларативное создание групп через параметры:
optionsoptgroupsoptgroupFieldnew TomSelect("#select", {
optgroupField: "category",
optgroups: [
{
value: "frontend",
label: "Frontend"
},
{
value: "backend",
label: "Backend"
}
],
options: [
{
value: "vue",
text: "Vue",
category: "frontend"
},
{
value: "react",
text: "React",
category: "frontend"
},
{
value: "node",
text: "Node.js",
category: "backend"
}
]
});
optgroupField определяет поле объекта, которое содержит
идентификатор группы.
optgroupField: "category"
Внутри опции:
{
value: "react",
text: "React",
category: "frontend"
}
Tom Select определяет:
frontend;optgroups.Каждая группа представляет собой объект:
{
value: "frontend",
label: "Frontend"
}
| Поле | Назначение |
|---|---|
value |
внутренний идентификатор |
label |
отображаемое название |
optgroups: [
{
value: "frontend",
label: "Frontend"
},
{
value: "backend",
label: "Backend"
},
{
value: "database",
label: "Databases"
}
]
Связь выполняется через поле, указанное в
optgroupField.
options: [
{
value: "mysql",
text: "MySQL",
category: "database"
}
]
Tom Select поддерживает массив групп.
new TomSelect("#select", {
optgroupField: "groups",
optgroupValueField: "id",
optgroupLabelField: "name",
optgroups: [
{
id: "js",
name: "JavaScript"
},
{
id: "backend",
name: "Backend"
}
],
options: [
{
value: "node",
text: "Node.js",
groups: ["js", "backend"]
}
]
});
По умолчанию Tom Select ожидает:
{
value: "...",
label: "..."
}
Но структура может быть изменена.
Указывает поле идентификатора.
optgroupValueField: "id"
Определяет поле отображаемого имени.
optgroupLabelField: "title"
new TomSelect("#select", {
optgroupField: "group",
optgroupValueField: "id",
optgroupLabelField: "title",
optgroups: [
{
id: "frontend",
title: "Frontend"
}
],
options: [
{
value: "vue",
text: "Vue",
group: "frontend"
}
]
});
Tom Select позволяет создавать группы после инициализации.
const control = new TomSelect("#select");
control.addOptionGroup("backend", {
label: "Backend"
});
control.addOption({
value: "nestjs",
text: "NestJS",
optgroup: "backend"
});
control.removeOptionGroup("backend");
После удаления:
Группы можно перезаписывать повторным вызовом:
control.addOptionGroup("frontend", {
label: "Frontend Frameworks"
});
control.clearOptionGroups();
Удаляются:
Опции при этом могут остаться.
Tom Select поддерживает сортировку групп через
lockOptgroupOrder.
new TomSelect("#select", {
lockOptgroupOrder: true
});
Если параметр включён:
Tom Select может менять порядок групп динамически:
Tom Select автоматически скрывает группы без элементов.
Например:
{
value: "empty",
label: "Empty Group"
}
Если в группе нет опций — заголовок не отображается.
Через render.optgroup_header можно полностью изменить
отображение заголовков.
new TomSelect("#select", {
render: {
optgroup_header(data, escape) {
return `
<div class="group-header">
Категория: ${escape(data.label)}
</div>
`;
}
}
});
new TomSelect("#select", {
render: {
optgroup_header(data) {
return `
<div class="group-header">
${data.label}
<span class="count">
(${data.$order})
</span>
</div>
`;
}
}
});
.ts-dropdown .optgroup-header {
font-weight: bold;
padding: 10px;
background: #f3f3f3;
}
.ts-dropdown .optgroup .option {
padding-left: 20px;
}
Tom Select не поддерживает настоящие вложенные группы:
<optgroup>
<optgroup>
Подобная структура недоступна в HTML-спецификации.
Вложенность обычно реализуют:
options: [
{
value: "vue2",
text: "— Vue 2",
group: "frontend"
},
{
value: "vue3",
text: "— Vue 3",
group: "frontend"
}
]
Поиск Tom Select работает:
Группы не ограничивают область поиска.
При вводе:
vue
Tom Select:
Группы особенно полезны при загрузке данных с сервера.
[
{
"value": "vue",
"text": "Vue",
"category": "frontend"
},
{
"value": "laravel",
"text": "Laravel",
"category": "backend"
}
]
new TomSelect("#select", {
valueField: "value",
labelField: "text",
optgroupField: "category",
optgroups: [
{
value: "frontend",
label: "Frontend"
},
{
value: "backend",
label: "Backend"
}
],
load(query, callback) {
fetch(`/api/search?q=${query}`)
.then(response => response.json())
.then(data => callback(data));
}
});
Группы можно генерировать динамически.
fetch("/api/categories")
.then(response => response.json())
.then(groups => {
groups.forEach(group => {
control.addOptionGroup(group.id, {
label: group.name
});
});
});
После выбора элемента:
Группировка работает только внутри dropdown.
Группы особенно полезны в режиме множественного выбора:
new TomSelect("#select", {
maxItems: null
});
При большом количестве элементов категории значительно улучшают навигацию.
Tom Select позволяет отключать группы.
optgroups: [
{
value: "premium",
label: "Premium",
disabled: true
}
]
Отключённая группа:
.ts-dropdown .optgroup.disabled .optgroup-header {
opacity: 0.5;
}
При работе с тысячами элементов рекомендуется:
render.optgroup_header.Ошибка:
optgroupField: "category"
Но в option:
{
group: "frontend"
}
Группы не будут работать.
{
value: "vue",
text: "Vue",
category: "frontend"
}
Если группа frontend не зарегистрирована в
optgroups, элемент может отображаться некорректно.
Ошибка:
{
value: "frontend"
}
повторяется несколько раз.
Идентификаторы групп должны быть уникальными.
new TomSelect("#products", {
optgroupField: "category",
optgroups: [
{
value: "phones",
label: "Смартфоны"
},
{
value: "laptops",
label: "Ноутбуки"
},
{
value: "tablets",
label: "Планшеты"
}
],
options: [
{
value: "iphone",
text: "iPhone 15",
category: "phones"
},
{
value: "macbook",
text: "MacBook Pro",
category: "laptops"
},
{
value: "ipad",
text: "iPad Air",
category: "tablets"
}
]
});
const control = new TomSelect("#skills", {
optgroupField: "type"
});
const groups = [
["frontend", "Frontend"],
["backend", "Backend"],
["devops", "DevOps"]
];
groups.forEach(group => {
control.addOptionGroup(group[0], {
label: group[1]
});
});
control.addOption({
value: "docker",
text: "Docker",
type: "devops"
});
control.refreshOptions(false);
Tom Select хранит группы внутри:
control.optgroups
console.log(control.optgroups);
Результат:
{
frontend: {
label: "Frontend"
},
backend: {
label: "Backend"
}
}
if (control.optgroups.backend) {
console.log("Группа существует");
}
control.optgroups.backend.label = "Server Side";
После изменения:
control.refreshOptions(false);
После массовых изменений рекомендуется:
control.clearCache();
control.refreshOptions(false);
Это заставляет Tom Select: