Ограничения перемещения

Библиотека SortableJS предоставляет мощный инструмент для реализации перетаскивания элементов списка с минимальными усилиями, однако в реальных приложениях часто требуется вводить ограничения на перемещение. Эти ограничения позволяют контролировать, какие элементы можно перемещать, куда их можно переместить, а также задавать условия для взаимодействия нескольких списков. SortableJS предоставляет несколько способов управления перемещением через настройки и события.


Использование свойства filter

Свойство filter позволяет указать элементы, которые нельзя перетаскивать. Оно принимает селектор CSS, функцию или массив селекторов. При попытке переместить элемент, подходящий под фильтр, операция отменяется.

Пример использования селектора:

const sortable = new Sortable(document.getElementById('list'), {
    filter: '.disabled',
    onMove: function (evt, originalEvent) {
        console.log('Попытка перемещения заблокированного элемента');
    }
});
  • Элементы с классом .disabled нельзя перемещать.
  • Событие onMove позволяет отследить попытки перемещения и выполнить дополнительные действия.

Функция в filter предоставляет больше гибкости:

filter: function (evt, target) {
    return target.dataset.locked === "true";
}

Элемент с атрибутом data-locked="true" становится заблокированным для перетаскивания.


Ограничение направления перемещения

Свойство direction задаёт разрешённое направление перетаскивания элементов:

  • vertical — только вертикальное перемещение.
  • horizontal — только горизонтальное перемещение.
  • null — разрешено любое направление.
const sortable = new Sortable(list, {
    direction: 'vertical'
});

Это особенно важно при создании сеток, таблиц или списков с фиксированными направлениями.


Ограничение перемещения между списками

С помощью опции group можно определить возможность перетаскивания между разными списками. Опция может быть объектом, позволяющим точную настройку:

group: {
    name: 'shared',
    pull: 'clone', // элементы копируются, а не перемещаются
    put: function (to, from, dragEl) {
        return !dragEl.classList.contains('restricted');
    }
}
  • name — имя группы списков.
  • pull — поведение при перетаскивании (true, false, ‘clone’).
  • put — функция, возвращающая true, если элемент разрешено положить в этот список.

Это позволяет создавать списки с элементами, которые могут перемещаться только в определённые контейнеры, либо запрещать перемещение некоторых элементов полностью.


Ограничение с помощью события onMove

Событие onMove вызывается перед фактическим перемещением элемента. Оно позволяет динамически контролировать допустимость операции.

onMove: function (evt, originalEvent) {
    if (evt.dragged.classList.contains('no-move')) {
        return false; // запрет перемещения
    }
    if (evt.to.id === 'restricted-list') {
        return false; // запрет перемещения в конкретный список
    }
}
  • Возврат false отменяет перемещение.
  • Доступ к объекту evt позволяет анализировать исходный и целевой контейнеры, позицию элемента и его свойства.

Ограничение позиции вставки

Для контроля позиции вставки элементов используется событие onEnd или onAdd. В них можно программно корректировать порядок элементов, если стандартная логика перемещения нарушает правила.

Пример:

onEnd: function (evt) {
    if (evt.newIndex < 1) {
        evt.from.insertBefore(evt.item, evt.from.children[1]);
    }
}

Элемент, случайно помещённый на первое место, автоматически перемещается на вторую позицию.


Ограничение размеров и области перемещения

SortableJS поддерживает опцию dragClass и CSS-подходы для ограничения зоны перемещения. С помощью CSS можно задать:

#list {
    overflow: hidden;
    max-height: 400px;
}
.dragging {
    position: absolute;
    pointer-events: none;
}
  • Ограничение области контейнера предотвращает выход элементов за видимую границу.
  • Опция fallbackOnBody вместе с CSS-классами позволяет создавать визуальные эффекты ограничения перемещения.

Сочетание ограничений

Все методы ограничения можно комбинировать для создания сложной логики перетаскивания:

  • filter блокирует отдельные элементы.
  • direction задаёт направление движения.
  • group управляет взаимодействием списков.
  • onMove и onEnd дают динамический контроль над допустимостью перемещения и позицией элементов.
  • CSS и dragClass ограничивают область визуального перемещения.

Такой комплексный подход позволяет реализовать перетаскивание с детальной настройкой правил, соответствующих любым бизнес-логикам интерфейса.