SortableJS — это легковесная библиотека для реализации перетаскивания элементов списка на веб-странице. В реальных приложениях важно не только визуально перемещать элементы, но и сохранять изменения на сервере, чтобы состояние интерфейса оставалось синхронизированным с базой данных.
SortableJS предоставляет несколько событий, которые позволяют
реагировать на действия пользователя. Ключевое событие для отправки
изменений на сервер — onEnd. Оно срабатывает после
завершения перетаскивания элемента, когда новый порядок элементов уже
установлен в DOM.
Пример подключения события:
import Sortable from 'sortablejs';
const list = document.getElementById('sortable-list');
Sortable.create(list, {
animation: 150,
onEnd: function (evt) {
const items = Array.from(list.children).map(item => item.dataset.id);
sendOrderToServer(items);
}
});
В этом примере dataset.id каждого элемента используется
как уникальный идентификатор. После завершения сортировки формируется
массив items, который отражает текущий порядок
элементов.
Для корректной отправки на сервер необходимо определить структуру данных. Чаще всего это массив идентификаторов в новом порядке, но возможны и более сложные структуры с дополнительными атрибутами:
function getListData(list) {
return Array.from(list.children).map(item => ({
id: item.dataset.id,
position: item.dataset.position
}));
}
Использование data- атрибутов позволяет хранить любую
служебную информацию в HTML, не нарушая визуальное отображение.
После формирования данных их можно отправить на сервер асинхронно с
помощью fetch:
function sendOrderToServer(order) {
fetch('/update-order', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ order })
})
.then(response => {
if (!response.ok) throw new Error('Ошибка при отправке данных');
return response.json();
})
.then(data => console.log('Порядок обновлён', data))
.catch(error => console.error('Ошибка:', error));
}
Важной практикой является обработка ошибок и подтверждение успешного сохранения данных на сервере. Это предотвращает рассинхронизацию интерфейса и базы данных.
SortableJS позволяет синхронизировать порядок элементов между
несколькими списками через опцию group. В таком случае
важно отслеживать не только порядок элементов, но и перемещение между
списками:
Sortable.create(list1, {
group: 'shared',
animation: 150,
onEnd: updateServer
});
Sortable.create(list2, {
group: 'shared',
animation: 150,
onEnd: updateServer
});
function updateServer(evt) {
const listId = evt.from.id;
const items = Array.from(evt.from.children).map(item => item.dataset.id);
fetch(`/update-list/${listId}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ order: items })
});
}
Каждое событие onEnd передаёт объект evt,
который содержит информацию о списках from и
to, индексах и перетаскиваемом элементе. Это позволяет
отправлять на сервер точные данные о перемещении.
При частых перетаскиваниях лучше накапливать изменения и отправлять их партиями, чтобы уменьшить нагрузку на сервер:
let pendingUpdates = [];
function queueUpdate(order) {
pendingUpdates.push(order);
if (!queueUpdate.timer) {
queueUpdate.timer = setTimeout(() => {
fetch('/bulk-update', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ updates: pendingUpdates })
});
pendingUpdates = [];
clearTimeout(queueUpdate.timer);
queueUpdate.timer = null;
}, 1000);
}
}
Такой подход предотвращает отправку запроса на каждый
onEnd, объединяя несколько изменений за короткий промежуток
времени.
data- атрибуты для хранения уникальных
идентификаторов и служебной информации.onEnd обеспечивает надежный момент для отправки
изменений после завершения сортировки.fetch с обработкой ошибок
позволяет поддерживать согласованное состояние интерфейса и
сервера.evt.from и evt.to.Эти принципы обеспечивают безопасное и стабильное сохранение порядка элементов при работе с SortableJS, позволяя интегрировать перетаскиваемые списки с серверной логикой.