Tom Select: умные списки и 6 интерактивных примеров
Поиск в списке, фильтры по темам, план работ, зависимые поля, собственные теги и команда. Шесть живых примеров с результатом, кодом и исходниками.

Обычный список подходит, пока в нём несколько коротких пунктов. Когда нужно найти запись по названию, выбрать несколько тем или связать категорию с шаблоном, одной стрелки раскрытия уже мало. При этом красивое поле само по себе не делает форму полезной: после выбора должно быть понятно, что изменилось и какие данные готовы для следующего действия.
Tom Select добавляет к полям поиск, множественный выбор, создание новых вариантов и группировку. Эти возможности настраиваются через параметры searchField, maxItems, create и optgroups; полный перечень есть в официальной документации. Ниже используем настоящую библиотеку и собственные учебные сценарии, а не картинки чужих примеров.
Что будем проверять
В каждом примере есть три части: список, действие пользователя и связанный результат. Можно набрать запрос, удалить выбранный пункт, проверить ограничения и посмотреть JSON. Записи каталога, оценки времени и участники команды вымышлены; поиск работает только по наборам этой мастерской, а не по всему сайту.
- Поиск материала: выбор одной записи раскрывает её карточку.
- Фильтр по темам: несколько значений меняют выдачу по правилу «Любая» или «Все».
- План работ: выбранные задачи складываются в список с оценкой времени.
- Связанные списки: раздел определяет доступные шаблоны.
- Собственные теги: новые значения проходят нормализацию и проверку.
- Подбор команды: число людей и набор ролей проверяются отдельно.
Живая мастерская Tom Select
Нажмите название сценария, измените выбор и посмотрите результат рядом. Кнопка «Развернуть» открывает мастерскую на всё окно; Escape возвращает встроенный режим. У каждого примера есть сброс, очистка, текущий JSON, журнал последних событий и готовый JavaScript.
Действия выполняются локально: мастерская не отправляет заявки, не приглашает участников и не создаёт теги в WordPress. Перезагрузка страницы очищает состояние. Скачанный JSON содержит результат выбранного примера, но не предназначен для обратной загрузки или восстановления всей мастерской.
Шесть прикладных сценариев
Поиск материала: от названия к карточке
Очистите выбор и начните вводить «клавиатуры». Выберите найденную запись мышью или клавишей Enter: рядом появятся название, описание и учебное время чтения. Затем введите заведомо отсутствующий запрос и проверьте сообщение пустой выдачи. Оно должно подсказывать следующий шаг, а не оставлять пустой прямоугольник.
Вариант хранит стабильный id, отдельный title и поле topic. Поиск идёт по заголовку и теме, а результат определяется по идентификатору. Разделение значения и подписи задаётся через valueField и labelField в настройках Tom Select. Так переименование материала не требует менять его внутренний ключ.
Темы: «Любая» и «Все» дают разные результаты
Оставьте CSS и добавьте «Доступность». С правилом «Любая» мастерская показывает записи хотя бы по одной теме. С правилом «Все» остаются только записи, у которых есть обе темы одновременно. Добавьте «Вёрстка», чтобы получить пустую выдачу, затем снимите ограничения кнопкой очистки.
Tom Select здесь только собирает выбранные идентификаторы. Пересечение и объединение рассчитывает наша функция: every() проверяет все темы, some() хотя бы одну. Это не настройка searchConjunction: у библиотеки она относится к словам поискового запроса внутри списка, как объясняет раздел Data / Searching.
const matches = catalogue.filter(article =>
selected.length === 0 ||
(mode === 'all'
? selected.every(tag => article.tags.includes(tag))
: selected.some(tag => article.tags.includes(tag)))
);
Состав работ: выбор меняет план, а не только поле
В начальном плане стоят «Уточнить сценарий» и «Собрать вёрстку». Добавьте «Подключить логику»: сумма учебных оценок станет 125 минут. Удаление пункта исключает его из расчёта. Стрелки в результате меняют порядок задач; крайние недоступные направления заблокированы.
Минуты в примере придуманы для демонстрации. Такой интерфейс можно использовать как конструктор чек-листа или состава заявки, но не выдавать сумму условных оценок за обещание реального срока. Перестановка у нас реализована через изменение массива и setValue(); метод описан в API библиотеки.
Связанные списки: нельзя сохранить несовместимую пару
В разделе «Формы» выберите «Обратная связь». Затем смените раздел на «Контент»: прежний шаблон должен исчезнуть, а подготовка результата стать недоступной до нового выбора. Укажите «Вопрос и ответ», чтобы получить два поля нового шаблона. В «Архиве» вариантов нет, поэтому второй список заблокирован и рядом объясняется причина.
Последовательность важна: сначала снимаем выбранное значение, затем очищаем доступные варианты, добавляем новый набор и включаем либо блокируем поле. По документации clearOptions() удаляет невыбранные варианты, поэтому перед полной заменой нужен clear() (Option Methods). Перед отправкой сервер должен ещё раз проверить, что шаблон действительно относится к переданному разделу.
child.clear(true);
child.clearOptions();
const rows = templates.filter(t => t.category === category);
child.addOptions(rows);
rows.length ? child.enable() : child.disable();
Проверить сброс зависимого поля
Собственные теги: создание с ограничениями
Введите «Новая тема» и нажмите Enter. В черновике появится нормализованный тег «новая тема»: начальные и конечные пробелы удаляются, повторные пробелы схлопываются, регистр приводится к нижнему. Попробуйте HTML или один символ: новый тег не должен добавиться. Максимум выбранных тегов в этом примере равен пяти.
Нормализация и регулярное выражение принадлежат нашему приложению. Tom Select предоставляет для этого create и createFilter; параметр persist: false убирает созданный пользователем вариант после снятия выбора (General Configuration). Не путайте эту настройку с хранением между посещениями: никакого постоянного хранилища у нашей мастерской нет.
Добавить и проверить свои теги
Команда: лимит количества не заменяет проверку ролей
По умолчанию выбраны редактор и разработчик. Добавьте Марию: появится проверяющий, и состав станет готовым. Теперь уберите её и выберите второго разработчика. Людей по-прежнему трое, но нужной роли нет, поэтому подготовка результата будет недоступна. Денис отмечен как отсутствующий и недоступен для выбора.
Группы делают справочник понятнее, maxItems ограничивает количество, а disabledField отмечает недоступные варианты (документация настроек). Наличие всех ролей проверяет отдельная функция приложения. В реальном сервисе запрет назначения и права доступа обязательно проверяются на сервере: заблокированный пункт интерфейса не является защитой API.
Подключение и готовый код
В мастерской зафиксирована версия 2.6.2. Для проекта со сборщиком установите пакет, подключите JavaScript и CSS, затем создайте экземпляр на существующем поле. Для множественного выбора в наших примерах используется <select multiple>.
npm install tom-select@2.6.2
import TomSelect from 'tom-select';
import 'tom-select/dist/css/tom-select.default.css';
const control = new TomSelect('#choice', {
options: [
{ id: 'forms', title: 'Формы' },
{ id: 'content', title: 'Контент' }
],
valueField: 'id',
labelField: 'title',
searchField: ['title'],
maxItems: 1,
create: false
});
control.on('change', () => {
console.log(control.getValue());
});
Тип результата getValue() зависит от исходного элемента: для select multiple возвращается массив, в других случаях строка. При удалении интерфейса вызывайте destroy(), чтобы убрать экземпляр и его обработчики; оба поведения описаны в API Tom Select. Мастерская уничтожает экземпляры перед переключением сценария и восстанавливает нужный выбор из памяти вкладки.
В блоке «Готовый JavaScript» есть отдельный минимальный пример для каждой задачи. Комментарий в начале указывает необходимую HTML-разметку; связанная логика выводит результат в pre. Полный ZIP содержит сам интерфейс, наборы данных, стили, README, lock-файл и лицензию библиотеки. Это удобнее одного фрагмента, если нужно повторить поведение страницы целиком.
Что проверить перед внедрением
- Идентификаторы: передавайте стабильные ключи, а не только человекочитаемые подписи.
- Клавиатура: проверьте Tab, ввод, Enter, удаление и Escape в вашей форме и модальном окне.
- Маленький экран: длинные названия и выбранные теги не должны растягивать страницу. В нашей мастерской раскрытый список находится в потоке документа, чтобы не обрезаться границами iframe.
- Пустое состояние: отличайте отсутствие совпадений от отсутствия доступных вариантов и от ошибки загрузки.
- Согласованность: при смене родительского поля сбрасывайте несовместимый выбор, а подготовленный результат пересчитывайте после изменений.
- Безопасный вывод: экранируйте данные в шаблонах. Функция
escapeпредусмотрена в render-callback; её важность отмечена в разделе Render Templates. - Серверная проверка: повторяйте ограничения по количеству, допустимым значениям и правам. Виджет не заменяет проверку бизнес-правил.
Для длинного справочника может понадобиться серверный поиск. Tom Select поддерживает загрузку через load(query, callback), а shouldLoad позволяет задать условие начала запроса (официальные примеры удалённых данных). В эту мастерскую сетевую загрузку намеренно не включали: все примеры воспроизводимы на небольших локальных массивах.
Начните с простого списка и добавляйте возможности по задаче. Если нужен только выбор из трёх пунктов, обычный select может оказаться достаточным; когда важны поиск, несколько значений и связанный результат, попробуйте соответствующую сцену выше и оцените поведение до внедрения.


