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

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

Настройка групп

Опция group может быть задана как строкой или объектом. При использовании строки все списки с одинаковым именем группы становятся взаимосвязанными. Например:

new Sortable(document.getElementById('list1'), {
    group: 'shared'
});

new Sortable(document.getElementById('list2'), {
    group: 'shared'
});

В данном случае элементы можно свободно перемещать между list1 и list2.

При более сложных требованиях используется объектная форма:

group: {
    name: 'shared',
    pull: true,
    put: false
}

Здесь pull и put определяют направление перемещения:

  • pull: разрешает текущему списку “тянуть” элементы для перемещения в другие списки.
  • put: разрешает принимать элементы из других списков.

Типы значений pull и put

pull и put могут быть следующего типа:

  • Boolean — простое разрешение или запрет.
  • String — имя другой группы, из которой разрешается перемещение.
  • Array строк — список разрешённых групп.
  • Функция — динамическая проверка, которая возвращает true или false в зависимости от элемента, списка или события.

Пример динамического ограничения перемещения:

group: {
    name: 'group1',
    put: function (to) {
        // разрешаем только элементы с классом .allowed
        return to.el.querySelectorAll('.allowed').length > 0;
    }
}

Ограничение перемещения по условию элемента

Для более детальной фильтрации перемещаемых элементов можно использовать параметр filter и событие onMove.

  • filter позволяет исключить элементы из перетаскивания полностью:
new Sortable(list, {
    filter: '.no-drag'
});
  • onMove позволяет проверять, можно ли перемещать конкретный элемент между группами:
new Sortable(list1, {
    group: 'shared',
    onMove: function (evt) {
        // запрет перемещения элементов с классом 'fixed' в другой список
        return !evt.dragged.classList.contains('fixed');
    }
});

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

Иногда требуется разрешить только определённые направления перемещения между группами. Для этого можно комбинировать pull и put с именами групп:

new Sortable(list1, {
    group: {
        name: 'groupA',
        pull: 'groupB', // можно только перетаскивать элементы в groupB
        put: false
    }
});

new Sortable(list2, {
    group: {
        name: 'groupB',
        pull: true,
        put: 'groupA' // можно принимать элементы только из groupA
    }
});

В этом примере элементы из list1 можно перемещать только в list2, а обратно перемещать нельзя.

Комбинация с множественным выбором элементов

SortableJS поддерживает множественный выбор элементов через опцию multiDrag. Ограничения групп в таком случае применяются ко всем выбранным элементам:

new Sortable(list, {
    group: 'shared',
    multiDrag: true,
    onMove: function(evt) {
        // блокируем перемещение, если выбран хотя бы один запрещённый элемент
        return !evt.dragged.classList.contains('no-move');
    }
});

Практические сценарии

  1. Доска задач с разделением по колонкам Каждая колонка — отдельная группа. Некоторые задачи можно перемещать только в определённые колонки. Для этого используются put и pull с фильтрацией по типу задачи.

  2. Фильтруемые списки товаров Разрешено перемещение товаров между категориями только определённого типа. С помощью функции в put проверяется соответствие категории.

  3. Защищённые элементы Некоторые элементы остаются неподвижными и не могут быть перемещены ни в один список. Это реализуется через filter и проверку в onMove.

События для отслеживания перемещений

Для контроля и логирования перемещений между группами применяются события:

  • onAdd — вызывается при добавлении элемента в список из другой группы.
  • onRemove — вызывается при удалении элемента из списка.
  • onStart / onEnd — начало и окончание перетаскивания.
  • onUpdate — изменение позиции элемента внутри списка.

Пример отслеживания перемещений:

new Sortable(list2, {
    group: 'shared',
    onAdd: function(evt) {
        console.log(`Элемент перемещён из ${evt.from.id} в ${evt.to.id}`);
    }
});

Важные нюансы

  • Группы взаимодействуют только если их имена совпадают или указаны через pull/put.
  • Значение put: false полностью блокирует принятие элементов.
  • Значение pull: false не мешает списку принимать элементы, но запрещает их вытягивать.
  • Использование функций для put и pull позволяет реализовать динамические и условные ограничения, что делает SortableJS очень гибким инструментом для сложных интерфейсов.