Анимации и переходы

Tom Sel ect представляет собой JavaScript-библиотеку для расширения стандартного элемента <select> с целью добавления функциональности поиска, множественного выбора, динамической подгрузки данных и кастомного отображения элементов. Библиотека построена с акцентом на минимальную зависимость от внешних фреймворков, гибкость API и расширяемость через плагины.

Основная идея заключается в замене ограниченного поведения нативного HTML <select> на управляемый компонент с поддержкой:

  • полнотекстового поиска по опциям
  • асинхронной загрузки данных
  • создания новых элементов на лету
  • множественного выбора с тегами
  • кастомного рендера элементов
  • группировки (optgroup)
  • событийной модели управления состоянием

Подключение и базовая инициализация

Подключение Tom Select возможно через npm или CDN.

Установка через npm

npm install tom-select

Импорт в модульной системе

import TomSelect fr om "tom-select";
import "tom-select/dist/css/tom-select.css";

Инициализация на существующем select

<select id="select-beast">
  <option value="1">Dragon</option>
  <option value="2">Unicorn</option>
  <option value="3">Phoenix</option>
</select>
new TomSelect("#select-beast");

После инициализации DOM-элемент заменяется управляемым компонентом с отдельной структурой ввода, списка и контейнеров выбранных значений.

Конфигурация экземпляра

Конструктор принимает второй аргумент с набором опций, определяющих поведение компонента.

new TomSelect("#select-beast", {
  maxItems: 3,
  create: false,
  searchField: ["text", "value"],
  placeholder: "Выбор сущности"
});

Основные параметры

  • maxItems — ограничение количества выбранных элементов
  • create — разрешение создания новых опций
  • searchField — поля для поиска
  • placeholder — текст-заполнитель
  • valueField, labelField, options — структура данных при динамической инициализации

Работа с данными

Tom Select поддерживает два основных режима данных: статический и динамический.

Статический список

new TomSelect("#select-beast", {
  options: [
    { id: 1, name: "Lion" },
    { id: 2, name: "Tiger" }
  ],
  valueField: "id",
  labelField: "name",
  searchField: "name"
});

Асинхронная загрузка данных

Поддерживается загрузка через load callback.

new TomSelect("#select-beast", {
  valueField: "id",
  labelField: "title",
  searchField: "title",
  load: function(query, callback) {
    fetch(`/api/items?q=${encodeURIComponent(query)}`)
      .then(res => res.json())
      .then(data => callback(data))
      .catch(() => callback());
  }
});

Асинхронная модель предполагает явный вызов callback для завершения загрузки, что позволяет интегрировать любые источники данных.

Механизм создания новых элементов

Функциональность создания новых опций активируется через параметр create.

new TomSelect("#select-beast", {
  create: true
});

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

new TomSelect("#select-beast", {
  create: function(input) {
    return {
      value: input.toLowerCase(),
      text: input
    };
  }
});

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

Множественный выбор и теги

Режим множественного выбора активируется через HTML-атрибут multiple или опцию maxItems.

<select id="tags" multiple>
  <option value="js">JavaScript</option>
  <option value="ts">TypeScript</option>
</select>
new TomSelect("#tags", {
  maxItems: null
});

При множественном выборе элементы отображаются в виде токенов, управляемых через внутренний state-компонент.

Поисковый механизм

Поиск осуществляется по полям, заданным в searchField. Алгоритм основан на фильтрации строк и может быть расширен.

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

Поддерживается кастомизация поведения поиска через переопределение метода score.

new TomSelect("#select-beast", {
  score: function(search) {
    return function(item) {
      return item.label.toLowerCase().includes(search.toLowerCase())
        ? 1
        : 0;
    };
  }
});

Рендеринг элементов (templates)

Tom Select предоставляет систему шаблонов для управления отображением элементов.

Основные шаблоны

  • item — выбранный элемент
  • option — элемент списка
  • dropdown — контейнер списка
  • optgroup_header — заголовок группы
