Grid to Grid
Introduction
Section titled “Introduction”Grid-to-grid dragging lets a row leave one grid and land in another — the
staple of transfer-list, kanban, and shortlist UIs. It builds on the same
RowDragManager that powers in-grid reordering:
each grid has its own manager, and you connect them by handing one manager the
drop zone of the other.
import { RowDragManager } from '@zengrid/enterprise/grid';
const dragA = new RowDragManager();const dragB = new RowDragManager();dragA.attach(gridA);dragB.attach(gridB);
// Rows dragged out of grid A can be dropped into grid B:dragA.addRowDropZone(dragB.getRowDropZone());getRowDropZone() returns a RowDropZone
bound to its grid — but unlike a plain external zone, this one knows how to
receive a row: it shows an in-grid drop line where the row will land and, on
release, inserts the dragged row’s data at that position. Register it on the
source grid’s manager with addRowDropZone, and the two are connected.
Move vs. copy
Section titled “Move vs. copy”By default a grid-to-grid drop is a move: the row is inserted into the target
grid and removed from the source. Pass { removeSource: false } to copy
instead — the source keeps its row and the target gets a duplicate:
// Move (default): the row leaves grid A.dragA.addRowDropZone(dragB.getRowDropZone());
// Copy: grid A keeps the row, grid B gets a copy.dragA.addRowDropZone(dragB.getRowDropZone({ removeSource: false }));| Option | Default | Effect |
|---|---|---|
removeSource |
true |
true removes the row from the source grid on drop (a move); false leaves it (a copy). |
onDrop |
— | Called after the row is inserted into the receiving grid. |
One-way vs. two-way
Section titled “One-way vs. two-way”Wiring is directional. dragA.addRowDropZone(dragB.getRowDropZone()) only enables
A → B. For a two-way transfer, wire the mirror as well:
dragA.addRowDropZone(dragB.getRowDropZone()); // A → BdragB.addRowDropZone(dragA.getRowDropZone()); // B → ABecause each grid keeps its own RowDragManager, dragging a row within a grid
still reorders that grid — grid-to-grid transfer and in-grid reordering coexist on
the same managers.
Reacting to a drop
Section titled “Reacting to a drop”Pass onDrop to react when a row arrives — persist the change, POST to a server,
or update a model. It receives the inserted rowData, the display index it landed
before (insertBeforeRow), and its new source index (toSource):
dragA.addRowDropZone( dragB.getRowDropZone({ onDrop: ({ rowData, insertBeforeRow, toSource }) => { console.log('received', rowData, 'at', insertBeforeRow, '→ source', toSource); }, }));The rows are dragged whole here (press anywhere on a row and drag). Add a drag handle or customise the drag preview exactly as you would for in-grid dragging — the same options apply.
Try it live
Section titled “Try it live”Both grids share the same columns, so a row moves across intact. Drag a row from one grid to the other; a line shows where it will land. Switch tabs to compare a two-way move, a copy-only palette, and a one-way flow with a drop callback.
Drag a row from either grid onto the other — it moves across and the line shows where it lands. Drag within a grid to reorder it. A ghost follows the pointer across the gap.
- Managed Row Dragging — in-grid reorder, whole-row or handle.
- External DropZone — drag rows out to any element, not just another grid.
- Row Dragging Customisation — the ghost, drop line, and origin-row styling that carry across grids.