Tom Select поддерживает механизм перетаскивания выбранных элементов
через плагин drag_drop, который расширяет стандартное
поведение мультиселекта и добавляет интерактивную сортировку элементов
внутри уже выбранного набора. Основная цель этого функционала — дать
возможность пользователю менять порядок выбранных значений без
необходимости удаления и повторного добавления.
Механизм drag & drop в контексте мультиселекта основан на перераспределении DOM-элементов, которые представляют выбранные значения. Каждый выбранный элемент превращается в отдельный токен (item), и именно эти токены становятся draggable-узлами.
Ключевые особенности поведения:
value массива соответствует
визуальному порядку.Внутри плагина используется логика сортировки DOM-узлов контейнера выбранных элементов, после чего пересчитывается внутреннее состояние инстанса селекта.
Активация функциональности осуществляется через систему плагинов:
new TomSelect('#select', {
plugins: ['drag_drop']
});
После подключения элементы выбора становятся перетаскиваемыми внутри контейнера выбранных значений. Никаких дополнительных настроек не требуется для базового поведения.
Важно, что плагин работает только в режиме multiple,
поскольку одиночный выбор не имеет смысловой структуры для
сортировки.
Стандартный пример использования с множественным выбором:
<select id="select" multiple>
<option value="js">JavaScript</option>
<option value="ts">TypeScript</option>
<option value="py">Python</option>
<option value="go">Go</option>
</select>
new TomSelect('#select', {
plugins: ['drag_drop'],
maxItems: null
});
После инициализации каждый выбранный элемент можно перетаскивать внутри контейнера, изменяя порядок отображения и итогового массива значений.
Сортировка реализуется через изменение порядка DOM-элементов внутри
контейнера .ts-control (или аналогичного root-элемента
управления выбранными значениями). При завершении drag-сессии
выполняются следующие шаги:
value;Фактически, DOM становится источником истины для порядка элементов до момента синхронизации с моделью данных.
При использовании ограничения количества выбранных элементов
(maxItems) drag & drop продолжает работать без
ограничений, однако важно учитывать:
Пример:
new TomSelect('#select', {
plugins: ['drag_drop'],
maxItems: 3
});
Если выбрано 3 элемента, их можно свободно переставлять, но добавить четвёртый нельзя без удаления одного из текущих.
Плагин допускает ограниченную кастомизацию поведения, в основном через стилизацию и вмешательство в DOM.
Часто используется визуальный индикатор перетаскивания. Он задаётся через CSS:
.ts-dropdown .item {
cursor: grab;
}
.ts-dropdown .item:active {
cursor: grabbing;
}
При необходимости можно добавить отдельную область для захвата (drag handle), модифицируя шаблон рендера элементов:
new TomSelect('#select', {
plugins: ['drag_drop'],
render: {
item: function(data, escape) {
return `
<div class="item">
<span class="handle">⋮⋮</span>
<span class="label">${escape(data.text)}</span>
</div>
`;
}
}
});
Хотя визуальный handle присутствует, логика перетаскивания обычно привязана ко всему элементу.
По умолчанию сортировка происходит горизонтально или вертикально в
зависимости от CSS-раскладки контейнера. Поведение не задаётся через
API, а определяется стилями flex или
inline-block.
Drag & drop влияет на порядок значений, что может быть отслежено через стандартные события изменения состояния селекта.
Основное событие:
change — вызывается после изменения порядка
элементов.Пример обработки:
new TomSelect('#select', {
plugins: ['drag_drop'],
onChange: function(value) {
console.log('Новый порядок:', value);
}
});
Значение value в этом случае будет массивом, отражающим
текущую последовательность после сортировки.
Дополнительно может использоваться событие update, если
требуется реагировать на любые изменения DOM-состояния, однако оно менее
предсказуемо в зависимости от версии сборки.
Drag & drop имеет смысл только при множественном выборе:
Попытка включить drag_drop в одиночном режиме не
приводит к ошибкам, но функциональность фактически отключена.
На мобильных устройствах drag & drop работает через touch-события. Поведение зависит от реализации браузера:
В некоторых сценариях требуется дополнительная настройка CSS:
.ts-control {
touch-action: manipulation;
}
Это уменьшает конфликты между прокруткой и перетаскиванием.
Сортировка выбранных элементов часто применяется в следующих сценариях:
При этом порядок значений часто сохраняется на сервере как массив, где позиция элемента имеет смысловое значение.
Пример сохранения:
const select = new TomSelect('#select', {
plugins: ['drag_drop'],
onChange: function(value) {
fetch('/save', {
method: 'POST',
body: JSON.stringify({ order: value })
});
}
});
При большом количестве выбранных элементов drag & drop может создавать нагрузку, связанную с:
Оптимизация обычно достигается за счёт:
Внутренняя логика не пересоздаёт весь компонент при сортировке, а ограничивается перестановкой узлов, что снижает стоимость операции по сравнению с полной реинициализацией инстанса.