Проверка работоспособности

Работоспособность Tom Sel ect начинается с корректного создания экземпляра и привязки к DOM-элементу. Основной этап диагностики — подтверждение того, что исходный <select> действительно был преобразован в управляемый компонент.

<select id="cities" multiple>
  <option value="1">Алматы</option>
  <option value="2">Астана</option>
</select>
const element = document.getElementById('cities');

const tom = new TomSelect(element, {
  maxItems: 3
});

Ключевой признак успешной инициализации — наличие свойства tomselect у DOM-узла:

console.log(element.tomselect);

Если объект отсутствует, проверяются типовые причины:

  • скрипт выполнен до загрузки DOM
  • неверный селектор
  • повторная инициализация без destroy()
  • элемент не является <select> или <input>

Дополнительная проверка через внутренний экземпляр:

console.log(tom instanceof TomSelect);

Проверка состояния экземпляра

После инициализации важна верификация внутреннего состояния: значения, список опций и синхронизация с DOM.

tom.getValue(); // текущее значение
tom.options;    // доступные опции
tom.items;      // выбранные элементы

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

Корректное обновление состояния выполняется через API:

tom.setValue(['1', '2']);
tom.clear();
tom.refreshItems();

Проверка событий жизненного цикла

События Tom Select используются для контроля корректности взаимодействий и диагностики поведения интерфейса.

tom.on('initialize', () => {
  console.log('инициализация завершена');
});

tom.on('change', (value) => {
  console.log('значение изменено', value);
});

tom.on('item_add', (value) => {
  console.log('добавлен элемент', value);
});

tom.on('item_remove', (value) => {
  console.log('удален элемент', value);
});

Отсутствие событий change или item_add при пользовательских действиях обычно указывает на:

  • блокировку поля (disabled)
  • перехват событий сторонним скриптом
  • конфликт с кастомной формой

Проверка загрузки данных (remote mode)

При использовании асинхронной подгрузки важно контролировать корректность функции load.

const tom = new TomSelect('#remote', {
  valueField: 'id',
  labelField: 'title',
  searchField: 'title',
  load: function(query, callback) {
    fetch(`/api/items?q=${encodeURIComponent(query)}`)
      .then(res => res.json())
      .then(callback)
      .catch(() => callback());
  }
});

Диагностические точки:

  • вызывается ли load при вводе текста
  • приходит ли корректный JSON
  • вызывается ли callback
  • не блокируется ли Promise

Ошибка отсутствия callback() приводит к зависанию интерфейса без обновления списка.

Проверка интеграции с формами

Tom Select должен корректно синхронизироваться с HTML-формой при отправке.

<form id="form">
  <select id="tags" name="tags[]" multiple>
    <option value="js">JavaScript</option>
    <option value="ts">TypeScript</option>
  </select>
  <button type="submit">Отправить</button>
</form>

Проверка отправляемых данных:

document.getElementById('form').addEventListener('submit', (e) => {
  e.preventDefault();
  const data = new FormData(e.target);
  console.log(data.getAll('tags[]'));
});

Типовые проблемы:

  • отсутствие name у <select>
  • использование optgroup без корректных значений
  • кастомные изменения через setValue без обновления формы

Проверка повторной инициализации

Частая ошибка — создание нескольких экземпляров на одном элементе.

Признак:

  • дублирование UI
  • некорректные события
  • утечка памяти

Проверка:

if (element.tomselect) {
  element.tomselect.destroy();
}

const tom = new TomSelect(element);

Метод destroy() восстанавливает исходный <select> и удаляет слушатели событий.

Проверка работы с отключенным состоянием

tom.disable();
tom.enable();

Проверка включает:

  • невозможность выбора
  • блокировку ввода
  • корректное отображение состояния UI

Если визуальная блокировка отсутствует, проверяется конфликт CSS или переопределение классов.

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

При использовании render важно убедиться, что шаблоны возвращают валидный HTML.

new TomSelect('#users', {
  render: {
    option: (data) => {
      return `<div>${data.name}</div>`;
    },
    item: (data) => {
      return `<span>${data.name}</span>`;
    }
  }
});

Диагностика:

  • отсутствие HTML-строк в результате
  • undefined в UI
  • ошибки при вставке SVG/HTML

Проверка производительности

При больших наборах данных основная проблема — деградация скорости открытия и поиска.

Контрольные параметры:

  • время реакции при вводе
  • задержка открытия dropdown
  • потребление памяти при частых обновлениях

Практический тест:

console.time('update');

for (let i = 0; i < 1000; i++) {
  tom.addOption({ value: i, text: `Item ${i}` });
}

console.timeEnd('update');

Замедление указывает на необходимость оптимизации:

  • ограничение количества опций
  • использование серверной фильтрации
  • очистка неиспользуемых элементов

Проверка совместимости с внешними изменениями DOM

Tom Select не отслеживает внешние изменения <option> автоматически.

element.add(new Option('Новый элемент', 'new'));
tom.sync();

Если sync() не вызывается, UI и DOM расходятся.

Проверка:

  • добавление/удаление <option>
  • синхронизация через API
  • обновление после AJAX-загрузки

Проверка ошибок и исключений

Критически важно отслеживать ошибки инициализации и выполнения:

try {
  new TomSelect('#broken', {});
} catch (e) {
  console.error('Ошибка Tom Select:', e);
}

Типовые источники ошибок:

  • несуществующий элемент
  • некорректный valueField
  • пустые данные в load
  • конфликт с другими библиотеками форм

Проверка через автоматизированное тестирование

Unit-тестирование (Jest + JSDOM)

import TomSelect fr om 'tom-select';

test('инициализация select', () => {
  document.body.innerHTML = `
    <select id="test">
      <option value="1">A</option>
    </select>
  `;

  const el = document.getElementById('test');
  const ts = new TomSelect(el);

  expect(el.tomselect).toBeDefined();
  expect(ts.getValue()).toBe('');
});

E2E тестирование (Playwright/Cypress)

Проверяется:

  • открытие dropdown
  • выбор элемента
  • отправка формы
  • фильтрация

Основной критерий — соответствие поведения пользователя и состояния DOM.

Проверка корректности очистки ресурсов

При удалении компонента важно убедиться, что слушатели событий удалены:

tom.destroy();
console.log(element.tomselect); // undefined

Признаки утечек:

  • сохраняющиеся события
  • повторное срабатывание обработчиков
  • рост потребления памяти при повторной инициализации

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

В динамических интерфейсах (SPA) компонент может создаваться и уничтожаться многократно.

Проверяется:

  • стабильность повторной инициализации
  • отсутствие дублирования DOM
  • корректное восстановление состояния после destroy()
function recreate() {
  if (element.tomselect) {
    element.tomselect.destroy();
  }
  return new TomSelect(element);
}

Надёжная работа Tom Select в реальных приложениях определяется не только фактом инициализации, но и устойчивостью поведения при изменениях данных, повторных рендерах и асинхронных сценариях.