Отправка изменений на сервер

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 API

После формирования данных их можно отправить на сервер асинхронно с помощью 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, позволяя интегрировать перетаскиваемые списки с серверной логикой.