Columns with Drag and Drop - How would you implement? #3953
-
How would you implement a Columns Drag and Drop? Using react-beautiful-dnd, for example, what would you use as your draggable element since the header of a column and its cells are rendered separated i.e there's not a single element I could grab afaik? Any ideas about how to approach this? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
Pretty sure you would want to only render a marker/separator of where the column would end up. |
Beta Was this translation helpful? Give feedback.
-
Here is my drag-and-drop implementation (v.8-alpha). My implementation uses only I share the only necessary part: let columnBeingDragged: number;
const onDragStart = (e: DragEvent<HTMLElement>): void => {
columnBeingDragged = Number(e.currentTarget.dataset.columnIndex);
};
const onDrop = (e: DragEvent<HTMLElement>): void => {
e.preventDefault();
const newPosition = Number(e.currentTarget.dataset.columnIndex);
const currentCols = instance.getVisibleLeafColumns().map((c) => c.id);
const colToBeMoved = currentCols.splice(columnBeingDragged, 1);
currentCols.splice(newPosition, 0, colToBeMoved[0]);
instance.setColumnOrder(currentCols); // <------------------------here you save the column ordering state
};
return (
// the rest of the table implementation is omitted
<thead>
{instance.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th
key={header.id}
colSpan={header.colSpan}
style={{ width: header.getSize() }} // for resizing
// the below props for column reordering ---------------------starting props for drag&drop
draggable={
!instance.getState().columnSizingInfo.isResizingColumn
}
data-column-index={header.index}
onDragStart={onDragStart}
onDragOver={(e): void => {
e.preventDefault();
}}
onDrop={onDrop} // <---------------------------------------- ending props for drag&drop
>
{/* {header.isPlaceholder ? null : header.renderHeader()} */}
{/* column filter */}
{header.isPlaceholder ? null : (
<>
{header.renderHeader()}
{header.column.getCanFilter() ? (
<div>
<Filter
column={header.column}
instance={instance}
/>
</div>
) : null}
</>
)}
{/* column resizer */}
<div
{...{
onMouseDown: header.getResizeHandler(),
onTouchStart: header.getResizeHandler(),
className: `resizer ${
header.column.getIsResizing() ? "isResizing" : ""
}`,
}}
/>
</th>
))}
</tr>
))}
</thead> You can inspire what to do. I hope it is useful for you. |
Beta Was this translation helpful? Give feedback.
-
I updated the TanStack Table official Column DnD example to do this with DnD Kit |
Beta Was this translation helpful? Give feedback.
Here is my drag-and-drop implementation (v.8-alpha). My implementation uses only
onChange
method notonEnd
. The behavior is that you drag&drop only theth
elements.I share the only necessary part: