Функциональность перетаскивания элементов в интерфейсах выбора основана на возможности изменять порядок уже выбранных значений без необходимости их удаления и повторного добавления. В Tom Select этот механизм реализуется через плагин drag_drop, который добавляет поддержку сортировки выбранных элементов непосредственно внутри поля выбора.
Основой работы является расширение поведения компонента, при котором каждый выбранный элемент становится draggable-узлом внутри контейнера значений. При изменении порядка библиотека синхронизирует внутреннее состояние массива выбранных значений с новым визуальным порядком.
Активация механизма выполняется подключением встроенного плагина:
new TomSelect('#select', {
plugins: ['drag_drop'],
maxItems: null
});
После подключения каждый выбранный элемент становится доступен для перетаскивания. Пользователь может менять порядок значений мышью или жестами на тач-устройствах, а библиотека автоматически обновляет внутреннюю модель данных.
Важно учитывать, что drag_drop работает только с уже выбранными элементами и не влияет на список доступных опций.
Tom Select хранит выбранные значения в виде массива. При использовании drag and drop изменяется именно порядок этого массива, а не только DOM-представление.
Принцип работы можно описать следующим образом:
Таким образом, визуальное изменение порядка всегда синхронизировано с данными формы.
В режиме multiple drag and drop сортировка приобретает ключевое значение, так как порядок элементов становится частью семантики данных.
new TomSelect('#select', {
plugins: ['drag_drop'],
maxItems: 10
});
В этом случае порядок выбранных значений влияет на:
При повторной загрузке значения восстанавливаются в том же порядке, в котором они были сохранены.
Плагин добавляет специальные CSS-классы, которые позволяют управлять состояниями элементов во время drag операции. Основные состояния:
Пример пользовательской стилизации:
.ts-wrapper .item {
cursor: grab;
}
.ts-wrapper .item.dragging {
opacity: 0.6;
cursor: grabbing;
}
.ts-wrapper .item.drop-before {
border-left: 2px solid #4a90e2;
}
Изменение внешнего вида важно для повышения предсказуемости интерфейса, особенно при большом количестве выбранных элементов.
При интеграции с сервером или сторонними формами необходимо учитывать, что порядок элементов имеет значение и должен сериализоваться корректно.
Tom Select предоставляет стандартный механизм получения данных:
const select = new TomSelect('#select', {
plugins: ['drag_drop']
});
const value = select.getValue();
В режиме multiple возвращается массив значений в актуальном порядке после сортировки.
При использовании скрытых полей формы порядок сохраняется автоматически:
<select id="select" multiple>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>
После drag and drop порядок в DOM синхронизируется с внутренним состоянием, что обеспечивает корректную отправку через стандартный form submit.
При включённом поиске (режим фильтрации опций) drag and drop действует только на уже выбранные элементы. Поисковый список не участвует в сортировке, что предотвращает конфликт между фильтрацией и изменением порядка.
Однако важно учитывать:
Сортировка drag and drop в Tom Select имеет ряд ограничений, обусловленных архитектурой компонента:
При использовании кастомных render-функций важно сохранять структуру элементов, так как изменение шаблона может повлиять на корректность drag-событий.
Tom Select позволяет переопределять отображение выбранных элементов через render:
new TomSelect('#select', {
plugins: ['drag_drop'],
render: {
item: function(data, escape) {
return `<div class="item-custom">${escape(data.text)}</div>`;
}
}
});
При этом важно сохранять возможность перетаскивания, не блокируя pointer-events и не изменяя контейнерные элементы так, чтобы нарушалась структура сортируемого узла.
На touch-устройствах drag and drop реализуется через обработку touch-событий. Логика остаётся аналогичной десктопной версии, но взаимодействие происходит через длительное удержание и перемещение пальцем.
Особенности:
Во время сортировки могут использоваться события компонента, связанные с изменением состояния:
Типичный сценарий обработки:
new TomSelect('#select', {
plugins: ['drag_drop'],
onChange: function(value) {
console.log('Новое состояние:', value);
}
});
Любое изменение порядка приводит к вызову обновления состояния, что позволяет синхронизировать UI с внешними системами управления данными.
При работе с большим числом выбранных значений drag and drop может создавать нагрузку на DOM из-за постоянных перерасчётов позиций элементов. В таких сценариях критичны:
Tom Select оптимизирует перестроение списка, но основная нагрузка остаётся на браузере, так как сортировка происходит на уровне DOM.
Помимо пользовательского drag and drop, порядок можно изменять программно через обновление значения:
select.setValue(['3', '1', '2']);
В этом случае визуальный порядок перестраивается автоматически, полностью соответствуя переданному массиву. Это позволяет синхронизировать серверный порядок с клиентским интерфейсом без ручного вмешательства пользователя.
При комбинировании программной сортировки и drag and drop приоритет всегда остаётся за последним изменением состояния, так как пользовательское действие перезаписывает порядок массива значений.