Удаление выбранных элементов

Поведение удаления выбранных значений в Tom Select опирается на внутреннюю модель данных, где каждый выбранный элемент представлен как объект с уникальным value. Управление удалением реализуется как на уровне API, так и через пользовательский интерфейс, а также через события и плагины. Гибкость механизма позволяет использовать компонент как в простых формах, так и в сложных интерфейсах с асинхронными источниками данных и кастомной логикой блокировки.


Базовое удаление выбранного элемента

Основной способ удаления значения из текущего набора — метод removeItem.

const tom = new TomSelect('#select', {
  plugins: ['remove_button']
});

tom.removeItem('value1');

Метод принимает значение (value), которое соответствует value option элемента. После вызова:

  • элемент удаляется из массива выбранных значений
  • обновляется DOM
  • пересчитывается состояние input
  • инициируется событие изменения

Важно учитывать, что сравнение выполняется строго по значению, поэтому тип данных должен совпадать (строка/число).


Удаление без всплытия событий (silent mode)

В сценариях, где требуется массовая синхронизация или обновление состояния без лишних триггеров, используется подавление событий:

tom.removeItem('value1', true);

Флаг silent = true отключает генерацию событий change и связанных обработчиков. Это критично при:

  • пакетных обновлениях
  • синхронизации с внешним state manager (Redux, Vuex)
  • восстановлении состояния формы

Удаление нескольких элементов

Удаление нескольких значений выполняется через последовательные вызовы:

['value1', 'value2', 'value3'].forEach(val => {
  tom.removeItem(val);
});

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

['value1', 'value2', 'value3'].forEach(val => {
  tom.removeItem(val, true);
});

tom.trigger('change');

Такой подход минимизирует перерасчёт DOM и предотвращает множественные перерендеры.


Очистка всех выбранных значений

Для полного сброса состояния используется метод clear.

tom.clear();

Он удаляет все выбранные элементы одновременно и возвращает компонент в исходное состояние.

Особенности поведения:

  • список выбранных элементов становится пустым
  • UI обновляется мгновенно
  • активируется событие change

В отличие от ручного удаления через removeItem, метод clear оптимизирован и работает быстрее при большом количестве значений.


Удаление через интерфейс пользователя

Tom Select поддерживает визуальное удаление выбранных элементов через плагин remove_button.

new TomSelect('#select', {
  plugins: ['remove_button']
});

После активации:

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

Визуальная логика зависит от шаблона item, который можно переопределить через render.


Кастомизация кнопки удаления

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

new TomSelect('#select', {
  plugins: ['remove_button'],
  render: {
    item: function(data, escape) {
      return `<div class="item">
                ${escape(data.text)}
                <span class="custom-remove" data-value="${data.value}">x</span>
              </div>`;
    }
  }
});

И обработка:

document.addEventListener('click', (e) => {
  if (e.target.classList.contains('custom-remove')) {
    const value = e.target.dataset.value;
    tom.removeItem(value);
  }
});

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


Обработка событий удаления

Удаление элементов сопровождается рядом событий, позволяющих отслеживать изменения состояния.

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

Также часто используется общее событие:

tom.on('change', () => {
  console.log('Состояние изменилось');
});

Типовая схема:

  • item_remove — точечное удаление
  • change — общее изменение состояния
  • clear — массовый сброс

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


Удаление элементов в режиме multiple

В режиме множественного выбора удаление становится основным сценарием взаимодействия.

new TomSelect('#select', {
  maxItems: null
});

Каждый элемент представлен как отдельный токен. Удаление:

tom.removeItem('value1');

Особенности:

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

Защищённые (locked) элементы

В некоторых сценариях элементы могут быть заблокированы и недоступны для удаления.

new TomSelect('#select', {
  options: [
    { value: '1', text: 'A', locked: true },
    { value: '2', text: 'B' }
  ]
});

Поведение:

  • locked элементы нельзя удалить через UI
  • метод removeItem может игнорировать или обрабатывать такие элементы в зависимости от конфигурации

Попытка удаления защищённого значения обычно не приводит к изменению состояния.


Удаление при асинхронных данных

При использовании remote loading через load удаление требует синхронизации с кешем:

new TomSelect('#select', {
  load: function(query, callback) {
    fetch('/api/search?q=' + query)
      .then(res => res.json())
      .then(callback);
  }
});

При удалении:

tom.removeItem('value1');

Важно учитывать:

  • удаление не влияет на серверный источник данных
  • локальный кеш может сохранять опции
  • при повторном добавлении элемент восстанавливается из кеша

Синхронизация с внешними формами

Tom Select часто используется внутри HTML-форм, где удаление должно отражаться в select и FormData.

const select = document.querySelector('#select');

tom.on('change', () => {
  console.log(new FormData(select).getAll('select[]'));
});

После удаления:

  • DOM <option selected> обновляется
  • FormData отражает актуальное состояние
  • native form submission остаётся корректным

Принудительное удаление через setValue

Иногда удобнее пересобрать состояние полностью:

tom.setValue(['value2', 'value3']);

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

Подходит для:

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

Частые ошибки при удалении

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

1. Несовпадение типов

tom.removeItem(1); // если value = "1" строка, удаление не сработает

2. Попытка удаления несуществующего значения

  • не вызывает ошибку
  • не изменяет состояние

3. Множественные перерендеры

  • вызваны отсутствием silent при batch-операциях

4. Конфликт с внешним state

  • при использовании React/Vue требуется синхронизация через change

Поведение DOM при удалении

Удаление элемента в Tom Select затрагивает несколько уровней:

  • удаляется визуальный token
  • обновляется скрытый input
  • пересчитывается список выбранных значений
  • обновляется доступность options в dropdown

Внутренне библиотека поддерживает согласованность между UI и data-model, исключая необходимость ручного вмешательства в DOM.


Оптимизация массового удаления

При работе с большими списками (100+ элементов) важно минимизировать перерасчёты:

const values = tom.getValue();

tom.clear(true);

values.slice(0, 10).forEach(v => tom.addItem(v, true));

tom.trigger('change');

Такой подход позволяет:

  • снизить количество DOM операций
  • ускорить обновление интерфейса
  • избежать лагов при рендеринге

Поведение при повторном добавлении после удаления

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

tom.removeItem('value1');
tom.addItem('value1');

Исключения:

  • если элемент disabled
  • если maxItems достигнут
  • если запрещена повторная выборка через кастомную логику

Итоговая модель удаления

Механизм удаления в Tom Select строится на трёх уровнях:

  • программный API (removeItem, clear, setValue)
  • пользовательский интерфейс (remove_button, кастомные элементы)
  • событийная модель (item_remove, change, clear)

Эти уровни взаимодействуют между собой, обеспечивая синхронное обновление состояния без необходимости прямого управления DOM.