Перейти к содержимому
Поиск
Разработка

Tom Select: умные списки и 6 интерактивных примеров

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

Александр Некрасов
Tom Select: умные списки в интерфейсе, раскрытый список и теги на тёмно-бирюзовом фоне

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

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 может оказаться достаточным; когда важны поиск, несколько значений и связанный результат, попробуйте соответствующую сцену выше и оцените поведение до внедрения.