Move cells
Move or copy a selected range of cells by dragging its border, the same way you would in a spreadsheet application.
Overview
When you set moveCells to true, hovering the border of a selected cell range shows a grab cursor. Dragging that border moves the block’s data — cell values and formatting — to the new location. Hold Ctrl (Windows) or ⌘ (Mac) during the drag to copy instead of move. Press Escape to cancel a drag before releasing.
The moveCells option was introduced in Handsontable 18.1.0. To move whole rows or columns instead of a cell range, see the Row moving and Column moving guides.
Enable cell moving
To enable drag-to-move, set the moveCells option to true:
moveCells: true,This option applies at the grid level and defaults to false.
Select a range of cells in the demo below, then drag its border to a new location. Hold Ctrl or ⌘ to copy the range instead of moving it.
import { useEffect, useRef } from 'react';import { HotTable } from '@handsontable/react-wrapper';import { registerAllModules } from 'handsontable/registry';// register Handsontable's modulesregisterAllModules();const data = [ ['Ana García', 'Engineering', 'Senior Engineer', 95000, 'Madrid', 12], ['James Okafor', 'Marketing', 'Product Manager', 88000, 'Lagos', 8], ['Li Wei', 'Engineering', 'Frontend Dev', 82000, 'Shanghai', 5], ['Maria Santos', 'HR', 'HR Specialist', 71000, 'Lisbon', 3], ['David Kim', 'Engineering', 'Backend Dev', 85000, 'Seoul', 7], ['Emma Wilson', 'Marketing', 'SEO Analyst', 68000, 'London', 2], ['Ahmed Hassan', 'Finance', 'Controller', 92000, 'Cairo', 10], ['Sara Johansson', 'Engineering', 'QA Engineer', 78000, 'Stockholm', 6],];const ExampleComponent = () => { const hotRef = useRef(null); // Pre-select an interior range so the move border is immediately discoverable. useEffect(() => { hotRef.current?.hotInstance?.selectCell(1, 1, 3, 3); }, []); return (<HotTable ref={hotRef} data={data} colHeaders={['Name', 'Department', 'Role', 'Salary', 'City', 'Tenure']} rowHeaders={true} width="auto" height="auto" moveCells={true} autoWrapRow={true} autoWrapCol={true} licenseKey="non-commercial-and-evaluation"/>);};export default ExampleComponent;import { useEffect, useRef } from 'react';import { HotTable, HotTableRef } from '@handsontable/react-wrapper';import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modulesregisterAllModules();
const data = [ ['Ana García', 'Engineering', 'Senior Engineer', 95000, 'Madrid', 12], ['James Okafor', 'Marketing', 'Product Manager', 88000, 'Lagos', 8], ['Li Wei', 'Engineering', 'Frontend Dev', 82000, 'Shanghai', 5], ['Maria Santos', 'HR', 'HR Specialist', 71000, 'Lisbon', 3], ['David Kim', 'Engineering', 'Backend Dev', 85000, 'Seoul', 7], ['Emma Wilson', 'Marketing', 'SEO Analyst', 68000, 'London', 2], ['Ahmed Hassan', 'Finance', 'Controller', 92000, 'Cairo', 10], ['Sara Johansson', 'Engineering', 'QA Engineer', 78000, 'Stockholm', 6],];
const ExampleComponent = () => { const hotRef = useRef<HotTableRef>(null);
// Pre-select an interior range so the move border is immediately discoverable. useEffect(() => { hotRef.current?.hotInstance?.selectCell(1, 1, 3, 3); }, []);
return ( <HotTable ref={hotRef} data={data} colHeaders={['Name', 'Department', 'Role', 'Salary', 'City', 'Tenure']} rowHeaders={true} width="auto" height="auto" moveCells={true} autoWrapRow={true} autoWrapCol={true} licenseKey="non-commercial-and-evaluation" /> );};
export default ExampleComponent;Moving cells with formulas
When the formulas plugin is active, formula references adjust automatically on move — the same way they do in Excel.
Limitations
- Drag-to-move works on a single contiguous cell range only. It has no effect on full-row, full-column, select-all, or multiple selections.
- The target must stay within the grid. Neither the target nor the source may overlap read-only cells, because a move has to clear the source. Copying with Ctrl or ⌘ leaves the source in place, so a read-only source cell blocks a move but not a copy.
- Drag-to-move is hidden when
disableVisualSelectionis set. - A move that would split a merged cell is blocked.
Hooks
beforeMoveCellsfires before the data relocates. Returnfalsefrom the handler to cancel the move.afterMoveCellsfires after the data has been relocated.
Move cells programmatically
To move or copy a range from code, call the plugin’s moveCellRange() method:
hot.getPlugin('moveCells').moveCellRange(sourceRange, targetTopLeft, isCopy);Related articles
Related guides
Configuration options
Hooks
Plugins
Microsoft and Excel are registered trademarks of Microsoft Corporation.