Column Reordering
Grid columns can be reordered by dragging and dropping column headers.
<div controller={PageController}>
<div class="flex mb-2">
<Repeater
records={computable(m.unusedColumns, (columns) =>
columns.map((key) => allColumns.find((c) => c.key === key)),
)}
>
<DragSource
class="bg-gray-100 border border-gray-300 px-2 py-1 text-sm mr-1 cursor-pointer"
data={{ type: "unused-column", key: m.$record.key }}
>
<span text={m.$record.header} />
</DragSource>
</Repeater>
<DropZone
class="border border-dashed border-gray-300 flex-grow px-2 py-1 text-sm transition-colors"
onDropTest={(e) => e?.source?.type === "grid-column"}
overClass="bg-yellow-100"
onDrop={(e, { store }) => {
let { key } = e.source.column
store.update(m.columnOrder, (order) => order.filter((c) => c !== key))
store.update(m.unusedColumns, (cols) => [...cols, key])
}}
>
Drag column here to remove
</DropZone>
</div>
<Grid
records={m.records}
mod="fixed-layout"
scrollable
border
style="height: 250px; margin-bottom: 10px"
lockColumnWidths
columnParams={m.columnOrder}
onGetColumns={(columnOrder) =>
columnOrder.map((key: string) => allColumns.find((c) => c.key === key))
}
onColumnDropTest={(e, instance) =>
(e.source?.type === "grid-column" &&
e.source?.gridInstance === instance) ||
e.source?.data?.type === "unused-column"
}
onColumnDrop={(e, { store }) => {
let key =
e.source.type === "grid-column"
? e.source.column.key
: e.source.data.key
let { index } = e.target
let columnOrder = store.get(m.columnOrder)
let at = columnOrder.indexOf(key)
let result = columnOrder.filter((c) => c !== key)
if (at >= 0 && at < index) index--
result = insertElement(result, index, key)
store.set(m.columnOrder, result)
store.update(m.unusedColumns, (unused) => unused.filter((c) => c !== key))
}}
/>
<Button onClick="onResetColumns">Reset Columns</Button>
</div> Drag column here to remove
| Name | Continent | Browser | OS | Visits |
|---|---|---|---|---|
| Alice Johnson | Europe | Chrome | Windows | 45 |
| Bob Smith | Asia | Firefox | macOS | 23 |
| Carol White | North America | Safari | macOS | 67 |
| David Brown | Europe | Chrome | Linux | 12 |
| Eva Green | Asia | Edge | Windows | 89 |
Drag column headers to reorder them. Drag a column to the drop zone above to remove it from the grid.
Enabling Draggable Columns
Set draggable: true on each column that can be reordered:
{
key: "fullName",
header: "Name",
field: "fullName",
draggable: true,
}
Each column should have a unique key so the Grid can correctly track column state.
Dynamic Column Generation
Use columnParams and onGetColumns to dynamically generate columns:
<Grid
columnParams={m.columnOrder}
onGetColumns={(columnOrder) =>
columnOrder.map((key) => allColumns.find((c) => c.key === key))
}
/>
When columnParams changes, onGetColumns is called to regenerate the column list.
Handling Column Drops
Implement onColumnDropTest and onColumnDrop to handle the drag and drop logic:
<Grid
onColumnDropTest={(e, instance) =>
e.source?.type === "grid-column" && e.source?.gridInstance === instance
}
onColumnDrop={(e, { store }) => {
let { key } = e.source.column;
let { index } = e.target;
// Update column order in store
}}
/>
Configuration
| Property | Type | Description |
|---|---|---|
draggable | boolean | Enable dragging for this column. |
key | string | Unique identifier for the column. Required for reordering. |
columnParams | any | Parameters passed to onGetColumns. Changes trigger column regeneration. |
onGetColumns | function | Callback to generate columns. Receives columnParams value. |
onColumnDropTest | function | Test if a drop is valid. Receives drag event and instance. |
onColumnDrop | function | Handle column drop. Receives drag event and instance. |
lockColumnWidths | boolean | Preserve column widths during reordering. |
See also: Column Resizing, Dynamic Columns