How to implement column and row reordering?
💡
This feature is only available in PRO version
This guide is based on getting started.
1. Add some new imports for further usage
We'll need Id, DropPosition,
Column and Row.
import { ReactGrid, Id, DropPosition, Column, Row } from "@silevis/reactgrid";  //highlight-line2. Modify the rows and columns to enable reordering
This is done by adding the reorderable property to a column or row and setting its value to true.
const [columns, setColumns] = React.useState<Column[]>(() => [
  { columnId: "Name", width: 100, reorderable: true },  //highlight-line
  { columnId: "Surname", width: 100, reorderable: true }  //highlight-line
]);Notice that we don't want the first row to be reorderable because that's our grid's header so the reorderable
property will become undefined contrary to other rows.
const [rows, setRows] = React.useState<Row[]>(() => [
  {
    rowId: 0,
    reorderable: true, //highlight-line
    cells: [
      { type: "header", text: "Name" },
      { type: "header", text: "Surname" }
    ]
  },
  {
    rowId: 1,
    reorderable: true, //highlight-line
    cells: [
      { type: "text", text: "Thomas" },
      { type: "text", text: "Goldman" }
    ]
  },
  {
    rowId: 2,
    reorderable: true, //highlight-line
    cells: [
      { type: "text", text: "Susie" },
      { type: "text", text: "Spencer" }
    ]
  },
  {
    rowId: 3,
    reorderable: true, //highlight-line
    cells: [
      { type: "text", text: "" },
      { type: "text", text: "" }
    ]
  }
]);3. Implement the handler functions
reorderArray function is used to order columns or rows.
// a helper function used to reorder arbitrary arrays
const reorderArray = <T extends {}>(arr: T[], idxs: number[], to: number) => {
  const movedElements: T[] = arr.filter((_: T, idx: number) => idxs.includes(idx));
  to = Math.min(...idxs) < to ? to += 1 : to -= idxs.filter(idx => idx < to).length;
  const leftSide: T[] = arr.filter((_: T, idx: number) => idx < to && !idxs.includes(idx));
  const rightSide: T[] = arr.filter((_: T, idx: number) => idx >= to && !idxs.includes(idx));
  return [...leftSide, ...movedElements, ...rightSide];
}
 
const handleColumnsReorder = (targetColumnId: Id, columnIds: Id[], dropPosition: DropPosition) => {
  const to = columns.findIndex((column: Column) => column.columnId === targetColumnId);
  const columnIdxs = columnIds.map((id: Id, idx: number) => columns.findIndex((c: Column) => c.columnId === id));
  setRows(rows.map(row => ({ ...row, cells: reorderArray(row.cells, columnIdxs, to) })));
  setColumns(reorderArray(columns, columnIdxs, to));
}
 
const handleRowsReorder = (targetRowId: Id, rowIds: Id[], dropPosition: DropPosition) => {
  setRows((prevRows) => {
    const to = rows.findIndex(row => row.rowId === targetRowId);
    const columnIdxs = rowIds.map(id => rows.findIndex(r => r.rowId === id));
    return reorderArray(prevRows, columnIdxs, to);
  });
}- Pass the handler functions to your ReactGridcomponent and addenableRowSelectionandenableColumnSelectionproperties to enable this type of events handling.
<ReactGrid
	rows={rows}
	columns={columns}
	onColumnsReordered={handleColumnsReordered} // highlight-line
	onRowsReordered={handleRowsReordered} // highlight-line
	enableRowSelection // highlight-line
	enableColumnSelection // highlight-line
/>Live demo
Code
const ColumnsAndRowsReorderSample = () => { const [columns, setColumns] = React.useState<Column[]>(() => [ { columnId: "Name", width: 100, reorderable: true }, { columnId: "Surname", width: 100, reorderable: true } ]); const [rows, setRows] = React.useState<Row[]>(() => [ { rowId: 0, reorderable: true, cells: [ { type: "header", text: "Name" }, { type: "header", text: "Surname" } ] }, { rowId: 1, reorderable: true, cells: [ { type: "text", text: "Thomas" }, { type: "text", text: "Goldman" } ] }, { rowId: 2, reorderable: true, cells: [ { type: "text", text: "Susie" }, { type: "text", text: "Spencer" } ] }, { rowId: 3, reorderable: true, cells: [ { type: "text", text: "" }, { type: "text", text: "" } ] } ]); const reorderArray = <T extends {}>(arr: T[], idxs: number[], to: number) => { const movedElements: T[] = arr.filter((_: T, idx: number) => idxs.includes(idx)); to = Math.min(...idxs) < to ? to += 1 : to -= idxs.filter(idx => idx < to).length; const leftSide: T[] = arr.filter((_: T, idx: number) => idx < to && !idxs.includes(idx)); const rightSide: T[] = arr.filter((_: T, idx: number) => idx >= to && !idxs.includes(idx)); return [...leftSide, ...movedElements, ...rightSide]; } const handleColumnsReorder = (targetColumnId: Id, columnIds: Id[], dropPosition: DropPosition) => { const to = columns.findIndex((column: Column) => column.columnId === targetColumnId); const columnIdxs = columnIds.map((id: Id, idx: number) => columns.findIndex((c: Column) => c.columnId === id)); setRows(rows.map(row => ({ ...row, cells: reorderArray(row.cells, columnIdxs, to) }))); setColumns(reorderArray(columns, columnIdxs, to)); } const handleRowsReorder = (targetRowId: Id, rowIds: Id[], dropPosition: DropPosition) => { setRows((prevRows) => { const to = rows.findIndex(row => row.rowId === targetRowId); const columnIdxs = rowIds.map(id => rows.findIndex(r => r.rowId === id)); return reorderArray(prevRows, columnIdxs, to); }); } const handleCanReorderColumns = (targetColumnId: Id, columnIds: Id[], dropPosition: DropPosition): boolean => { return true; } const handleCanReorderRows = (targetColumnId: Id, rowIds: Id[], dropPosition: DropPosition): boolean => { return true; } return ( <ReactGrid rows={rows} columns={columns} onColumnsReordered={handleColumnsReorder} onRowsReordered={handleRowsReorder} canReorderRows={handleCanReorderRows} canReorderColumns={handleCanReorderColumns} enableRowSelection enableColumnSelection /> ); } render(<ColumnsAndRowsReorderSample/>)
Preview