new TomSelect("#select-beast", {
  render: {
    option: function(data, escape) {
      return `<div>${escape(data.text)}</div>`;
    },
    item: function(data, escape) {
      return `<div class="item">${escape(data.text)}</div>`;
    }
  }
});

Функция escape используется для защиты от XSS при вставке пользовательских данных.

Группировка данных (Optgroups)

Поддерживается стандартная HTML-модель группировки:

new TomSelect("#select-beast", {
  optgroups: [
    { value: "mammals", label: "Mammals" },
    { value: "birds", label: "Birds" }
  ],
  options: [
    { value: "lion", text: "Lion", optgroup: "mammals" },
    { value: "eagle", text: "Eagle", optgroup: "birds" }
  ]
});

Группы визуально разделяют список и позволяют структурировать большие наборы данных.

Событийная модель

Компонент предоставляет набор событий для отслеживания состояния.

Основные события

  • change — изменение выбранных значений
  • item_add — добавление элемента
  • item_remove — удаление элемента
  • dropdown_open
  • dropdown_close
  • focus
  • blur
const ts = new TomSelect("#select-beast");

ts.on("change", value => {
  console.log(value);
});

События позволяют синхронизировать состояние с внешними системами управления данными.

API управления экземпляром

После инициализации доступен программный интерфейс управления.

const ts = new TomSelect("#select-beast");

Основные методы

  • setValue(value) — установка значения
  • getValue() — получение текущего значения
  • addItem(value) — добавление элемента
  • removeItem(value) — удаление элемента
  • clear() — очистка выбора
  • clearOptions() — очистка списка опций
  • destroy() — уничтожение экземпляра
ts.setValue(["1", "2"]);
ts.addItem("3");
ts.clear();

Работа с состоянием и внутренней моделью

Внутреннее состояние Tom Select основано на синхронизации:

  • массива options
  • выбранных значений
  • отфильтрованных результатов
  • DOM-структуры

Любое изменение проходит через централизованные методы обновления, что исключает прямое вмешательство в DOM без синхронизации состояния.

Плагины и расширяемость

Архитектура поддерживает подключение плагинов для расширения функциональности.

Пример использования плагина

new TomSelect("#select-beast", {
  plugins: ["remove_button"]
});

Плагины могут:

  • модифицировать DOM
  • добавлять события
  • изменять поведение поиска
  • расширять рендеринг

Асинхронные сценарии и debounce

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

new TomSelect("#select-beast", {
  loadThrottle: 300
});

Это снижает количество запросов при вводе текста и улучшает производительность при интеграции с серверными поисковыми системами.

Кастомизация CSS и структура DOM

Компонент генерирует собственную DOM-структуру:

  • wrapper контейнер
  • input поле
  • dropdown список
  • item элементы
  • control блок

Классы элементов позволяют полностью переопределять визуальное представление через CSS без изменения логики.

.ts-control {
  border: 1px solid #ccc;
}

.ts-dropdown {
  max-height: 300px;
  overflow: auto;
}

Интеграция с внешними системами данных

Tom Select часто используется как слой UI поверх API:

  • REST сервисы
  • GraphQL источники
  • локальные JSON структуры
  • IndexedDB

Типичная схема интеграции включает:

  1. ввод запроса
  2. debounce
  3. запрос к API
  4. преобразование данных
  5. передача через callback

Производительность и оптимизация

При больших списках ключевое значение имеет:

  • ограничение числа отображаемых элементов
  • виртуализация (через плагины или кастомные решения)
  • debounce запросов
  • минимизация DOM-операций

Оптимизация достигается через контроль load, score и render функций, где можно снижать вычислительную сложность поиска и рендера.

Поведение при фокусе и вводе

Компонент управляет состояниями:

  • открытие dropdown при фокусе
  • закрытие при blur
  • удержание выбранных значений при вводе
  • автоматическое позиционирование списка

Взаимодействие основано на обработчиках событий клавиатуры и мыши, включая навигацию стрелками и выбор через Enter.