Перетаскивание между сетками

Gridstack.js предоставляет мощный механизм для создания интерактивных сеток с возможностью перетаскивания элементов. Одной из продвинутых возможностей является drag-and-drop между несколькими сетками. Это позволяет пользователю перемещать виджеты не только внутри одной сетки, но и между разными контейнерами, сохраняя их размеры, позиции и привязку к сетке.


Подключение нескольких сеток

Для работы с несколькими сетками необходимо создать каждый контейнер с классом .grid-stack и инициализировать его с помощью Gridstack:

const grid1 = GridStack.init({
    column: 12,
    draggable: { handle: '.grid-stack-item-content' }
}, '#grid1');

const grid2 = GridStack.init({
    column: 12,
    draggable: { handle: '.grid-stack-item-content' }
}, '#grid2');

Ключевым моментом является настройка draggable через объект конфигурации, где указывается handle. Это гарантирует, что перетаскивание будет происходить только по выбранной области элемента.


Включение перетаскивания между сетками

Для того чтобы элементы можно было перемещать между разными сетками, используется метод addDropTarget. Например:

grid1.addDropTarget(grid2.el);
grid2.addDropTarget(grid1.el);

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


События при переносе

Gridstack.js предоставляет события, которые позволяют контролировать процесс перетаскивания между сетками:

  • dragstart – срабатывает при начале перетаскивания.
  • drag – вызывается при каждом движении виджета.
  • dragstop – срабатывает при завершении перемещения.
  • dropped – ключевое событие для работы с виджетами, перенесенными в другую сетку.

Пример:

grid2.on('dropped', function(event, previousWidget, newWidget) {
    console.log('Элемент перенесен в grid2', newWidget);
});

Аргументы previousWidget и newWidget позволяют получить полную информацию о старой и новой позициях элемента.


Сохранение размеров и позиций

При переносе виджетов между сетками важно сохранить их ширину (w) и высоту (h), а также координаты (x, y). Gridstack автоматически учитывает эти параметры, но при кастомных обработчиках можно использовать:

const node = el.gridstackNode; // доступ к данным виджета
console.log(node.x, node.y, node.w, node.h);

Для сохранения состояния всех элементов обеих сеток можно применять:

const grid1Data = grid1.save();
const grid2Data = grid2.save();

Данные сохраняются в виде массива объектов, где каждый объект содержит координаты, размеры и идентификатор элемента.


Ограничения при переносе

  1. Размер сетки – виджет не может выйти за пределы количества колонок.
  2. Минимальные и максимальные размеры виджета – свойства minW, minH, maxW, maxH могут быть заданы для контроля масштабирования.
  3. Соседние виджеты – Gridstack автоматически перемещает соседние элементы, чтобы избежать наложений, если включена опция float: false.

Динамическое добавление новых целей

Если в приложении создаются новые сетки динамически, их также можно подключать как drop targets:

function createNewGrid(containerId) {
    const newGrid = GridStack.init({ column: 12 }, `#${containerId}`);
    newGrid.addDropTarget(grid1.el);
    grid1.addDropTarget(newGrid.el);
    return newGrid;
}

Это позволяет расширять интерфейс на лету и обеспечивать гибкую работу с перетаскиванием.


Практические советы

  • Управление событиями – для больших интерфейсов рекомендуется слушать dropped вместо dragstop, чтобы обрабатывать только успешные переносы между сетками.
  • Анимация и визуальные подсказки – Gridstack автоматически подсвечивает возможные позиции, но можно использовать CSS для более наглядного эффекта.
  • Сохранение состояния – после перетаскивания синхронизировать данные с сервером или localStorage, чтобы при перезагрузке сетка оставалась в актуальном состоянии.

Пример комплексной схемы

const grids = [];
grids.push(GridStack.init({ column: 12 }, '#grid1'));
grids.push(GridStack.init({ column: 12 }, '#grid2'));

grids.forEach((g, i) => {
    grids.forEach((target, j) => {
        if (i !== j) g.addDropTarget(target.el);
    });
    g.on('dropped', function(event, previousWidget, newWidget) {
        console.log(`Элемент перенесен в сетку ${i + 1}`);
    });
});

Такой подход позволяет легко масштабировать количество сеток и обеспечивает полную взаимосвязанность виджетов между ними.


Gridstack.js, благодаря addDropTarget, гибкой системе событий и сохранению состояний, делает перетаскивание между сетками простым, но при этом мощным инструментом для построения интерактивных дашбордов и редакторов интерфейсов.