Доступ к API Tom Select

Доступ к API библиотеки Tom Select строится вокруг экземпляра компонента, который создаётся при инициализации и далее становится центральной точкой управления состоянием, данными и поведением селекта. Каждый вызов new TomSelect(...) возвращает объект, через который осуществляется полный контроль над компонентом.

При создании селекта экземпляр возвращается напрямую из конструктора:

const select = new TomSelect('#select-id', {
  create: true,
  maxItems: 5
});

Этот объект содержит весь публичный API. Однако в реальных приложениях часто требуется получить доступ к уже инициализированному экземпляру после создания. Tom Select сохраняет ссылку на инстанс внутри DOM-элемента:

const el = document.querySelector('#select-id');
const select = el.tomselect;

Свойство tomselect автоматически добавляется после инициализации и является основным способом доступа к API извне.

Если селект инициализируется динамически или через несколько модулей, проверка наличия экземпляра выполняется явно:

if (el.tomselect) {
  el.tomselect.open();
}

Основные методы управления значениями

API предоставляет набор методов для работы с выбранными значениями. Они различаются для одиночного и множественного выбора, но поведение унифицировано.

Установка значения

Метод setValue полностью заменяет текущее значение:

select.setValue('value1');

Для множественного выбора допускается массив:

select.setValue(['value1', 'value2']);

Важная особенность заключается в том, что метод синхронизирует внутреннее состояние, обновляет UI и вызывает связанные события изменения.

Получение значения

Для получения текущего состояния используется getValue:

const value = select.getValue();

Возвращаемый тип зависит от конфигурации:

  • строка при одиночном выборе
  • массив при maxItems > 1

Управление элементами списка

Tom Select позволяет динамически управлять набором опций без пересоздания компонента.

Добавление новых опций

Метод addOption добавляет элемент в список доступных значений:

select.addOption({
  value: 'new1',
  text: 'Новый элемент'
});

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

Добавление выбранного элемента

Чтобы одновременно добавить и выбрать значение, используется addItem:

select.addItem('new1');

При этом, если опция отсутствует, она может быть создана автоматически при включённой настройке create.

Удаление выбранных значений

Удаление осуществляется через removeItem:

select.removeItem('value1');

Метод изменяет только выбранные элементы, не затрагивая список опций.

Очистка выбора

Полная очистка выполняется через clear:

select.clear();

Это эквивалентно сбросу состояния без удаления доступных опций.

Управление интерфейсом

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

Открытие и закрытие списка

select.open();
select.close();

Эти методы управляют выпадающим меню напрямую, минуя пользовательские события.

Проверка состояния:

if (select.isOpen) {
  select.close();
}

Фокусировка и взаимодействие

Методы focus и blur управляют фокусом input-элемента внутри компонента:

select.focus();
select.blur();

Они полезны при программной навигации или интеграции с кастомными формами.

Обновление состояния интерфейса

Метод refreshOptions используется для пересчёта и перерисовки списка опций:

select.refreshOptions();

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

Работа с событиями через API

Tom Select предоставляет собственную систему событий, доступную через методы on и off.

Подписка на события

select.on('change', (value) => {
  console.log(value);
});

Отписка от событий

select.off('change');

Также возможно удаление конкретного обработчика при сохранении ссылки:

function handler(value) {
  console.log(value);
}

select.on('change', handler);
select.off('change', handler);

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

  • change — изменение значения
  • item_add — добавление элемента
  • item_remove — удаление элемента
  • dropdown_open — открытие списка
  • dropdown_close — закрытие списка
  • focus — получение фокуса
  • blur — потеря фокуса

Доступ к внутренним данным

Экземпляр содержит несколько свойств, отражающих текущее состояние:

select.items;   // выбранные значения
select.options; // доступные опции
select.settings; // конфигурация

Изменение этих структур напрямую не рекомендуется, но чтение используется для диагностики и синхронизации.

Пример:

console.log(select.items);
console.log(Object.keys(select.options));

Обновление и синхронизация данных

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

select.sync();

Метод используется при изменении оригинального <select> или внешнего источника данных.

Уничтожение экземпляра

Полное удаление компонента выполняется через destroy:

select.destroy();

После вызова:

  • DOM-структура восстанавливается к исходному виду
  • события удаляются
  • ссылка tomselect очищается

Проверка состояния после уничтожения:

if (!el.tomselect) {
  // экземпляр удалён
}

Управление опциями в реальном времени

Динамическое изменение данных часто требует комбинации методов API:

select.clear();
select.addOption({ value: 'a', text: 'A' });
select.addOption({ value: 'b', text: 'B' });
select.refreshOptions();
select.setValue('a');

Такой подход обеспечивает согласованность между внутренними данными и интерфейсом.

Программная интеграция с внешними источниками

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

fetch('/api/items')
  .then(res => res.json())
  .then(data => {
    data.forEach(item => {
      select.addOption(item);
    });

    select.refreshOptions();
  });

После обновления списка опций компонент автоматически отражает новые данные в выпадающем меню.

Особенности жизненного цикла API

Экземпляр Tom Select проходит несколько стадий:

  • инициализация
  • готовность к взаимодействию
  • активное состояние
  • разрушение

На каждом этапе доступ к API может отличаться. Например, до завершения инициализации свойства tomselect может быть недоступно.

Проверка готовности:

document.addEventListener('DOMContentLoaded', () => {
  const el = document.querySelector('#select-id');
  const select = el.tomselect;
});

Синхронные и асинхронные операции

Некоторые методы API работают синхронно (setValue, addItem), другие требуют последующего обновления интерфейса (refreshOptions). При интеграции с асинхронными источниками важно учитывать задержки обновления данных.

Типичный сценарий:

async function load() {
  const res = await fetch('/api');
  const data = await res.json();

  select.clearOptions();

  data.forEach(item => select.addOption(item));

  select.refreshOptions();
}

Прямое взаимодействие с DOM через API

Несмотря на наличие обёртки, экземпляр предоставляет доступ к корневому элементу:

select.wrapper;
select.control;
select.dropdown;

Эти свойства используются для низкоуровневой кастомизации интерфейса, включая стилизацию и внедрение дополнительных элементов управления.

Расширенное управление состоянием

API позволяет комбинировать методы для построения сложных сценариев поведения:

select.on('item_add', (value) => {
  if (select.items.length > 3) {
    select.removeItem(select.items[0]);
  }
});

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