Skip to content

Make specified cells read-only to protect them from unwanted changes but still allow navigation and copying of data.

Disable individual cells, entire columns, or entire rows to prevent user edits. Use readOnly on cells, columns, or the whole grid.

Overview

Disabling a cell makes the cell read-only or non-editable. Both have similar outcomes, with the following differences:

Read-only cell
readOnly: true
Non-editable cell
editor: false
Has an additional CSS class (htDimmed)Has no additional CSS class
Copy works, paste doesn’t workCopy-paste works
Drag-to-fill doesn’t workDrag-to-fill works
Can’t be changed by populateFromArray()Can be changed by populateFromArray()

To disable a cell

To make the entire grid read-only, set readOnly to true as a top-level grid option.

JavaScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#exampleReadOnlyGrid');
new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
height: 'auto',
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
licenseKey: 'non-commercial-and-evaluation',
// make the entire grid read-only
readOnly: true,
autoWrapRow: true,
autoWrapCol: true,
});
TypeScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#exampleReadOnlyGrid')!;
new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
height: 'auto',
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
licenseKey: 'non-commercial-and-evaluation',
// make the entire grid read-only
readOnly: true,
autoWrapRow: true,
autoWrapCol: true,
});

To disable a column

To make a column read-only, declare it in the columns configuration option. The column remains available for keyboard navigation and copying data (Ctrl/Cmd+C), but editing and pasting are disabled. You can also define a special renderer function that will dim the read-only values, providing a visual cue for the user that the cells are read-only.

JavaScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example1');
new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
height: 'auto',
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
licenseKey: 'non-commercial-and-evaluation',
columns: [
{
data: 'car',
readOnly: true,
},
{
data: 'year',
},
{
data: 'chassis',
},
{
data: 'bumper',
},
],
autoWrapRow: true,
autoWrapCol: true,
});
TypeScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example1')!;
new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
height: 'auto',
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
licenseKey: 'non-commercial-and-evaluation',
columns: [
{
data: 'car',
readOnly: true,
},
{
data: 'year',
},
{
data: 'chassis',
},
{
data: 'bumper',
},
],
autoWrapRow: true,
autoWrapCol: true,
});

To disable a row

To make specific cells read-only, use the cells function to set the readOnly property conditionally. The example below makes cells that contain the word “Nissan” read-only.

JavaScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example2');
const hot = new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
hot.updateSettings({
cells(row, col) {
return hot.getData()[row][col] === 'Nissan' ? { readOnly: true } : {};
},
});
TypeScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example2')!;
const hot = new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
hot.updateSettings({
cells(row, col) {
return hot.getData()[row][col] === 'Nissan' ? { readOnly: true } : {};
},
});

Non-editable cells behave like any other cells apart from preventing you from manually changing their values.

To disable a column (non-editable)

To make a column non-editable, declare it in the columns configuration option. The column’s basic behavior does not change — you can still use keyboard navigation, Ctrl/Cmd+C, Ctrl/Cmd+V, and drag-to-fill. You can also define a special renderer function that will dim the editor value, providing a visual cue that the cell is non-editable.

JavaScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example3');
new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
height: 'auto',
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
licenseKey: 'non-commercial-and-evaluation',
columns: [
{
data: 'car',
editor: false,
},
{
data: 'year',
editor: 'numeric',
},
{
data: 'chassis',
editor: 'text',
},
{
data: 'bumper',
editor: 'text',
},
],
autoWrapRow: true,
autoWrapCol: true,
});
TypeScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example3')!;
new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
height: 'auto',
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
licenseKey: 'non-commercial-and-evaluation',
columns: [
{
data: 'car',
editor: false,
},
{
data: 'year',
editor: 'numeric',
},
{
data: 'chassis',
editor: 'text',
},
{
data: 'bumper',
editor: 'text',
},
],
autoWrapRow: true,
autoWrapCol: true,
});

To disable a cell

To make specific cells non-editable, set editor: false in the cell configuration. The following example shows a table with non-editable cells containing the word “Nissan”.

JavaScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example4');
const hot = new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
hot.updateSettings({
cells(row, _col, prop) {
return hot.getDataAtRowProp(row, prop) === 'Nissan' ? { editor: false } : { editor: 'text' };
},
});
TypeScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example4')!;
const hot = new Handsontable(container, {
data: [
{ car: 'Tesla', year: 2017, chassis: 'black', bumper: 'black' },
{ car: 'Nissan', year: 2018, chassis: 'blue', bumper: 'blue' },
{ car: 'Chrysler', year: 2019, chassis: 'yellow', bumper: 'black' },
{ car: 'Volvo', year: 2020, chassis: 'white', bumper: 'gray' },
],
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
hot.updateSettings({
cells(row, _col, prop) {
return hot.getDataAtRowProp(row, prop as string) === 'Nissan' ? { editor: false } : { editor: 'text' };
},
});

Configuration options

Result

Read-only cells display with the htDimmed CSS class and block paste and drag-to-fill operations. Non-editable cells block manual editing but allow copy-paste and drag-to-fill.