Angular Data GridPlugin: Configuration options
- Description
- Members
- activeHeaderClassName
- allowEmpty
- allowHtml
- allowInsertColumn
- allowInsertRow
- allowInvalid
- allowRemoveColumn
- allowRemoveRow
- ariaTags
- autoColumnSize
- autoRowSize
- autoWrapCol
- autoWrapRow
- bindRowsWithHeaders
- cell
- cells
- checkedTemplate
- className
- colHeaders
- collapsibleColumns
- columnHeaderHeight
- columns
- columnSorting
- columnSummary
- colWidths
- commentedCellClassName
- comments
- contextMenu
- copyable
- copyPaste
- correctFormat Deprecated
- currentColClassName
- currentHeaderClassName
- currentRowClassName
- customBorders
- data
- dataDotNotation
- dataSchema
- dateFormat
- datePickerConfig Deprecated
- defaultDate
- dialog
- disableVisualSelection
- dragToScroll
- dropdownMenu
- editor
- emptyDataState
- enterBeginsEditing
- enterCommits
- enterMoves
- fillHandle
- filter
- filteringCaseSensitive
- filters
- filterSelectedItems
- fixedColumnsStart
- fixedRowsBottom
- fixedRowsTop
- formulas
- fragmentSelection
- headerClassName
- height
- hiddenColumns
- hiddenRows
- imeFastEdit
- initialState
- injectCoreCss
- invalidCellClassName
- label
- language
- layoutDirection
- licenseKey
- loading
- locale
- manualColumnFreeze
- manualColumnMove
- manualColumnResize
- manualRowMove
- manualRowResize
- maxCols
- maxRows
- maxSelections
- mergeCells
- minCols
- minRowHeights
- minRows
- minSpareCols
- minSpareRows
- multiColumnSorting
- navigableHeaders
- nestedHeaders
- nestedRows
- noWordWrapClassName
- numericFormat
- observeDOMVisibility
- outsideClickDeselects
- pagination
- parsePastedValue
- placeholder
- placeholderCellClassName
- preventOverflow
- readOnly
- readOnlyCellClassName
- renderAllColumns
- renderAllRows
- renderer
- rowHeaders
- rowHeaderWidth
- rowHeights
- sanitizer
- search
- searchInput
- selectionMode
- selectOptions
- skipColumnOnPaste
- skipRowOnPaste
- sortByRelevance
- source
- sourceDataValidator
- sourceDataWarningMessage
- sourceSortFunction
- startCols
- startRows
- stretchH
- strict
- tableClassName
- tabMoves
- tabNavigation
- textEllipsis
- theme
- themeName
- timeFormat
- title
- trimDropdown
- trimRows
- trimWhitespace
- type
- uncheckedTemplate
- undo
- validator
- valueFormatter
- valueGetter
- valueParser
- valueSetter
- viewportColumnRenderingOffset
- viewportColumnRenderingThreshold
- viewportRowRenderingOffset
- viewportRowRenderingThreshold
- visibleRows
- width
- wordWrap
- Methods
Description
Configuration options let you heavily customize your Handsontable instance. For example, you can:
- Enable and disable built-in features
- Enable and configure additional plugins
- Personalize Handsontable's look
- Adjust Handsontable's behavior
- Implement your own custom features
settings = {
data: [
["A1", "B1", "C1", "D1", "E1"],
["A2", "B2", "C2", "D2", "E2"],
["A3", "B3", "C3", "D3", "E3"],
["A4", "B4", "C4", "D4", "E4"],
["A5", "B5", "C5", "D5", "E5"],
],
width: 400,
height: 300,
colHeaders: true,
rowHeaders: true,
customBorders: true,
dropdownMenu: true,
multiColumnSorting: true,
filters: true,
manualRowMove: true,
};
<hot-table [settings]="settings" />
Depending on your needs, you can apply configuration options to different elements of your grid:
- The entire grid
- Individual columns
- Individual rows
- Individual cells
- Individual grid elements, based on any logic you implement
Read more:
Members
activeHeaderClassName
Source codeoptions.activeHeaderClassName : string
The activeHeaderClassName option lets you add a CSS class name
to every currently-active, currently-selected header (when a whole column or row is selected).
Read more:
currentRowClassNamecurrentColClassNamecurrentHeaderClassNameinvalidCellClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: "ht__active_highlight"
Category: Core
Since: 0.38.2
Example
// add an `ht__active_highlight` CSS class name
// to every currently-active, currently-selected header
activeHeaderClassName: 'ht__active_highlight',
allowEmpty
Source codeoptions.allowEmpty : boolean
The allowEmpty option determines whether Handsontable accepts the following values:
nullundefined''
You can set the allowEmpty option to one of the following:
| Setting | Description |
|---|---|
true (default) | - Accept null, undefined and '' values- Mark cells that contain null, undefined or '' values as valid |
false | - Don't accept null, undefined and '' values- Mark cells that contain null, undefined or '' values with as invalid |
TIP
To use the allowEmpty option, you need to set the validator option (or the type option).
Default: true
Category: Core
Example
// allow empty values in each cell of the entire grid
allowEmpty: true,
// or
columns: [
{
type: 'date',
dateFormat: 'DD/MM/YYYY',
// allow empty values in each cell of the 'date' column
allowEmpty: true
}
],
allowHtml
Source codeoptions.allowHtml : boolean
The allowHtml option configures whether autocomplete
and dropdown cells' source data
is treated as HTML.
You can set the allowHtml option to one of the following:
| Setting | Description |
|---|---|
false (default) | The source data is not treated as HTML |
true | The source data is treated as HTML |
Warning: Setting the allowHtml option to true can cause serious XSS vulnerabilities.
Read more:
Default: false
Category: Core
Example
columns: [
{
// set the `type` of each cell in this column to `autocomplete`
type: 'autocomplete',
// set options available in every `autocomplete` cell of this column
source: ['<strong>foo</strong>', '<strong>bar</strong>']
// use HTML in the `source` list
allowHtml: true,
},
],
allowInsertColumn
Source codeoptions.allowInsertColumn : boolean
If set to true, the allowInsertColumn option adds the following menu items to the context menu:
- Insert column left
- Insert column right
Default: true
Category: Core
Example
// hide the 'Insert column left' and 'Insert column right' menu items from the context menu
allowInsertColumn: false,
allowInsertRow
Source codeoptions.allowInsertRow : boolean
If set to true, the allowInsertRow option adds the following menu items to the context menu:
- Insert row above
- Insert row below
Default: true
Category: Core
Example
// hide the 'Insert row above' and 'Insert row below' menu items from the context menu
allowInsertRow: false,
allowInvalid
Source codeoptions.allowInvalid : boolean
The allowInvalid option determines whether Handsontable accepts values
that were marked as invalid by the cell validator.
You can set the allowInvalid option to one of the following:
| Setting | Description |
|---|---|
true (default) | - Accept invalid values- Allow the user to close the cell editor with invalid values- Save invalid values into the data source |
false | - Don't accept invalid values- Don't allow the user to close the cell editor with invalid values- Don't save invalid values into the data source |
Setting the allowInvalid option to false can be useful when used with the Autocomplete strict mode.
Read more:
Default: true
Category: Core
Example
// don't accept `invalid` values
// don't allow the user to close the cell editor
// don't save `invalid` values into the data source
allowInvalid: false,
allowRemoveColumn
Source codeoptions.allowRemoveColumn : boolean
If set to true, the allowRemoveColumn option adds the following menu items to the context menu:
- Remove column
Read more:
Default: true
Category: Core
Example
// hide the 'Remove column' menu item from the context menu
allowRemoveColumn: false,
allowRemoveRow
Source codeoptions.allowRemoveRow : boolean
If set to true, the allowRemoveRow option adds the following menu items to the context menu:
- Remove row
Read more:
Default: true
Category: Core
Example
// hide the 'Remove row' menu item from the context menu
allowRemoveRow: false,
ariaTags
Source codeoptions.ariaTags : boolean
If set to true, the accessibility-related ARIA tags will be added to the table. If set to false, they
will be omitted.
Defaults to true.
Default: true
Category: Core
Since: 14.0.0
autoColumnSize
Source codeoptions.autoColumnSize : object | boolean
The autoColumnSize option configures the AutoColumnSize plugin.
You can set the autoColumnSize option to one of the following:
| Setting | Description |
|---|---|
false | Disable the AutoColumnSize plugin |
true | Enable the AutoColumnSize plugin with the default configuration |
| An object | Enable the AutoColumnSize plugin and modify the plugin options |
If you set the autoColumnSize option to an object, you can set the following AutoColumnSize plugin options:
| Property | Possible values | Description |
|---|---|---|
syncLimit | A number | A percentage string | The number/percentage of columns to keep in sync (default: 50) |
useHeaders | true | false | When calculating column widths:true: use column headersfalse: don't use column headers |
samplingRatio | A number | The number of samples of the same length to be used in column width calculations |
allowSampleDuplicates | true | false | When calculating column widths:true: Allow duplicate samplesfalse: Don't allow duplicate samples |
By default, the autoColumnSize option is set to undefined,
but the AutoColumnSize plugin acts as enabled.
To disable the AutoColumnSize plugin completely,
set the autoColumnSize option to false.
Using the colWidths option forcibly disables the AutoColumnSize plugin.
Read more:
Default: undefined
Category: AutoColumnSize
Example
autoColumnSize: {
// keep 40% of columns in sync (the rest of columns: async)
syncLimit: '40%',
// when calculating column widths, use column headers
useHeaders: true,
// when calculating column widths, use 10 samples of the same length
samplingRatio: 10,
// when calculating column widths, allow duplicate samples
allowSampleDuplicates: true
},
autoRowSize
Source codeoptions.autoRowSize : object | boolean
The autoRowSize option configures the AutoRowSize plugin.
You can set the autoRowSize option to one of the following:
| Setting | Description |
|---|---|
false | Disable the AutoRowSize plugin |
true | Enable the AutoRowSize plugin with the default configuration |
| An object | Enable the AutoRowSize plugin and modify the plugin options |
To give Handsontable's scrollbar a proper size, set the autoRowSize option to true.
If you set the autoRowSize option to an object, you can set the following AutoRowSize plugin options:
| Property | Possible values | Description |
|---|---|---|
syncLimit | A number | A percentage string | The number/percentage of rows to keep in sync (default: 500) |
Using the rowHeights option forcibly disables the AutoRowSize plugin.
Read more:
Default: undefined
Category: AutoRowSize
Example
autoRowSize: {
// keep 40% of rows in sync (the rest of rows: async)
syncLimit: '40%'
},
autoWrapCol
Source codeoptions.autoWrapCol : boolean
| Setting | Description |
|---|---|
false (default) | When you select a bottom-most cell, pressing ↓ doesn't do anything. When you select a top-most cell, pressing ↑ doesn't do anything. |
true | When you select a bottom-most cell, pressing ↓ takes you to the top-most cell of the next column. When you select a top-most cell, pressing ↑ takes you to the bottom-most cell of the previous column. |
Default: false
Category: Core
Example
// when you select a bottom-most cell, pressing ⬇ doesn't do anything
// when you select a top-most cell, pressing ⬆ doesn't do anything
autoWrapCol: false, // default setting
// when you select a bottom-most cell, pressing ⬇ takes you to the top-most cell of the next column
// when you select a top-most cell, pressing ⬆ takes you to the bottom-most cell of the previous column
autoWrapCol: true,
autoWrapRow
Source codeoptions.autoWrapRow : boolean
| Setting | Description |
|---|---|
false (default) | When you select the first cell of a row, pressing ←* (or Shift+Tab**) doesn't do anything. When you select the last cell of a row, pressing →* (or Tab**) doesn't do anything. |
true | When you select the first cell of a row, pressing ←* (or Shift+Tab**) takes you to the last cell of the row above. When you select the last cell of a row, pressing →* (or Tab**) takes you to the first cell of the row below. |
* The exact key depends on your layoutDirection configuration.
** Unless tabNavigation is set to false.
Default: false
Category: Core
Example
// when you select the first cell of a row, pressing ⬅ (or Shift+Tab) doesn't do anything
// when you select the last cell of a row, pressing ➡ (or Tab) doesn't do anything
autoWrapRow: false, // default setting
// when you select the first cell of a row, pressing ⬅ (or Shift+Tab) takes you to the last cell of the row above
// when you select the last cell of a row, pressing ➡ (or Tab) takes you to the first cell of the row below
autoWrapRow: true,
bindRowsWithHeaders
Source codeoptions.bindRowsWithHeaders : boolean | string
The bindRowsWithHeaders option configures the BindRowsWithHeaders plugin.
You can set the bindRowsWithHeaders option to one of the following:
| Setting | Description |
|---|---|
false | Disable the the BindRowsWithHeaders plugin |
true | Enable the the BindRowsWithHeaders plugin |
Read more:
Default: undefined
Category: BindRowsWithHeaders
Example
// enable the `BindRowsWithHeaders` plugin
bindRowsWithHeaders: true
cell
Source codeoptions.cell : Array<Array>
The cell option lets you apply configuration options to individual cells.
The cell option overwrites the top-level grid options,
and the columns options.
Read more:
Default: []
Category: Core
Example
// set the `cell` option to an array of objects
cell: [
// make the cell with coordinates (0, 0) read-only
{
row: 0,
col: 0,
readOnly: true
}
],
cells
Source codeoptions.cells : function
The cells option lets you apply any other configuration options to
individual grid elements (columns, rows, cells), based on any logic you implement.
The cells option overwrites all other options (including options set by columns and cell).
It takes the following parameters:
| Parameter | Required | Type | Description |
|---|---|---|---|
row | Yes | Number | A physical row index |
column | Yes | Number | A physical column index |
prop | No | String | Number | If data is set to an array of arrays, prop is the same number as column.If data is set to an array of objects, prop is a property name for the column's data object. |
Read more:
- Configuration options: Implementing custom logic
- Configuration options: Setting row options
columnscell
Default: undefined
Category: Core
Example
// set the `cells` option to your custom function
cells(row, column, prop) {
const cellProperties = { readOnly: false };
const visualRowIndex = this.instance.toVisualRow(row);
const visualColIndex = this.instance.toVisualColumn(column);
if (visualRowIndex === 0 && visualColIndex === 0) {
cellProperties.readOnly = true;
}
return cellProperties;
},
checkedTemplate
Source codeoptions.checkedTemplate : boolean | string | number
The checkedTemplate option lets you configure what value
a checked checkbox cell has.
You can set the checkedTemplate option to one of the following:
| Setting | Description |
|---|---|
true (default) | If a checkbox cell is checked,the getDataAtCell method for this cell returns true |
| A string | If a checkbox cell is checked,the getDataAtCell method for this cell returns a string of your choice |
Read more:
Default: true
Category: Core
Example
columns: [
{
// set the `type` of each cell in this column to `checkbox`
// when checked, the cell's value is `true`
// when unchecked, the cell's value is `false`
type: 'checkbox',
},
{
// set the `type` of each cell in this column to `checkbox`
type: 'checkbox',
// when checked, the cell's value is `'Yes'`
checkedTemplate: 'Yes',
// when unchecked, the cell's value is `'No'`
uncheckedTemplate: 'No'
}
],
className
Source codeoptions.className : string | Array<string>
The className option lets you add CSS class names to every currently-selected element.
You can set the className option to one of the following:
| Setting | Description |
|---|---|
| A string | Add a single CSS class name to every currently-selected element |
| An array of strings | Add multiple CSS class names to every currently-selected element |
TIP
Don't change the className metadata of the column summary row.
To style the summary row, use the class name assigned automatically by the ColumnSummary plugin: columnSummaryResult.
To apply different CSS class names on different levels, use Handsontable's cascading configuration.
Read more:
- Configuration options: Cascading configuration
currentRowClassNamecurrentColClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamecommentedCellClassNamenoWordWrapClassNamereadOnlyCellClassNameTableClassName
Default: undefined
Category: Core
Example
// add a `your-class-name` CSS class name
// to every currently-selected element
className: 'your-class-name',
// add `first-class-name` and `second-class-name` CSS class names
// to every currently-selected element
className: ['first-class-name', 'second-class-name'],
colHeaders
Source codeoptions.colHeaders : boolean | Array<string> | function
The colHeaders option configures your grid's column headers.
You can set the colHeaders option to one of the following:
| Setting | Description |
|---|---|
true | Enable the default column headers ('A', 'B', 'C', ...) |
false | Disable column headers |
| An array | Define your own column headers (e.g. ['One', 'Two', 'Three', ...]) |
| A function | Define your own column headers, using a function |
Read more:
Default: null
Category: Core
Example
// enable the default column headers
colHeaders: true,
// set your own column headers
colHeaders: ['One', 'Two', 'Three'],
// set your own column headers, using a function
colHeaders: function(visualColumnIndex) {
return `${visualColumnIndex} + : AB`;
},
collapsibleColumns
Source codeoptions.collapsibleColumns : boolean | Array<object>
The collapsibleColumns option configures the CollapsibleColumns plugin.
You can set the collapsibleColumns option to one of the following:
| Setting | Description |
|---|---|
false | Disable the CollapsibleColumns plugin |
true | Enable the CollapsibleColumns plugin |
| An array of objects | Enable the CollapsibleColumns plugin for selected column headers |
Read more:
Default: undefined
Category: CollapsibleColumns
Example
// enable column collapsing for all headers
collapsibleColumns: true,
// enable column collapsing for selected headers
collapsibleColumns: [
{row: -4, col: 1, collapsible: true},
{row: -3, col: 5, collapsible: true}
],
columnHeaderHeight
Source codeoptions.columnHeaderHeight : number | Array<number>
The columnHeaderHeight option configures the height of column headers.
You can set the columnHeaderHeight option to one of the following:
| Setting | Description |
|---|---|
| A number | Set the same height for every column header |
| An array | Set different heights for individual column headers |
Default: undefined
Category: Core
Example
// set the same height for every column header
columnHeaderHeight: 25,
// set different heights for individual column headers
columnHeaderHeight: [25, 30, 55],
columns
Source codeoptions.columns : Array<object> | function
The columns option lets you apply any other configuration options to individual columns (or ranges of columns).
You can set the columns option to one of the following:
- An array of objects (each object represents one column)
- A function that returns an array of objects
The columns option overwrites the top-level grid options.
When you use columns, the startCols, minCols, and maxCols options are ignored.
Read more:
Default: undefined
Category: Core
Example
// set the `columns` option to an array of objects
// each object represents one column
columns: [
{
// column options for the first (by physical index) column
type: 'numeric',
numericFormat: {
pattern: '0,0.00 $'
}
},
{
// column options for the second (by physical index) column
type: 'text',
readOnly: true
}
],
// or set the `columns` option to a function, based on physical indexes
columns(index) {
return {
type: index > 0 ? 'numeric' : 'text',
readOnly: index < 1
}
}
columnSorting
Source codeoptions.columnSorting : boolean | object
The columnSorting option configures the ColumnSorting plugin.
You can set the columnSorting option to one of the following:
| Setting | Description |
|---|---|
true | Enable the ColumnSorting plugin with the default configuration |
false | Disable the ColumnSorting plugin |
| An object | - Enable the ColumnSorting plugin- Modify the ColumnSorting plugin options |
If you set the columnSorting option to an object,
you can set the following ColumnSorting plugin options:
| Option | Possible settings |
|---|---|
indicator | true: Display the arrow icon in the column header, to indicate a sortable columnfalse: Don't display the arrow icon in the column header |
headerAction | true: Enable clicking on the column header to sort the columnfalse: Disable clicking on the column header to sort the column |
sortEmptyCells | true: Sort empty cells as wellfalse: Place empty cells at the end |
compareFunctionFactory | A custom compare function |
If you set the columnSorting option to an object,
you can also sort individual columns at Handsontable's initialization.
In the columnSorting object, add an object named initialConfig,
with the following properties:
| Option | Possible settings | Description |
|---|---|---|
column | A number | The index of the column that you want to sort at initialization |
sortOrder | 'asc' | 'desc' | The sorting order:'asc': ascending'desc': descending |
Read more:
Default: undefined
Category: ColumnSorting
Example
// enable the `ColumnSorting` plugin
columnSorting: true
// enable the `ColumnSorting` plugin with custom configuration
columnSorting: {
// sort empty cells as well
sortEmptyCells: true,
// display the arrow icon in the column header
indicator: true,
// disable clicking on the column header to sort the column
headerAction: false,
// add a custom compare function
compareFunctionFactory(sortOrder, columnMeta) {
return function(value, nextValue) {
// some value comparisons which will return -1, 0 or 1...
}
}
}
// enable the `ColumnSorting` plugin
columnSorting: {
// at initialization, sort column 1 in ascending order
initialConfig: {
column: 1,
sortOrder: 'asc'
},
// at initialization, sort column 2 in descending order
initialConfig: {
column: 2,
sortOrder: 'desc'
}
}
columnSummary
Source codeoptions.columnSummary : Array<object> | function
The columnSummary option configures the ColumnSummary plugin.
You can set the columnSummary option to an array of objects.
Each object configures a single column summary, using the following properties:
| Property | Possible values | Description |
|---|---|---|
sourceColumn | A number | Column to summarize |
ranges | An array | Ranges of rows to summarize |
type | 'sum' | 'min' | 'max' | 'count' | 'average' | 'custom' | Summary function |
destinationRow | A number | Destination cell's row coordinate |
destinationColumn | A number | Destination cell's column coordinate |
forceNumeric | true | false | Treat non-numerics as numerics |
reversedRowCoords | true | false | Reverse row coordinates |
suppressDataTypeErrors | true | false | Suppress data type errors |
readOnly | true | false | Make summary cell read-only |
roundFloat | true | false | A number | Round summary result |
customFunction | A function | Custom summary function |
Read more:
Default: undefined
Category: ColumnSummary
Example
columnSummary: [
{
sourceColumn: 0,
ranges: [
[0, 2], [4], [6, 8]
],
type: 'custom',
destinationRow: 4,
destinationColumn: 1,
forceNumeric: true,
reversedRowCoords: true,
suppressDataTypeErrors: false,
readOnly: true,
roundFloat: false,
customFunction(endpoint) {
return 100;
}
}
],
colWidths
Source codeoptions.colWidths : number | Array<number> | string | Array<string> | Array<undefined> | function
The colWidths option sets columns' widths, in pixels.
The default column width is 50px. To change it, set the colWidths option to one of the following:
| Setting | Description | Example |
|---|---|---|
| A number | Set the same width for every column | colWidths: 100 |
| A string | Set the same width for every column | colWidths: '100px' |
| An array | Set widths separately for each column | colWidths: [100, 120, undefined] |
| A function | Set column widths dynamically, on each render | colWidths(visualColumnIndex) { return visualColumnIndex * 10; } |
undefined | Used by the modifyColWidth hook, to detect column width changes. | colWidths: undefined |
Setting colWidths even for a single column disables the AutoColumnSize plugin
for all columns. For this reason, if you use colWidths, we recommend you set a width for each one
of your columns. Otherwise, every column with an undefined width defaults back to 50px,
which may cut longer columns names.
Read more:
Default: undefined
Category: Core
Example
// set every column's width to 100px
colWidths: 100,
// set every column's width to 100px
colWidths: '100px',
// set the first (by visual index) column's width to 100
// set the second (by visual index) column's width to 120
// set the third (by visual index) column's width to `undefined`, so that it defaults to 50px
// set any other column's width to the default 50px (note that longer cell values and column names can get cut)
colWidths: [100, 120, undefined],
// set each column's width individually, using a function
colWidths(visualColumnIndex) {
return visualColumnIndex * 10;
},
commentedCellClassName
Source codeoptions.commentedCellClassName : string
The commentedCellClassName option lets you add a CSS class name to cells
that have comments.
Read more:
- Comments
commentsreadOnlyCellClassNamecurrentRowClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamereadOnlyCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: "htCommentCell"
Category: Core
Example
// add a `has-comment` CSS class name
// to each cell that has a comment
commentedCellClassName: 'has-comment',
comments
Source codeoptions.comments : boolean | Array<object>
The comments option configures the Comments plugin.
You can set the comments option to one of the following:
| Setting | Description |
|---|---|
true | - Enable the Comments plugin- Add comment menu items to the context menu |
false | Disable the Comments plugin |
| An object | - Enable the Comments plugin- Add comment menu items to the context menu - Configure comment settings |
If you set the comments option to an object, you can configure the following comment options:
| Option | Possible settings | Description |
|---|---|---|
displayDelay | A number (default: 250) | Display comments after a delay (in milliseconds) |
readOnly | true | false (default) | true: Make comments read-only |
style | An object | Set comment boxes' width and height (in pixels) |
Read more:
Default: false
Category: Comments
Example
// enable the `Comments` plugin
comments: true,
// enable the `Comments` plugin
// and configure its settings
comments: {
// display all comments with a 1-second delay
displayDelay: 1000,
// make all comments read-only
readOnly: true,
// set the default size of all comment boxes
style: {
width: 300,
height: 100
}
}
contextMenu
Source codeoptions.contextMenu : boolean | Array<string> | object
The contextMenu option configures the ContextMenu plugin.
You can set the contextMenu option to one of the following:
| Setting | Description |
|---|---|
false | Disable the ContextMenu plugin |
true | - Enable the ContextMenu plugin- Use the default context menu options |
| An array | - Enable the ContextMenu plugin- Modify individual context menu options |
| An object | - Enable the ContextMenu plugin- Apply a custom context menu configuration |
Read more:
- Context menu
- Context menu: Context menu with default options
- Context menu: Context menu with specific options
- Context menu: Context menu with fully custom configuration options
- Plugins:
ContextMenu
Default: undefined
Category: ContextMenu
Example
// enable the `ContextMenu` plugin
// use the default context menu options
contextMenu: true,
// enable the `ContextMenu` plugin
// and modify individual context menu options
contextMenu: ['row_above', 'row_below', '---------', 'undo', 'redo'],
// enable the `ContextMenu` plugin
// and apply a custom context menu configuration
contextMenu: {
items: {
'option1': {
name: 'Option 1'
},
'option2': {
name: 'Option 2',
submenu: {
items: [
{
key: 'option2:suboption1',
name: 'Suboption 1',
callback: function(key, options) {
...
}
},
...
]
}
}
}
},
copyable
Source codeoptions.copyable : boolean
The copyable option determines whether a cell's value can be copied to the clipboard or not.
You can set the copyable option to one of the following:
| Setting | Description |
|---|---|
true (default) | - On pressing Ctrl/Cmd+C, add the cell's value to the clipboard |
false(default for the password cell type) | - On pressing Ctrl/Cmd+C, add an empty string ("") to the clipboard |
Read more:
Default: true
Category: Core
Example
// enable copying for each cell of the entire grid
copyable: true,
// enable copying for individual columns
columns: [
{
// enable copying for each cell of this column
copyable: true
},
{
// disable copying for each cell of this column
copyable: false
}
]
// enable copying for specific cells
cell: [
{
col: 0,
row: 0,
// disable copying for cell (0, 0)
copyable: false,
}
],
copyPaste
Source codeoptions.copyPaste : object | boolean
The copyPaste option configures the CopyPaste plugin.
You can set the copyPaste option to one of the following:
| Setting | Description |
|---|---|
true (default) | Enable the CopyPaste plugin with the default configuration |
false | Disable the CopyPaste plugin |
| An object | - Enable the CopyPaste plugin- Modify the CopyPaste plugin options |
copyPaste: Additional options
If you set the copyPaste option to an object, you can set the following CopyPaste plugin options:
| Option | Possible settings | Description |
|---|---|---|
columnsLimit | A number (default: Infinity) | The maximum number of columns that can be copied |
rowsLimit | A number (default: Infinity) | The maximum number of columns that can be copied |
pasteMode | 'overwrite' | 'shift_down' | 'shift_right' | When pasting:'overwrite': overwrite the currently-selected cells'shift_down': move the currently-selected cells down'shift_right': move the currently-selected cells to the right |
copyColumnHeaders | Boolean (default: false) | true: add a context menu option for copying cells along with their nearest column headers |
copyColumnGroupHeaders | Boolean (default: false) | true: add a context menu option for copying cells along with all their related columns headers |
copyColumnHeadersOnly | Boolean (default: false) | true: add a context menu option for copying column headers nearest to the selected cells (without copying cells) |
uiContainer | An HTML element | The UI container for the secondary focusable element |
Read more:
Default: true
Category: CopyPaste
Example
// enable the plugin with the default configuration
copyPaste: true // set by default
// disable the plugin
copyPaste: false,
// enable the plugin with a custom configuration
copyPaste: {
// set a maximum number of columns that can be copied
columnsLimit: 25,
// set a maximum number of rows that can be copied
rowsLimit: 50,
// set the paste behavior
pasteMode: 'shift_down',
// add the option to copy cells along with their nearest column headers
copyColumnHeaders: true,
// add the option to copy cells along with all their related columns headers
copyColumnGroupHeaders: true,
// add the option to copy just column headers (without copying cells)
copyColumnHeadersOnly: true,
// set a UI container
uiContainer: document.body,
},
correctFormat Deprecated
Source codeoptions.correctFormat : boolean
WARNING
This option is deprecated and will be removed in the next major release.
The correctFormat option configures whether incorrectly-formatted times and dates are amended or not.
When the user enters dates and times, Handsontable can automatically adjust their format
to match the dateFormat and timeFormat settings.
You can set the correctFormat option to one of the following:
| Setting | Description |
|---|---|
false (default) | Don't correct the format of the entered date or time (treat the entered date or time as invalid) |
true | Correct the format of the entered date or time to match the dateFormat or timeFormat settings |
Read more:
Default: false
Category: Core
Example
columns: [
{
// set the `type` of each cell in this column to `date`
type: 'date',
// for every `date` cell of this column, set the date format to `YYYY-MM-DD`
dateFormat: 'YYYY-MM-DD',
// enforce the `YYYY-MM-DD` date format
correctFormat: true
},
{
// set the `type` of each cell in this column to `time`
type: 'time',
// for every `time` cell of this column, set the time format to `h:mm:ss a`
timeFormat: 'h:mm:ss a',
// enforce the `h:mm:ss a` time format
correctFormat: true
},
],
currentColClassName
Source codeoptions.currentColClassName : string
The currentColClassName option lets you add a CSS class name
to each cell of the currently-visible, currently-selected columns.
Read more:
currentRowClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: undefined
Category: Core
Example
// add a `your-class-name` CSS class name
// to each cell of the currently-visible, currently-selected columns
currentColClassName: 'your-class-name',
currentHeaderClassName
Source codeoptions.currentHeaderClassName : string
The currentHeaderClassName option lets you add a CSS class name
to every currently-visible, currently-selected header.
Read more:
currentRowClassNamecurrentColClassNameactiveHeaderClassNameinvalidCellClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: "ht__highlight"
Category: Core
Example
// add an `ht__highlight` CSS class name
// to every currently-visible, currently-selected header
currentHeaderClassName: 'ht__highlight',
currentRowClassName
Source codeoptions.currentRowClassName : string
The currentRowClassName option lets you add a CSS class name
to each cell of the currently-visible, currently-selected rows.
Read more:
currentColClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: undefined
Category: Core
Example
// add a `your-class-name` CSS class name
// to each cell of the currently-visible, currently-selected rows
currentRowClassName: 'your-class-name',
customBorders
Source codeoptions.customBorders : boolean | Array<object>
The customBorders option configures the CustomBorders plugin.
To enable the CustomBorders plugin
(and add its menu items to the context menu),
set the customBorders option to true.
To enable the CustomBorders plugin
and add a predefined border around a particular cell,
set the customBorders option to an array of objects.
Each object represents a border configuration for one cell, and has the following properties:
| Property | Sub-properties | Types | Description |
|---|---|---|---|
row | - | row: Number | The cell's row coordinate. |
col | - | col: Number | The cell's column coordinate. |
start | widthcolorstyle | width: Numbercolor: Stringstyle: String | If the layout direction is LTR (default): start sets the width (width), color (color) and style (style) of the left-hand border.If the layout direction is RTL: start sets the width (width), color (color) and style (style) of the right-hand border. |
end | widthcolorstyle | width: Numbercolor: Stringstyle: String | If the layout direction is LTR (default): end sets the width (width), color (color) and style (style) of the right-hand border.If the layout direction is RTL: end sets the width (width), color (color) and style (style) of the left-hand border. |
top | widthcolorstyle | width: Numbercolor: Stringstyle: String | Sets the width (width), color (color) and style (style) of the top border. |
bottom | widthcolorstyle | width: Numbercolor: Stringstyle: String | Sets the width (width), color (color) and style (style) of the bottom border. |
To enable the CustomBorders plugin
and add a predefined border around a range of cells,
set the customBorders option to an array of objects.
Each object represents a border configuration for a single range of cells, and has the following properties:
| Property | Sub-properties | Types | Description |
|---|---|---|---|
range | from {row, col}to {row, col} | from: Objectto: Objectrow: Numbercol: Number | If the layout direction is LTR (default): - from selects the range's top-left corner.- to selects the range's bottom-right corner.If the layout direction is RTL: - from selects the range's top-right corner.- to selects the range's bottom-left corner. |
start | widthcolorstyle | width: Numbercolor: Stringstyle: String | If the layout direction is LTR (default): start sets the width (width), color (color) and style (style) of the left-hand border.If the layout direction is RTL: start sets the width (width), color (color) and style (style) of the right-hand border. |
end | widthcolorstyle | width: Numbercolor: Stringstyle: String | If the layout direction is LTR (default): end sets the width (width), color (color) and style (style) of the right-hand border.If the layout direction is RTL: end sets the width (width), color (color) and style (style) of the left-hand border. |
top | widthcolorstyle | width: Numbercolor: Stringstyle: String | Sets the width (width), color (color) and style (style) of the top border. |
bottom | widthcolorstyle | width: Numbercolor: Stringstyle: String | Sets the width (width), color (color) and style (style) of the bottom border. |
Read more:
- Formatting cells: Custom cell borders
- Context menu
- Plugins:
CustomBorders - Layout direction
layoutDirection
Default: false
Category: CustomBorders
Example
// enable the `CustomBorders` plugin
customBorders: true,
// enable the `CustomBorders` plugin
// and add a predefined border for a particular cell
customBorders: [
// add an object with a border configuration for one cell
{
// set the cell's row coordinate
row: 2,
// set the cell's column coordinate
col: 2,
// set the left/right border's width and color
start: {
width: 2,
color: 'red'
},
// set the right/left border's width, color and style
end: {
width: 1,
color: 'green',
style: 'dashed'
},
// set the top border's width and color
top: '',
// set the bottom border's width and color
bottom: ''
}
],
// enable the `CustomBorders` plugin
// and add a predefined border for a range of cells
customBorders: [
// add an object with a border configuration for one range of cells
{
// select a range of cells
range: {
// set the range's top-left corner
from: {
row: 1,
col: 1
},
// set the range's bottom-right corner
to: {
row: 3,
col: 4
}
},
// set the left/right border's width, color and style
start: {
width: 2,
color: 'red',
style: 'dashed'
},
// set the right/left border's width and color
end: {},
// set the top border's width and color
top: {},
// set the bottom border's width and color
bottom: {}
}
],
data
Source codeoptions.data : Array<Array> | Array<object>
The data option sets the initial data of your Handsontable instance.
Handsontable's data is bound to your source data by reference (i.e. when you edit Handsontable's data, your source data alters as well).
You can set the data option:
- Either to an array of arrays.
- Or to an array of objects.
If you don't set the data option (or set it to null), Handsontable renders as an empty 5x5 grid by default.
Read more:
Default: undefined
Category: Core
Example
// as an array of arrays
data: [
['A', 'B', 'C'],
['D', 'E', 'F'],
['G', 'H', 'J']
]
// as an array of objects
data: [
{id: 1, name: 'Ted Right'},
{id: 2, name: 'Frank Honest'},
{id: 3, name: 'Joan Well'},
{id: 4, name: 'Gail Polite'},
{id: 5, name: 'Michael Fair'},
]
dataDotNotation
Source codeoptions.dataDotNotation : boolean
If true, Handsontable will interpret the dots in the columns mapping as a nested object path. If your dataset contains
the dots in the object keys and you don't want Handsontable to interpret them as a nested object path, set this option to false.
The option only works when defined in the global table settings.
Default: true
Category: Core
Since: 14.4.0
Example
// All dots are interpreted as nested object paths
dataDotNotation: true,
data: [
{ id: 1, name: { first: 'Ted', last: 'Right' }, user: { address: '1234 Any Street' } },
],
columns={[
{ data: 'name.first' },
{ data: 'user.address' },
]},
// All dots are interpreted as simple object keys
dataDotNotation: false,
data: [
{ id: 1, 'name.first': 'Ted', 'user.address': '1234 Any Street' },
],
columns={[
{ data: 'name.first' },
{ data: 'user.address' },
]},
dataSchema
Source codeoptions.dataSchema : object | function
When the data option is set to an array of objects
(or is empty), the dataSchema option defines the structure of new rows.
Using the dataSchema option, you can start out with an empty grid.
You can set the dataSchema option to one of the following:
- An object
- A function
Read more:
- Binding to data: Array of objects with custom data schema
- Binding to data: Function data source and schema
data
Default: undefined
Category: Core
Example
// with `dataSchema`, you can start with an empty grid
data: null,
dataSchema: {id: null, name: {first: null, last: null}, address: null},
colHeaders: ['ID', 'First Name', 'Last Name', 'Address'],
columns: [
{data: 'id'},
{data: 'name.first'},
{data: 'name.last'},
{data: 'address'}
],
startRows: 5,
minSpareRows: 1
dateFormat
Source codeoptions.dateFormat : string | object
Configures the date format for date cells. Accepts either a string (legacy, for date
cells) or an object of Intl.DateTimeFormat (opens new window)
options (for intl-date cells).
WARNING
The string form of dateFormat is deprecated and will be removed in the next major release.
It is used only by the date cell type (moment.js-based). Use the intl-date cell type
with an Intl.DateTimeFormat options object instead. In the next major release, intl-date
will become the default date cell type, and intl-date will be an alias for date.
Object form (Intl.DateTimeFormat options):
The object form is supported only when the cell type is intl-date. The locale is controlled separately via the locale option.
Source data format
For intl-date cells, source data must be in an ISO 8601 date format (YYYY-MM-DD). Otherwise operations such
as sorting and filtering can be unstable or unpredictable. The dateFormat object affects only how dates are
displayed; the underlying value should remain ISO.
Style shortcuts:
| Property | Possible values | Description |
|---|---|---|
dateStyle | 'full', 'long', 'medium', 'short' | Date formatting style (expands to weekday, day, month, year, era) |
timeStyle | 'full', 'long', 'medium', 'short' | Time formatting style (expands to hour, minute, second, timeZoneName) |
Date-time component options:
| Property | Possible values | Description |
|---|---|---|
weekday | 'long', 'short', 'narrow' | Representation of the weekday |
era | 'long', 'short', 'narrow' | Representation of the era |
year | 'numeric', '2-digit' | Representation of the year |
month | 'numeric', '2-digit', 'long', 'short', 'narrow' | Representation of the month |
day | 'numeric', '2-digit' | Representation of the day |
dayPeriod | 'narrow', 'short', 'long' | Day period (e.g. "am", "noon") |
hour | 'numeric', '2-digit' | Representation of the hour |
minute | 'numeric', '2-digit' | Representation of the minute |
second | 'numeric', '2-digit' | Representation of the second |
fractionalSecondDigits | 1, 2, 3 | Fraction-of-second digits |
timeZoneName | 'long', 'short', 'shortOffset', 'longOffset', 'shortGeneric', 'longGeneric' | Time zone display |
Locale and other options:
| Property | Possible values | Description |
|---|---|---|
localeMatcher | 'best fit' (default), 'lookup' | Locale matching algorithm |
calendar | 'chinese', 'gregory', 'persian', etc. | Calendar to use |
numberingSystem | 'latn', 'arab', 'hans', etc. | Numbering system |
timeZone | IANA time zone (e.g. 'UTC', 'America/New_York') | Time zone for formatting |
hour12 | true, false | Use 12-hour vs 24-hour time |
hourCycle | 'h11', 'h12', 'h23', 'h24' | Hour cycle |
formatMatcher | 'basic', 'best fit' (default) | Format matching algorithm |
For complete reference, see MDN: Intl.DateTimeFormat (opens new window).
Read more:
Deprecated: string form
Passing a string (e.g. 'DD/MM/YYYY', 'YYYY-MM-DD') is deprecated and works only with the date cell type.
Migrate to the intl-date cell type and pass an Intl.DateTimeFormat options object.
Migration example:
// Before (deprecated)
columns: [{
type: 'date',
dateFormat: 'YYYY-MM-DD'
}]
// After (recommended)
columns: [{
type: 'intl-date',
locale: 'en-US',
dateFormat: {
year: 'numeric',
month: '2-digit',
day: '2-digit'
}
}]
Default: "DD/MM/YYYY"
Category: Core
Example
// intl-date cell type with Intl options
columns: [
{
type: 'intl-date',
locale: 'en-US',
dateFormat: {
dateStyle: 'short'
}
}
]
Example
// Legacy: date cell type with string format (deprecated)
columns: [
{
type: 'date',
dateFormat: 'YYYY-MM-DD'
}
]
datePickerConfig Deprecated
Source codeoptions.datePickerConfig : object
WARNING
This option is deprecated and will be removed in the next major release.
The datePickerConfig option configures the date cell editor's date picker, which uses an external dependency: Pikaday (opens new window).
You can set the datePickerConfig option to an object with any of the available Pikaday options (opens new window),
except for the following, which are always overwritten by the date cell editor:
boundcontainerfieldtrigger
If the datePickerConfig option is not defined, the date cell editor overwrites the following Pikaday options (opens new window) as well:
| Pikaday option | Handsontable's setting |
|---|---|
format | 'DD/MM/YYYY' |
reposition | false |
Read more:
Default: undefined
Category: Core
defaultDate
Source codeoptions.defaultDate : string
The defaultDate option configures the date displayed
in the editor for an empty date cell.
The option accepts a string in ISO 8601 format (YYYY-MM-DD).
Read more:
Default: undefined
Category: Core
Example
columns: [
{
type: 'date',
defaultDate: '2015-02-02'
}
],
dialog
Source codeoptions.dialog : boolean | object
The dialog option configures the Dialog plugin.
You can set the dialog option to one of the following:
| Setting | Description |
|---|---|
false | Disable the Dialog plugin |
true | Enable the Dialog plugin with default options |
dialog: Additional options
| Option | Possible settings | Description |
|---|---|---|
template | Object with the template configuration (default: null). | The template of the dialog allows to use prebuild templates |
template.type | The type of the template ('confirm') | The type of the template |
template.title | The title of the template | The title of the template |
template.description | The description of the template | The description of the template |
template.buttons | Array of objects with the buttons configuration (default: []) | The buttons of the template |
template.buttons.text | The text of the button | The text of the button |
template.buttons.type | The type of the button ('primary' | 'secondary') |
template.buttons.callback | The callback function to trigger when the button is clicked | The callback function to trigger when the button is clicked |
content | A string, HTMLElement or DocumentFragment (default: '') | The content of the dialog |
customClassName | A string (default: '') | The custom class name of the dialog |
background | One of the options: 'solid' or 'semi-transparent' (default: 'solid') | The background of the dialog |
contentBackground | Boolean (default: false) | Whether to show the content background |
animation | Boolean (default: true) | Whether to show the animation |
closable | Boolean (default: false) | Whether to make the dialog closable |
a11y | Object with accessibility options (default: { role: 'dialog', ariaLabel: 'Dialog', ariaLabelledby: '', ariaDescribedby: '' }) | Accessibility options for the dialog |
a11y.role | The role of the dialog ('dialog' | 'alertdialog') |
a11y.ariaLabel | The label of the dialog | The label of the dialog |
a11y.ariaLabelledby | The ID of the element that labels the dialog | The ID of the element that labels the dialog |
a11y.ariaDescribedby | The ID of the element that describes the dialog | The ID of the element that describes the dialog |
Read more:
Default: false
Category: Dialog
Since: 16.1.0
Example
settings = {
dialog: {
content: 'Dialog content',
customClassName: 'custom-dialog',
background: 'semi-transparent',
contentBackground: false,
animation: false,
closable: true,
a11y: {
role: 'dialog',
ariaLabel: 'Dialog',
ariaLabelledby: 'titleID',
ariaDescribedby: 'descriptionID',
}
}
};
// enable the Dialog plugin using a template
settings = {
dialog: {
template: {
type: 'confirm',
title: 'Confirm',
description: 'Do you want change the value?',
}
}
};
<hot-table [settings]="settings" />
disableVisualSelection
Source codeoptions.disableVisualSelection : boolean | string | Array<string>
The disableVisualSelection option configures how
selection is shown.
You can set the disableVisualSelection option to one of the following:
| Setting | Description |
|---|---|
false (default) | - Show single-cell selection - Show range selection - Show header selection |
true | - Don't show single-cell selection - Don't show range selection - Don't show header selection |
'current' | - Don't show single-cell selection - Show range selection - Show header selection |
'area' | - Show single-cell selection - Don't show range selection - Show header selection |
'header' | - Show single-cell selection - Show range selection - Don't show header selection |
| An array | A combination of 'current', 'area', and/or 'header' |
Read more:
Default: false
Category: Core
Example
// don't show single-cell selection
// don't show range selection
// don't show header selection
disableVisualSelection: true,
// don't show single-cell selection
// show range selection
// show header selection
disableVisualSelection: 'current',
// don't show single-cell selection
// don't show range selection
// show header selection
disableVisualSelection: ['current', 'area'],
dragToScroll
Source codeoptions.dragToScroll : boolean
The dragToScroll option configures the DragToScroll plugin.
You can set the dragToScroll option to one of the following:
| Setting | Description |
|---|---|
true (default) | When selection reaches the edge of the grid's viewport, scroll the viewport |
false | Don't scroll the viewport |
Read more:
Default: true
Category: DragToScroll
Example
// when selection reaches the edge of the grid's viewport, scroll the viewport
dragToScroll: true,
dropdownMenu
Source codeoptions.dropdownMenu : boolean | object | Array<string>
The dropdownMenu option configures the DropdownMenu plugin.
You can set the dropdownMenu option to one of the following:
| Setting | Description |
|---|---|
false | Disable the DropdownMenu plugin |
true | - Enable the DropdownMenu plugin- Use the default context menu options |
| An array | - Enable the DropdownMenu plugin- Modify individual context menu options |
| An object | - Enable the DropdownMenu plugin- Apply a custom dropdown menu configuration |
Read more:
Default: undefined
Category: DropdownMenu
Example
// enable the `DropdownMenu` plugin
// use the default context menu options
dropdownMenu: true,
// enable the `DropdownMenu` plugin
// and modify individual context menu options
dropdownMenu: ['---------', 'undo', 'redo'],
// enable the `DropdownMenu` plugin
// and apply a custom dropdown menu configuration
dropdownMenu: {
items: {
'option1': {
name: 'Option 1'
},
'option2': {
name: 'Option 2',
submenu: {
items: [
{
key: 'option2:suboption1',
name: 'Suboption 1',
callback(key, options) {
...
}
},
...
]
}
}
}
},
editor
Source codeoptions.editor : string | function | boolean
The editor option sets a cell editor for a cell.
You can set the editor option to one of the following cell editor aliases:
| Alias | Cell editor function |
|---|---|
| A custom alias | Your custom cell editor function |
'autocomplete' | AutocompleteEditor |
'base' | BaseEditor |
'checkbox' | CheckboxEditor |
'date' | DateEditor |
'intl-date' | IntlDateEditor |
'dropdown' | DropdownEditor |
'handsontable' | HandsontableEditor |
'numeric' | NumericEditor |
'password' | PasswordEditor |
'select' | SelectEditor |
'text' | TextEditor |
'time' | TimeEditor |
'intl-time' | IntlTimeEditor |
To disable editing cells through cell editors,
set the editor option to false.
You'll still be able to change cells' content through Handsontable's API
or through plugins (e.g. CopyPaste), though.
To set the editor, renderer, and validator
options all at once, use the type option.
Read more:
Default: undefined
Category: Core
Example
// use the `numeric` editor for each cell of the entire grid
editor: 'numeric',
// apply the `editor` option to individual columns
columns: [
{
// use the `autocomplete` editor for each cell of this column
editor: 'autocomplete'
},
{
// disable editing cells through cell editors for each cell of this column
editor: false
}
]
emptyDataState
Source codeoptions.emptyDataState : boolean | object
The emptyDataState option configures the EmptyDataState plugin.
You can set the emptyDataState option to one of the following:
| Setting | Description |
|---|---|
false | Disable the EmptyDataState plugin |
true | Enable the EmptyDataState plugin |
| An object | Enable the EmptyDataState plugin with custom settings |
If you set the emptyDataState option to an object, you can configure the following settings:
| Property | Possible values | Description |
|---|---|---|
message | string | object | function | Message to display in the empty data state overlay. |
If you set the message option to an object, it have following properties:
| Property | Possible values | Description |
|---|---|---|
title | string | Title to display in the empty data state overlay. |
description | string | Description to display in the empty data state overlay. |
buttons | array | Buttons to display in the empty data state overlay. |
If you set the buttons option to an array, each item requires following properties:
| Property | Possible values | Description |
|---|---|---|
text | string | Text to display in the button. |
type | 'primary' | 'secondary' | Type of the button. |
callback | function | Callback function to call when the button is clicked. |
Read more:
Default: false
Category: EmptyDataState
Since: 16.2.0
Example
// Enable empty data state plugin with default messages
emptyDataState: true,
// Enable empty data state plugin with custom message
emptyDataState: {
message: 'No data available',
},
// Enable empty data state plugin with custom message and buttons for any source
emptyDataState: {
message: {
title: 'No data available',
description: 'There’s nothing to display yet.',
buttons: [{ text: 'Reset filters', type: 'secondary', callback: () => {} }],
},
},
// Enable empty data state plugin with custom message and buttons for specific source
emptyDataState: {
message: (source) => {
switch (source) {
case "filters":
return {
title: 'No data available',
description: 'There’s nothing to display yet.',
buttons: [{ text: 'Reset filters', type: 'secondary', callback: () => {} }],
};
default:
return {
title: 'No data available',
description: 'There’s nothing to display yet.',
};
}
},
},
enterBeginsEditing
Source codeoptions.enterBeginsEditing : boolean
The enterBeginsEditing option configures the action of the Enter key.
You can set the enterBeginsEditing option to one of the following:
| Setting | Description |
|---|---|
true (default) | - On pressing Enter once, enter the editing mode of the active cell - On pressing Enter twice, move to another cell, as configured by the enterMoves setting |
false | - On pressing Enter once, move to another cell, as configured by the enterMoves setting |
Read more:
Default: true
Category: Core
Example
// press Enter once to start editing
// press Enter twice to move to another cell
enterBeginsEditing: true,
// press Enter once to move to another cell
enterBeginsEditing: false,
enterCommits
Source codeoptions.enterCommits : boolean
The enterCommits option configures whether the Enter key closes the multiSelect editor.
Default: true
Category: Core
Since: 17.0.0
Example
columns: [{
type: 'multiSelect',
// press Enter to close the `multiSelect` editor and Space to select an option
enterCommits: true,
}, {
type: 'multiSelect',
// press Enter to select an option
enterCommits: false,
}],
],
enterMoves
Source codeoptions.enterMoves : object | function
The enterMoves option configures the action of the Enter key.
If the enterBeginsEditing option is set to true,
the enterMoves setting applies to the second pressing of the Enter key.
If the enterBeginsEditing option is set to false,
the enterMoves setting applies to the first pressing of the Enter key.
You can set the enterMoves option to an object with the following properties
(or to a function that returns such an object):
| Property | Type | Description |
|---|---|---|
col | Number | - On pressing Enter, move selection col columns right- On pressing Shift+Enter, move selection col columns left |
row | Number | - On pressing Enter, move selection row rows down- On pressing Shift+Enter, move selection row rows up |
Read more:
Default: {col: 0, row: 1}
Category: Core
Example
// on pressing Enter, move selection 1 column right and 1 row down
// on pressing Shift+Enter, move selection 1 column left and 1 row up
enterMoves: {col: 1, row: 1},
// the same setting, as a function
// `event` is a DOM Event object received on pressing Enter
// you can use it to check whether the user pressed Enter or Shift+Enter
enterMoves(event) {
return {col: 1, row: 1};
},
fillHandle
Source codeoptions.fillHandle : boolean | string | object
The fillHandle option configures the Autofill plugin.
You can set the fillHandle option to one the following:
| Setting | Description |
|---|---|
true | - Enable autofill in all directions - Add the fill handle |
false | Disable autofill |
'vertical' | - Enable vertical autofill - Add the fill handle |
'horizontal' | - Enable horizontal autofill - Add the fill handle |
| An object | - Enable autofill - Add the fill handle - Configure autofill options |
If you set the fillHandle option to an object, you can configure the following autofill options:
| Option | Possible settings | Description |
|---|---|---|
autoInsertRow | true (default) | false | true: When you reach the grid's bottom, add new rowsfalse: When you reach the grid's bottom, stop |
direction | 'vertical' | 'horizontal' | 'vertical': Enable vertical autofill'horizontal': Enable horizontal autofill |
Read more:
Default: true
Category: Core
Example
// enable autofill in all directions
// with `autoInsertRow` enabled
fillHandle: true,
// enable vertical autofill
// with `autoInsertRow` enabled
fillHandle: 'vertical',
// enable horizontal autofill
// with `autoInsertRow` enabled
fillHandle: 'horizontal',
// enable autofill in all directions
// with `autoInsertRow` disabled
fillHandle: {
autoInsertRow: false,
},
// enable vertical autofill
// with `autoInsertRow` disabled
fillHandle: {
autoInsertRow: false,
direction: 'vertical'
},
filter
Source codeoptions.filter : boolean
The filter option configures whether autocomplete cells'
lists are updated by the end user's input.
You can set the filter option to one of the following:
| Setting | Description |
|---|---|
true (default) | When the end user types into the input area, only options matching the input are displayed |
false | When the end user types into the input area, all options are displayed (options matching the input are put in bold |
Read more:
Default: true
Category: Core
Example
columns: [{
// set the `type` of each cell in this column to `autocomplete`
type: 'autocomplete',
// set options available in every `autocomplete` cell of this column
source: ['A', 'B', 'C'],
// when the end user types in `A`, display only the A option
// when the end user types in `B`, display only the B option
// when the end user types in `C`, display only the C option
filter: true
}],
filteringCaseSensitive
Source codeoptions.filteringCaseSensitive : boolean
The filteringCaseSensitive option configures whether autocomplete and multiSelect-typed cells'
search inputs are case-sensitive.
You can set the filteringCaseSensitive option to one of the following:
| Setting | Description |
|---|---|
false (default) | autocomplete cells' input is not case-sensitive |
true | autocomplete cells' input is case-sensitive |
Read more:
Default: false
Category: Core
Example
columns: [
{
type: 'autocomplete',
source: [ ... ],
// match case while searching autocomplete options
filteringCaseSensitive: true
},
{
type: 'multiSelect',
source: [ ... ],
// match case while searching multiSelect options
filteringCaseSensitive: true
}
],
filters
Source codeoptions.filters : boolean
The filters option configures the Filters plugin.
You can set the filters option to one of the following:
| Setting | Description |
|---|---|
false | Disable the Filters plugin |
true | Enable the Filters plugin |
| An object | Enable the Filters plugin with custom settings |
If you set the filters option to an object, you can configure the following settings:
| Property | Possible values | Description |
|---|---|---|
searchMode | 'show' | 'apply' | Enable filtering only visible elements |
If filers is set to true, the searchMode option is set to 'show' by default.
Read more:
Default: undefined
Category: Filters
Example
// enable the `Filters` plugin
filters: true,
filterSelectedItems
Source codeoptions.filterSelectedItems : boolean
The filterSelectedItems option configures whether the selected items are filtered out of the dropdown, when using the search input of the multiSelect editor.
Default: true
Category: Core
Example
// filter out the selected items from the dropdown
filterSelectedItems: true,
// keep the selected items in the dropdown
filterSelectedItems: false,
### fixedColumnsLeft
::: source-code-link https://github.com/handsontable/handsontable/blob/53e039566708d1b19ea3cf69f74562bd0dcda552/handsontable/src/dataMap/metaManager/metaSchema.js#L2729
:::
_options.fixedColumnsLeft : number_
`fixedColumnsLeft` is a legacy option.
If your grid's [layout direction](/angular-data-grid/layout-direction/) is LTR (default), `fixedColumnsLeft` acts like the [`fixedColumnsStart`](#fixedcolumnsstart) option.
If your grid's [layout direction](/angular-data-grid/layout-direction/) is RTL, using `fixedColumnsLeft` throws an error.
Use [`fixedColumnsStart`](#fixedcolumnsstart), which works in any layout direction.
Read more:
- [`fixedColumnsStart`](#fixedcolumnsstart)
**Default**: <code>0</code>
**Category**: [Core](/angular-data-grid/api/core/)
**Example**
```js
// freeze the first 3 columns from the left
fixedColumnsLeft: 3,
fixedColumnsStart
Source codeoptions.fixedColumnsStart : number
If your grid's layout direction is LTR (default), the fixedColumnsStart option sets the number of frozen columns at the left-hand edge of the grid.
If your grid's layout direction is RTL, the fixedColumnsStart option sets the number of frozen columns at the right-hand edge of the grid.
Read more:
Default: 0
Category: Core
Example
// when `layoutDirection` is set to `inherit` (default)
// freeze the first 3 columns from the left or from the right
// depending on your HTML document's `dir` attribute
layoutDirection: 'inherit',
fixedColumnsStart: 3,
// when `layoutDirection` is set to `rtl`
// freeze the first 3 columns from the right
// regardless of your HTML document's `dir` attribute
layoutDirection: 'rtl',
fixedColumnsStart: 3,
// when `layoutDirection` is set to `ltr`
// freeze the first 3 columns from the left
// regardless of your HTML document's `dir` attribute
layoutDirection: 'ltr',
fixedColumnsStart: 3,
fixedRowsBottom
Source codeoptions.fixedRowsBottom : number
The fixedRowsBottom option sets the number of frozen rows
at the bottom of the grid.
Read more:
Default: 0
Category: Core
Example
// freeze the bottom 3 rows
fixedRowsBottom: 3,
fixedRowsTop
Source codeoptions.fixedRowsTop : number
The fixedRowsTop option sets the number of frozen rows at the top of the grid.
Read more:
Default: 0
Category: Core
Example
// freeze the top 3 rows
fixedRowsTop: 3,
formulas
Source codeoptions.formulas : object
The formulas option configures the Formulas plugin.
The Formulas plugin uses the HyperFormula (opens new window) calculation engine.
To install HyperFormula (opens new window), read the following:
You can set the formulas option to an object with the following properties:
| Property | Possible values |
|---|---|
engine | HyperFormula |A HyperFormula (opens new window) instance | A HyperFormula configuration (opens new window) object |
sheetId | A number |
sheetName | A string |
Read more:
- Plugins:
Formulas - Formula calculation
- HyperFormula documentation: Client-side installation (opens new window)
- HyperFormula documentation: Configuration options (opens new window)
Default: undefined
Category: Formulas
Example
// either add the `HyperFormula` class
formulas: {
// set `engine` to `HyperFormula`
engine: HyperFormula,
sheetId: 1,
sheetName: 'Sheet 1'
}
// or, add a HyperFormula instance
// initialized with the `'internal-use-in-handsontable'` license key
const hyperformulaInstance = HyperFormula.buildEmpty({
licenseKey: 'internal-use-in-handsontable',
});
formulas: {
// set `engine` to a HyperFormula instance
engine: hyperformulaInstance,
sheetId: 1,
sheetName: 'Sheet 1'
}
// or, add a HyperFormula configuration object
formulas: {
// set `engine` to a HyperFormula configuration object
engine: {
hyperformula: HyperFormula // or `engine: hyperformulaInstance`
leapYear1900: false, // this option comes from HyperFormula
// add more HyperFormula configuration options
},
sheetId: 1,
sheetName: 'Sheet 1'
}
// use the same HyperFormula instance in multiple Handsontable instances
// a Handsontable instance `hot1`
formulas: {
engine: HyperFormula,
sheetId: 1,
sheetName: 'Sheet 1'
}
// a Handsontable instance `hot2`
formulas: {
engine: hot1.getPlugin('formulas').engine,
sheetId: 1,
sheetName: 'Sheet 1'
}
fragmentSelection
Source codeoptions.fragmentSelection : boolean | string
The fragmentSelection option configures text selection settings.
You can set the fragmentSelection option to one of the following:
| Setting | Description |
|---|---|
false (default) | Disable text selection |
true | Enable text selection in multiple cells at a time |
'cell' | Enable text selection in one cell at a time |
Default: false
Category: Core
Example
// enable text selection in multiple cells at a time
fragmentSelection: true,
// enable text selection in one cell a time
fragmentSelection: 'cell',
headerClassName
Source codeoptions.headerClassName : string
The headerClassName option allows adding one or more class names to the column headers' inner div element.
It can be used to align the labels in the column headers to left, center or right by setting this option to
htLeft, htCenter, or htRight respectively.
Default: undefined
Category: Core
Since: 14.5.0
Example
// Adding class names to all column headers
headerClassName: 'htRight my-class',
columns: [
{
// Adding class names to the column header of a single column
headerClassName: 'htRight my-class',
}
]
height
Source codeoptions.height : number | string | function
The height option configures the height of your grid.
You can set height option to one of the following:
| Setting | Example |
|---|---|
| A number of pixels | height: 500 |
| A string with a CSS unit (opens new window) | height: '75vw' |
| A function that returns a valid number or string | height() { return 500; } |
Read more:
Default: undefined
Category: Core
Example
// set the grid's height to 500px
height: 500,
// set the grid's height to 75vh
height: '75vh',
// set the grid's height to 500px, using a function
height() {
return 500;
},
hiddenColumns
Source codeoptions.hiddenColumns : boolean | object
The hiddenColumns option configures the HiddenColumns plugin.
You can set the hiddenColumns option to one of the following:
| Setting | Description |
|---|---|
false | Disable the HiddenColumns plugin |
true | Enable the HiddenColumns plugin with the default plugin options |
| An object | - Enable the HiddenColumns plugin- Modify the plugin options |
If you set the hiddenColumns to an object, you can set the following HiddenColumns plugin options:
| Property | Possible values | Description |
|---|---|---|
columns | An array of indexes | An array of indexes of columns that are hidden at initialization |
copyPasteEnabled | true | false | true: when copying or pasting data, take hidden columns into accountfalse: when copying or pasting data, don't take hidden columns into account |
indicators | true | false | true: display UI markers to indicate the presence of hidden columnsfalse: display UI markers |
Read more:
Default: undefined
Category: HiddenColumns
Example
// enable the `HiddenColumns` plugin
hiddenColumns: true,
// enable `HiddenColumns` plugin, and modify the plugin options
hiddenColumns: {
// set columns that are hidden by default
columns: [5, 10, 15],
// when copying or pasting data, take hidden columns into account
copyPasteEnabled: true,
// show where hidden columns are
indicators: true
}
hiddenRows
Source codeoptions.hiddenRows : boolean | object
The hiddenRows option configures the HiddenRows plugin.
You can set the hiddenRows option to one of the following:
| Setting | Description |
|---|---|
false | Disable the HiddenRows plugin |
true | Enable the HiddenRows plugin with the default plugin options |
| An object | - Enable the HiddenRows plugin- Modify the plugin options |
If you set the hiddenRows to an object, you can set the following HiddenRows plugin options:
| Property | Possible values | Description |
|---|---|---|
rows | An array of indexes | An array of indexes of rows that are hidden at initialization |
copyPasteEnabled | true | false | true: when copying or pasting data, take hidden rows into accountfalse: when copying or pasting data, don't take hidden rows into account |
indicators | true | false | true: display UI markers to indicate the presence of hidden rowsfalse: display UI markers |
Read more:
Default: undefined
Category: HiddenRows
Example
// enable the `HiddenRows` plugin
hiddenRows: true,
// enable `HiddenRows` plugin, and modify the plugin options
hiddenRows: {
// set rows that are hidden by default
rows: [5, 10, 15],
// when copying or pasting data, take hidden rows into account
copyPasteEnabled: true,
// show where hidden rows are
indicators: true
}
imeFastEdit
Source codeoptions.imeFastEdit : boolean
The imeFastEdit option allows using the "fast edit" feature for the IME users. It's disabled by default
because of its incompatibility with some of the accessibility features.
Enabling this option can make a negative impact on how some screen readers handle reading the table cells.
Category: Core
Since: 14.0.0
initialState
Source codeoptions.initialState : object | undefined
The initialState option configures the grid's initial state.
This object accepts any grid configuration option. In case of conflicts between
initialState and table settings, the table settings take precedence.
Note: The initialState option is ignored when passed to the
updateSettings() method.
Default: undefined
Category: Core
Since: 16.1.0
Example
initialState: {
// configure initial column order
manualColumnMove: [1, 0],
},
injectCoreCss
Source codeoptions.injectCoreCss : boolean
The injectCoreCss option controls whether Handsontable injects its core CSS into the document.
You can set the injectCoreCss option to one of the following:
| Setting | Description |
|---|---|
true (default) | Inject core styles into the document head |
false | Do not inject core styles (use when you load CSS yourself, e.g. import 'handsontable/styles/handsontable.css') |
Read more:
Default: true
Category: Core
Since: 17.0.0
Example
// inject core CSS (default)
injectCoreCss: true,
// skip injection when you load Handsontable CSS yourself
injectCoreCss: false,
invalidCellClassName
Source codeoptions.invalidCellClassName : string
The invalidCellClassName option lets you add a CSS class name to cells
that were marked as invalid by the cell validator.
Read more:
- Cell validator
currentRowClassNamecurrentHeaderClassNameactiveHeaderClassNamecurrentColClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: "htInvalid"
Category: Core
Example
// add a `highlight-error` CSS class name
// to every `invalid` cell`
invalidCellClassName: 'highlight-error',
label
Source codeoptions.label : object
The label option configures checkbox cells` labels.
You can set the label option to an object with the following properties:
| Property | Possible values | Description |
|---|---|---|
position | 'after' (default) | 'before' | 'after': place the label to the right of the checkbox'before': place the label to the left of the checkbox |
value | A string | A function | The label's text |
separated | false (default) | true | false: don't separate the label from the checkboxtrue: separate the label from the checkbox |
property | A string | - A data object property name that's used as the label's text - Works only when the data option is set to an array of objects |
Read more:
Default: undefined
Category: Core
Example
columns: [{
type: 'checkbox',
// add 'My label:' after the checkbox
label: { position: 'before', value: 'My label: ', separated: true }
}],
language
Source codeoptions.language : string
The language option configures Handsontable's language settings.
You can set the language option to one of the following:
| Setting | Description |
|---|---|
'en-US' (default) | English - United States |
'ar-AR' | Arabic - Global To properly render this language, set the layout direction to RTL. |
'cs-CZ' | Czech - Czech Republic |
'de-CH' | German - Switzerland |
'de-DE' | German - Germany |
'es-MX' | Spanish - Mexico |
'fa-IR' | Persian - Iran |
'fr-FR' | French - France |
'hr-HR' | Croatian - Croatia |
'it-IT' | Italian - Italy |
'ja-JP' | Japanese - Japan |
'ko-KR' | Korean - Korea |
'lv-LV' | Latvian - Latvia |
'nb-NO' | Norwegian (Bokmål) - Norway |
'nl-NL' | Dutch - Netherlands |
'pl-PL' | Polish - Poland |
'pt-BR' | Portuguese - Brazil |
'ru-RU' | Russian - Russia |
'sr-SP' | Serbian (Latin) - Serbia |
'zh-CN' | Chinese - China |
'zh-TW' | Chinese - Taiwan |
Read more:
Default: "en-US"
Category: Core
Example
// set Handsontable's language to Polish
language: 'pl-PL',
layoutDirection
Source codeoptions.layoutDirection : string
The layoutDirection option configures whether Handsontable renders from the left to the right, or from the right to the left.
You can set the layout direction only at Handsontable's initialization. Any change of the layoutDirection option after the initialization (e.g. using the updateSettings() method) is ignored.
You can set the layoutDirection option only for the entire grid.
You can't set it for individual columns, rows, or cells.
You can set the layoutDirection option to one of the following strings:
| Setting | Description |
|---|---|
inherit (default) | Set Handsontable's layout direction automatically, based on the value of your HTML document's dir (opens new window) attribute |
rtl | Render Handsontable from the right to the left, even when your HTML document's dir (opens new window) attribute is set to ltr |
ltr | Render Handsontable from the left to the right, even when your HTML document's dir (opens new window) attribute is set to rtl |
Read more:
Default: "inherit"
Category: Core
Example
// inherit Handsontable's layout direction
// from the value of your HTML document's `dir` attribute
layoutDirection: 'inherit',
// render Handsontable from the right to the left
// regardless of your HTML document's `dir`
layoutDirection: 'rtl',
// render Handsontable from the left to the right
// regardless of your HTML document's `dir`
layoutDirection: 'ltr',
licenseKey
Source codeoptions.licenseKey : string
The licenseKey option sets your Handsontable license key.
You can set the licenseKey option to one of the following:
| Setting | Description |
|---|---|
| A string with your commercial license key | For commercial use |
'non-commercial-and-evaluation' | For non-commercial use |
Read more:
Default: undefined
Category: Core
Example
// for commercial use
licenseKey: 'xxxxx-xxxxx-xxxxx-xxxxx-xxxxx', // your commercial license key
// for non-commercial use
licenseKey: 'non-commercial-and-evaluation',
loading
Source codeoptions.loading : boolean | object
The loading option configures the Loading plugin.
Loading plugin, automatically loads Dialog plugin.
You can set the loading option to one of the following:
| Setting | Description |
|---|---|
false | Disable the Loading plugin |
true | Enable the Loading plugin with default configuration |
| An object | - Enable the Loading plugin- Apply custom configuration |
If you set the loading option to an object, you can configure the following loading options:
| Option | Possible settings | Description |
|---|---|---|
icon | A string | Custom loading icon to display (default: <svg />) |
title | A string | Custom loading title to display (default: 'Loading...') |
description | A string | Custom loading description to display (default: '') |
Read more:
Default: false
Category: Loading
Since: 16.1.0
Example
// enable the `Loading` plugin with default configuration
loading: true,
// enable the `Loading` plugin with custom configuration
loading: {
icon: 'A custom loading icon in SVG format',
title: 'Custom loading title',
description: 'Custom loading description',
}
locale
Source codeoptions.locale : string
The locale option configures Handsontable's locale settings.
You can set the locale option to any valid and canonicalized Unicode BCP 47 locale tag,
both for the entire grid,
and for individual columns.
Read more:
Default: "en-US"
Category: Core
Example
// set the entire grid's locale to Polish
locale: 'pl-PL',
// set individual columns' locales
columns: [
{
// set the first column's locale to Polish
locale: 'pl-PL',
},
{
// set the second column's locale to German
locale: 'de-DE',
},
],
manualColumnFreeze
Source codeoptions.manualColumnFreeze : boolean
The manualColumnFreeze option configures the ManualColumnFreeze plugin.
You can set the manualColumnFreeze option to one of the following:
| Setting | Description |
|---|---|
true | Enable the ManualColumnFreeze plugin |
false | Disable the ManualColumnFreeze plugin |
Read more:
Default: undefined
Category: ManualColumnFreeze
Example
// enable the `ManualColumnFreeze` plugin
manualColumnFreeze: true,
manualColumnMove
Source codeoptions.manualColumnMove : boolean | Array<number>
The manualColumnMove option configures the ManualColumnMove plugin.
You can set the manualColumnMove option to one of the following:
| Setting | Description |
|---|---|
true | Enable the ManualColumnMove plugin |
false | Disable the ManualColumnMove plugin |
| An array | - Enable the ManualColumnMove plugin- Move individual columns at initialization |
Read more:
Default: undefined
Category: ManualColumnMove
Example
// enable the `ManualColumnMove` plugin
manualColumnMove: true,
// enable the `ManualColumnMove` plugin
// at initialization, move column 0 to 1
// at initialization, move column 1 to 4
// at initialization, move column 2 to 6
manualColumnMove: [1, 4, 6],
manualColumnResize
Source codeoptions.manualColumnResize : boolean | Array<number>
The manualColumnResize option configures the ManualColumnResize plugin.
You can set the manualColumnResize option to one of the following:
| Setting | Description |
|---|---|
true | Enable the ManualColumnResize plugin |
false | Disable the ManualColumnResize plugin |
| An array | - Enable the ManualColumnResize plugin- Set initial widths of individual columns |
Read more:
Default: undefined
Category: ManualColumnResize
Example
// enable the `manualColumnResize` plugin
manualColumnResize: true,
// enable the `manualColumnResize` plugin
// set the initial width of column 0 to 40 pixels
// set the initial width of column 1 to 50 pixels
// set the initial width of column 2 to 60 pixels
manualColumnResize: [40, 50, 60],
manualRowMove
Source codeoptions.manualRowMove : boolean | Array<number>
The manualRowMove option configures the ManualRowMove plugin.
You can set the manualRowMove option to one of the following:
| Setting | Description |
|---|---|
true | Enable the ManualRowMove plugin |
false | Disable the ManualRowMove plugin |
| An array | - Enable the ManualRowMove plugin- Move individual rows at initialization |
Read more:
Default: undefined
Category: ManualRowMove
Example
// enable the `ManualRowMove` plugin
manualRowMove: true,
// enable the `ManualRowMove` plugin
// at initialization, move row 1 to 0
// at initialization, move row 4 to 1
// at initialization, move row 6 to 2
manualRowMove: [1, 4, 6],
manualRowResize
Source codeoptions.manualRowResize : boolean | Array<number>
The manualRowResize option configures the ManualRowResize plugin.
You can set the manualRowResize option to one of the following:
| Setting | Description |
|---|---|
true | Enable the ManualRowResize plugin |
false | Disable the ManualRowResize plugin |
| An array | - Enable the ManualRowResize plugin- Set initial heights of individual rows |
Read more:
Default: undefined
Category: ManualRowResize
Example
// enable the `ManualRowResize` plugin
manualRowResize: true,
// enable the `ManualRowResize` plugin
// set the initial height of row 0 to 40 pixels
// set the initial height of row 1 to 50 pixels
// set the initial height of row 2 to 60 pixels
manualRowResize: [40, 50, 60],
maxCols
Source codeoptions.maxCols : number
The maxCols option sets a maximum number of columns.
The maxCols option is used:
- At initialization: if the
maxColsvalue is lower than the initial number of columns, Handsontable trims columns from the right. - At runtime: for example, when inserting columns.
Default: Infinity
Category: Core
Example
// set the maximum number of columns to 300
maxCols: 300,
maxRows
Source codeoptions.maxRows : number
The maxRows option sets a maximum number of rows.
The maxRows option is used:
- At initialization: if the
maxRowsvalue is lower than the initial number of rows, Handsontable trims rows from the bottom. - At runtime: for example, when inserting rows.
Default: Infinity
Category: Core
Example
// set the maximum number of rows to 300
maxRows: 300,
maxSelections
Source codeoptions.maxSelections : number
The maxSelections option sets a maximum number of selections for the multiSelect-typed cells.
Default: undefined
Category: Core
Since: 17.0.0
Example
columns: [{
// set the `type` of each cell in this column to `multiSelect`
type: 'multiSelect',
// set the maximum number of selections to 3
maxSelections: 3,
}],
mergeCells
Source codeoptions.mergeCells : boolean | Array<object>
The mergeCells option configures the MergeCells plugin.
You can set the mergeCells option to one of the following:
| Setting | Description |
|---|---|
true | Enable the MergeCells plugin |
false | Disable the MergeCells plugin |
| An array of objects | - Enable the MergeCells plugin- Merge specific cells at initialization |
| { virtualized: true } | Enable the MergeCells plugin with enabled virtualization mode |
To merge specific cells at Handsontable's initialization,
set the mergeCells option to an array of objects, with the following properties:
| Property | Description |
|---|---|
row | The row index of the merged section's beginning |
col | The column index of the merged section's beginning |
rowspan | The width (as a number of rows) of the merged section |
colspan | The height (as a number of columns ) of the merged section |
Read more:
Default: false
Category: MergeCells
Example
// enable the `MergeCells` plugin
mergeCells: true,
// enable the `MergeCells` plugin
// and merge specific cells at initialization
mergeCells: [
// merge cells from cell (1,1) to cell (3,3)
{row: 1, col: 1, rowspan: 3, colspan: 3},
// merge cells from cell (3,4) to cell (2,2)
{row: 3, col: 4, rowspan: 2, colspan: 2},
// merge cells from cell (5,6) to cell (3,3)
{row: 5, col: 6, rowspan: 3, colspan: 3}
],
// enable the `MergeCells` plugin with enabled virtualization mode
// and merge specific cells at initialization
mergeCells: {
virtualized: true,
cells: [
// merge cells from cell (1,1) to cell (3,3)
{row: 1, col: 1, rowspan: 3, colspan: 3},
// merge cells from cell (3,4) to cell (2,2)
{row: 3, col: 4, rowspan: 2, colspan: 2},
// merge cells from cell (5,6) to cell (3,3)
{row: 5, col: 6, rowspan: 3, colspan: 3}
],
},
minCols
Source codeoptions.minCols : number
The minCols option sets a minimum number of columns.
The minCols option is used:
- At initialization: if the
minColsvalue is higher than the initial number of columns, Handsontable adds empty columns to the right. - At runtime: for example, when removing columns.
The minCols option works only when your data is an array of arrays.
When your data is an array of objects,
you can only have as many columns as defined in:
- The first data row
- The
dataSchemaoption - The
columnsoption
Default: 0
Category: Core
Example
// set the minimum number of columns to 10
minCols: 10,
minRowHeights
Source codeoptions.minRowHeights : number | Array<number> | string | Array<string> | Array<undefined> | function
Alias for the rowHeights option.
See the rowHeights option description for more information.
Default: undefined
Category: Core
Since: 16.2.0
Example
// set every row's minimum height to 100px
minRowHeights: 100,
// set every row's minimum height to 100px
minRowHeights: '100px',
// set the first (by visual index) row's minimum height to 100
// set the second (by visual index) row's minimum height to 120
// set any other row's minimum height to the default height value
minRowHeights: [100, 120],
// set each row's minimum height individually, using a function
minRowHeights(visualRowIndex) {
return visualRowIndex * 10;
},
minRows
Source codeoptions.minRows : number
The minRows option sets a minimum number of rows.
The minRows option is used:
- At initialization: if the
minRowsvalue is higher than the initial number of rows, Handsontable adds empty rows at the bottom. - At runtime: for example, when removing rows.
Default: 0
Category: Core
Example
// set the minimum number of rows to 10
minRows: 10,
minSpareCols
Source codeoptions.minSpareCols : number
The minSpareCols option sets a minimum number of empty columns
at the grid's right-hand end.
If there already are other empty columns at the grid's right-hand end,
they are counted into the minSpareCols value.
The total number of columns can't exceed the maxCols value.
The minSpareCols option works only when your data is an array of arrays.
When your data is an array of objects,
you can only have as many columns as defined in:
- The first data row
- The
dataSchemaoption - The
columnsoption
Default: 0
Category: Core
Example
// at Handsontable's initialization, add at least 3 empty columns on the right
minSpareCols: 3,
minSpareRows
Source codeoptions.minSpareRows : number
The minSpareRows option sets a minimum number of empty rows
at the bottom of the grid.
If there already are other empty rows at the bottom,
they are counted into the minSpareRows value.
The total number of rows can't exceed the maxRows value.
Default: 0
Category: Core
Example
// at Handsontable's initialization, add at least 3 empty rows at the bottom
minSpareRows: 3,
multiColumnSorting
Source codeoptions.multiColumnSorting : boolean | object
The multiColumnSorting option configures the MultiColumnSorting plugin.
You can set the multiColumnSorting option to one of the following:
| Setting | Description |
|---|---|
true | Enable the MultiColumnSorting plugin with the default configuration |
false | Disable the MultiColumnSorting plugin |
| An object | - Enable the MultiColumnSorting plugin- Modify the MultiColumnSorting plugin options |
If you set the multiColumnSorting option to an object,
you can set the following MultiColumnSorting plugin options:
| Option | Possible settings |
|---|---|
indicator | true: Display the arrow icon in the column header, to indicate a sortable columnfalse: Don't display the arrow icon in the column header |
headerAction | true: Enable clicking on the column header to sort the columnfalse: Disable clicking on the column header to sort the column |
sortEmptyCells | true: Sort empty cells as wellfalse: Place empty cells at the end |
compareFunctionFactory | A custom compare function |
If you set the multiColumnSorting option to an object,
you can also sort individual columns at Handsontable's initialization.
In the multiColumnSorting object, add an object named initialConfig,
with the following properties:
| Option | Possible settings | Description |
|---|---|---|
column | A number | The index of the column that you want to sort at initialization |
sortOrder | 'asc' | 'desc' | The sorting order:'asc': ascending'desc': descending |
Read more:
Default: undefined
Category: MultiColumnSorting
Example
// enable the `MultiColumnSorting` plugin
multiColumnSorting: true
// enable the `MultiColumnSorting` plugin with custom configuration
multiColumnSorting: {
// sort empty cells as well
sortEmptyCells: true,
// display the arrow icon in the column header
indicator: true,
// disable clicking on the column header to sort the column
headerAction: false,
// add a custom compare function
compareFunctionFactory(sortOrder, columnMeta) {
return function(value, nextValue) {
// some value comparisons which will return -1, 0 or 1...
}
}
}
// enable the `MultiColumnSorting` plugin
multiColumnSorting: {
// at initialization, sort column 1 in ascending order
initialConfig: {
column: 1,
sortOrder: 'asc'
},
// at initialization, sort column 2 in descending order
initialConfig: {
column: 2,
sortOrder: 'desc'
}
}
navigableHeaders
Source codeoptions.navigableHeaders : boolean
When set to true, the navigableHeaders option lets you navigate row headers and column headers, using the arrow keys or the Tab key (if the tabNavigation option is set to true).
Default: false
Category: Core
Since: 14.0.0
Example
// you can navigate row and column headers with the keyboard
navigableHeaders: true,
// default behavior: you can't navigate row and column headers with the keyboard
navigableHeaders: false,
nestedHeaders
Source codeoptions.nestedHeaders : boolean | Array<Array>
The nestedHeaders option configures the NestedHeaders plugin.
You can set the nestedHeaders option to one of the following:
| Setting | Description |
|---|---|
false (default) | Disable the NestedHeaders plugin |
true | - Enable the NestedHeaders plugin- Don't configure any nested headers |
| Array of arrays | - Enable the NestedHeaders plugin- Configure headers that are nested on Handsontable's initialization |
If you set the nestedHeaders option to an array of arrays, each array configures one set of nested headers.
Each array element configures one header, and can be one of the following:
| Array element | Description |
|---|---|
| A string | The header's label |
| An object | Properties:label (string): the header's labelcolspan (integer): the column width |
Read more:
Default: undefined
Category: NestedHeaders
Example
nestedHeaders: [
['A', {label: 'B', colspan: 8}, 'C'],
['D', {label: 'E', colspan: 4}, {label: 'F', colspan: 4}, 'G'],
['H', 'I', 'J', 'K', 'L', 'M', 'N', 'R', 'S', 'T']
],
nestedRows
Source codeoptions.nestedRows : boolean
The nestedRows option configures the NestedRows plugin.
You can set the nestedRows option to one of the following:
| Setting | Description |
|---|---|
false (default) | Disable the NestedRows plugin |
true | Enable the NestedRows plugin |
Read more:
Default: false
Category: NestedRows
Example
// enable the `NestedRows` plugin
nestedRows: true,
noWordWrapClassName
Source codeoptions.noWordWrapClassName : string
The noWordWrapClassName option lets you add a CSS class name
to each cell that has the wordWrap option set to false.
Read more:
wordWrapcurrentRowClassNamecurrentColClassNamecurrentHeaderClassNameinvalidCellClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: "htNoWrap"
Category: Core
Example
// add an `is-noWrapCell` CSS class name
// to each cell that doesn't wrap content
noWordWrapClassName: 'is-noWrapCell',
numericFormat
Source codeoptions.numericFormat : object
Configures the number format for numeric
cells, including currency, units, precision, and other display options.
WARNING
The numericFormat.pattern and numericFormat.culture options are deprecated and will be
removed in the next major release. Pass Intl.NumberFormat options directly to numericFormat
and use the locale cell property instead of culture.
Since v17.0.0, this option accepts all properties of the
Intl.NumberFormatOptions (opens new window)
object. The locale is controlled separately via the locale option.
Style options:
| Property | Possible values | Description |
|---|---|---|
style | 'decimal' (default), 'currency', 'percent', 'unit' | The formatting style to use |
currency | ISO 4217 currency codes (e.g., 'USD', 'EUR', 'PLN') | Required when style is 'currency' |
currencyDisplay | 'symbol' (default), 'narrowSymbol', 'code', 'name' | How to display the currency |
currencySign | 'standard' (default), 'accounting' | Use parentheses for negative values in accounting format |
unit | Unit identifiers (e.g., 'kilometer', 'liter') | Required when style is 'unit' |
unitDisplay | 'short' (default), 'narrow', 'long' | How to display the unit |
Notation options:
| Property | Possible values | Description |
|---|---|---|
notation | 'standard' (default), 'scientific', 'engineering', 'compact' | The formatting notation |
compactDisplay | 'short' (default), 'long' | Display style for compact notation (e.g., 1.5M vs 1.5 million) |
Sign and grouping options:
| Property | Possible values | Description |
|---|---|---|
signDisplay | 'auto' (default), 'never', 'always', 'exceptZero', 'negative' | When to display the sign |
useGrouping | true, false (default), 'always', 'auto', 'min2' | Whether to use grouping separators (e.g., 1,000) |
Digit options:
| Property | Possible values | Description |
|---|---|---|
minimumIntegerDigits | 1 to 21 | Minimum number of integer digits (pads with zeros) |
minimumFractionDigits | 0 to 100 | Minimum number of fraction digits |
maximumFractionDigits | 0 to 100 | Maximum number of fraction digits |
minimumSignificantDigits | 1 to 21 | Minimum number of significant digits |
maximumSignificantDigits | 1 to 21 | Maximum number of significant digits |
Rounding options:
| Property | Possible values | Description |
|---|---|---|
roundingMode | 'halfExpand' (default), 'ceil', 'floor', 'expand', 'trunc', 'halfCeil', 'halfFloor', 'halfTrunc', 'halfEven' | Rounding algorithm |
roundingPriority | 'auto' (default), 'morePrecision', 'lessPrecision' | Priority between fraction and significant digits |
roundingIncrement | 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 | Increment for rounding (e.g., nickel rounding) |
trailingZeroDisplay | 'auto' (default), 'stripIfInteger' | Whether to strip trailing zeros for integers |
Locale options:
| Property | Possible values | Description |
|---|---|---|
localeMatcher | 'best fit' (default), 'lookup' | Locale matching algorithm |
numberingSystem | 'latn', 'arab', 'hans', 'deva', 'thai', etc. | Numbering system to use |
For complete reference, see MDN: Intl.NumberFormat (opens new window).
This option affects only the displayed output in the cell renderer. It has no effect on the numeric cell editor. In the source data, numeric values are stored as JavaScript numbers.
Read more:
Deprecated options:
The pattern and culture properties (numbro.js-based formatting) are deprecated and will be
removed in the next major release. Migrate to the Intl.NumberFormat API shown above.
| Deprecated property | Possible values | Replacement |
|---|---|---|
pattern | All numbro.js number formats (opens new window) | Use Intl.NumberFormat options (see tables above) |
culture | All numbro.js currency formats (opens new window) | Use the locale option |
Migration example:
// Before (deprecated)
numericFormat: {
pattern: '0,0.00 $',
culture: 'en-US'
}
// After (recommended)
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2
}
Default: undefined
Category: Core
Since: 0.35.0
Example
columns: [
{
type: 'numeric',
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
}
}
],
observeDOMVisibility
Source codeoptions.observeDOMVisibility : boolean
If the observeDOMVisibility option is set to true,
Handsontable rerenders every time it detects that the grid was made visible in the DOM.
Default: true
Category: Core
Example
// don't rerender the grid on visibility changes
observeDOMVisibility: false,
outsideClickDeselects
Source codeoptions.outsideClickDeselects : boolean | function
The outsideClickDeselects option determines what happens to the current selection
when you click outside of the grid.
You can set the outsideClickDeselects option to one of the following:
| Setting | Description |
|---|---|
true (default) | On a mouse click outside of the grid, clear the current selection |
false | On a mouse click outside of the grid, keep the current selection |
| A function | A function that takes the click event target and returns a boolean |
Default: true
Category: Core
Example
// on a mouse click outside of the grid, clear the current selection
outsideClickDeselects: true,
// on a mouse click outside of the grid, keep the current selection
outsideClickDeselects: false,
// take the click event target and return `false`
outsideClickDeselects(event) {
return false;
}
// take the click event target and return `true`
outsideClickDeselects(event) {
return false;
}
pagination
Source codeoptions.pagination : boolean
The pagination option configures the Pagination plugin.
You can set the pagination option to one of the following:
| Setting | Description |
|---|---|
false | Disable the Pagination plugin |
true | Enable the Pagination plugin |
pagination: Additional options
If you set the pagination option to an object, you can set the following Pagination plugin options:
| Option | Possible settings | Description |
|---|---|---|
pageSize | A number or auto (default: 10) | Sets the number of rows displayed per page. If 'auto' is set, the page size will be calculated to match all rows to the currently set table's viewport height |
pageSizeList | An array (default: ['auto', 5, 10, 20, 50, 100]) | Defines the selectable values for page size in the UI |
initialPage | A number (default: 1) | Specifies which page to display on initial load |
showPageSize | Boolean (default: true) | Controls visibility of the "page size" section |
showCounter | Boolean (default: true) | Controls visibility of the "page counter" section (e.g., "1 - 10 of 50"); |
showNavigation | Boolean (default: true) | Controls visibility of the "page navigation" section |
uiContainer | An HTML element (default: null) | The container element where the pagination UI will be installed. If not provided, the pagination container will be injected below the root table element. |
Read more:
Default: undefined
Category: Pagination
Since: 16.1.0
Example
// enable the `Pagination` plugin
pagination: true,
parsePastedValue
Source codeoptions.parsePastedValue : boolean
The parsePastedValue option determines how pasted content is written to cells when the user pastes
from the clipboard into Handsontable (e.g. from another Handsontable instance or between cells in the same table).
It does not affect how other applications read or process the clipboard.
When set to false, pasted content is written as plain strings. Non-scalar values (e.g. objects) are coerced
to string, so an object becomes "[object Object]".
When set to true, pasted text is parsed so that JSON-like (or other supported) values are converted to
JavaScript values and written to the data source. This allows copying and pasting more sophisticated JavaScript
structures (e.g. objects, arrays) between cells and between Handsontable instances. Cells then store the resulting
object (e.g. { id: 1, value: 'A1' }). Schema validation is relaxed so object-based values can be pasted into
cells that would normally expect a scalar.
You can set the parsePastedValue option to one of the following:
| Setting | Description |
|---|---|
false (default) | Write pasted content as plain strings |
true | Parse pasted text and write JavaScript values |
Default: false
Category: CopyPaste
Since: 17.0.0
Example
// write pasted content as strings (objects become "[object Object]")
parsePastedValue: false,
Example
// parse pasted text so cells receive JavaScript objects when pasted content is object-like
parsePastedValue: true,
placeholder
Source codeoptions.placeholder : string
The placeholder option lets you display placeholder text in every empty cell.
You can set the placeholder option to one of the following:
| Setting | Example | Description |
|---|---|---|
| A non-empty string | 'Empty cell' | Display Empty cell text in empty cells |
| A non-string value | 000 | Display 000 text in empty cells (non-string values get stringified) |
Read more:
Default: undefined
Category: Core
Example
// display 'Empty cell' text
// in every empty cell of the entire grid
placeholder: 'Empty cell',
// or
columns: [
{
data: 'date',
dateFormat: 'DD/MM/YYYY',
// display 'Empty date cell' text
// in every empty cell of the `date` column
placeholder: 'Empty date cell'
}
],
placeholderCellClassName
Source codeoptions.placeholderCellClassName : string
The placeholderCellClassName option lets you add a CSS class name to cells
that contain placeholder text.
Read more:
- Cell validator
placeholdercurrentRowClassNamecurrentHeaderClassNameactiveHeaderClassNamecurrentColClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: "htPlaceholder"
Category: Core
Example
// add a `has-placeholder` CSS class name
// to each cell that contains `placeholder` text
placeholderCellClassName: 'has-placeholder',
preventOverflow
Source codeoptions.preventOverflow : string | boolean
The preventOverflow option configures preventing Handsontable
from overflowing outside of its parent element.
You can set the preventOverflow option to one of the following:
| Setting | Description |
|---|---|
false (default) | Don't prevent overflowing |
'horizontal' | Prevent horizontal overflowing |
'vertical' | Prevent vertical overflowing |
Default: false
Category: Core
Example
// prevent horizontal overflowing
preventOverflow: 'horizontal',
readOnly
Source codeoptions.readOnly : boolean
The readOnly option determines whether a cell,
comment, column
or the entire grid is editable or not. You can configure it as follows:
| Setting | Description |
|---|---|
false (default) | Set as editable |
true | - Set as read-only - Add the readOnlyCellClassName CSS class name (by default: htDimmed) |
readOnly cells can't be changed by the populateFromArray() method.
Read more:
Default: false
Category: Core
Example
// make the entire grid read-only
const configurationOptions = {
columnSorting: true,
};
// make the third column read-only
const configurationOptions = {
columns: [
{},
{},
{
readOnly: true,
},
],
};
// make a specific cell read-only
const configurationOptions = {
cell: [
{
row: 0,
col: 0,
readOnly: true,
},
};
readOnlyCellClassName
Source codeoptions.readOnlyCellClassName : string
The readOnlyCellClassName option lets you add a CSS class name to read-only cells.
Read more:
currentRowClassNamecurrentColClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamecommentedCellClassNamenoWordWrapClassNamereadOnlyCellClassNameTableClassName
Default: "htDimmed"
Category: Core
Example
// add a `is-readOnly` CSS class name
// to every read-only cell
readOnlyCellClassName: 'is-readOnly',
renderAllColumns
Source codeoptions.renderAllColumns : boolean
The renderAllColumns option configures Handsontable's column virtualization.
You can set the renderAllColumns option to one of the following:
| Setting | Description |
|---|---|
false (default) | Enable column virtualization, rendering only visible columns for better performance with many columns. |
true | Disable column virtualization (render all columns of the grid), rendering all columns in the dataset, and ensuring all columns are available regardless of horizontal scrolling. |
Setting renderAllColumns to true overwrites the viewportColumnRenderingOffset setting.
Read more:
Default: false
Category: Core
Since: 14.1.0
Example
// disable column virtualization
renderAllColumns: true,
renderAllRows
Source codeoptions.renderAllRows : boolean
The renderAllRows option controls Handsontable's row virtualization.
You can configure it as follows:
| Setting | Description |
|---|---|
false (default) | Enable row virtualization, rendering only the visible rows for optimal performance with large datasets. |
true | Disable row virtualization (render all rows of the grid), rendering all rows in the dataset for consistent rendering and screen reader accessibility. |
Setting renderAllRows to true overwrites the viewportRowRenderingOffset setting.
Read more:
Default: false
Category: Core
Example
// disable row virtualization
renderAllRows: true,
renderer
Source codeoptions.renderer : string | function
The renderer option sets a cell renderer for a cell.
You can set the renderer option to one of the following:
- A custom renderer function
- One of the following cell renderer aliases:
| Alias | Cell renderer function |
|---|---|
| A custom alias | Your custom cell renderer function |
'autocomplete' | AutocompleteRenderer |
'base' | BaseRenderer |
'checkbox' | CheckboxRenderer |
'date' | DateRenderer |
'intl-date' | IntlDateRenderer |
'dropdown' | DropdownRenderer |
'html' | HtmlRenderer |
'numeric' | NumericRenderer |
'password' | PasswordRenderer |
'text' | TextRenderer |
'time' | TimeRenderer |
'intl-time' | IntlTimeRenderer |
To set the renderer, editor, and validator
options all at once, use the type option.
Read more:
Default: undefined
Category: Core
Example
// use the `numeric` renderer for each cell of the entire grid
renderer: `'numeric'`,
// add a custom renderer function
renderer(hotInstance, td, row, column, prop, value, cellProperties) {
// your custom renderer's logic
...
}
// apply the `renderer` option to individual columns
columns: [
{
// use the `autocomplete` renderer for each cell of this column
renderer: 'autocomplete'
},
{
// use the `myCustomRenderer` renderer for each cell of this column
renderer: 'myCustomRenderer'
}
]
rowHeaders
Source codeoptions.rowHeaders : boolean | Array<string> | function
The rowHeaders option configures your grid's row headers.
You can set the rowHeaders option to one of the following:
| Setting | Description |
|---|---|
true | Enable the default row headers ('1', '2', '3', ...) |
false | Disable row headers |
| An array | Define your own row headers (e.g. ['One', 'Two', 'Three', ...]) |
| A function | Define your own row headers, using a function |
Read more:
Default: undefined
Category: Core
Example
// enable the default row headers
rowHeaders: true,
// set your own row headers
rowHeaders: ['One', 'Two', 'Three'],
// set your own row headers, using a function
rowHeaders: function(visualRowIndex) {
return `${visualRowIndex}: AB`;
},
rowHeaderWidth
Source codeoptions.rowHeaderWidth : number | Array<number>
The rowHeaderWidth option configures the width of row headers.
You can set the rowHeaderWidth option to one of the following:
| Setting | Description |
|---|---|
| A number | Set the same width for every row header |
| An array | Set different widths for individual row headers |
Default: undefined
Category: Core
Example
// set the same width for every row header
rowHeaderWidth: 25,
// set different widths for individual row headers
rowHeaderWidth: [25, 30, 55],
rowHeights
Source codeoptions.rowHeights : number | Array<number> | string | Array<string> | Array<undefined> | function
The rowHeights option sets rows' heights, in pixels.
In the rendering process, the default row height is classic: 26px, main: 29px, horizon: 37px or whatever is defined in the used theme (based on the line height, vertical padding and cell borders).
You can change it to equal or greater than the default value, by setting the rowHeights option to one of the following:
| Setting | Description | Example |
|---|---|---|
| A number | Set the same height for every row | rowHeights: 100 |
| A string | Set the same height for every row | rowHeights: '100px' |
| An array | Set heights separately for each row | rowHeights: [100, 120, undefined] |
| A function | Set row heights dynamically, on each render | rowHeights(visualRowIndex) { return visualRowIndex * 10; } |
undefined | Used by the modifyRowHeight hook, to detect row height changes | rowHeights: undefined |
The rowHeights option also sets the minimum row height that can be set
via the ManualRowResize and AutoRowSize plugins (if they are enabled).
Read more:
Default: undefined
Category: Core
Example
// set every row's height to 100px
rowHeights: 100,
// set every row's height to 100px
rowHeights: '100px',
// set the first (by visual index) row's height to 100
// set the second (by visual index) row's height to 120
// set the third (by visual index) row's height to `undefined`
// set any other row's height to the default height value
rowHeights: [100, 120, undefined],
// set each row's height individually, using a function
rowHeights(visualRowIndex) {
return visualRowIndex * 10;
},
sanitizer
Source codeoptions.sanitizer : function
The sanitizer option configures the function used to sanitize HTML before it is written to the DOM.
Whenever Handsontable sets HTML (e.g. cell content, headers, context menu labels, dialog content,
paste from clipboard), it can pass the string through this function first. Sanitization is important
when content comes from users or external sources to prevent XSS (e.g. script injection, event handlers).
If no sanitizer is set, HTML is applied as-is. Set a sanitizer when you need to allow rich content
while stripping or neutralizing dangerous markup.
The function receives the raw HTML string and an optional second argument (source) indicating where
the content is used (e.g. 'innerHTML', 'CopyPaste.paste'), so you can apply different rules per source.
It must return a string that is safe to assign to innerHTML.
This option is only respected when set in the table settings. It does not work when defined per column
or per cell (e.g. in columns or cell meta).
Default: undefined
Category: Core
Since: 17.0.0
Example
// Allowlist-based sanitization based on the DOMPurify library
import DOMPurify from 'dompurify';
sanitizer: (content, source) {
if (source === 'CopyPaste.paste') {
return DOMPurify.sanitize(content, {
ADD_TAGS: ['meta'],
ADD_ATTR: ['content'],
FORCE_BODY: true,
});
}
return DOMPurify.sanitize(content);
},
Example
// Maximum safety: strip all tags and escape output (no rich HTML)
sanitizer: (content, source) => {
const tpl = document.createElement('template');
tpl.innerHTML = content;
const text = tpl.content.textContent ?? '';
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
},
Example
// Trusted Types: wrap sanitization in a policy so the sink accepts the result.
// Add the policy name to the CSP trusted-types directive (e.g. trusted-types default handsontable).
const policy = window.trustedTypes?.createPolicy('handsontable', {
createHTML: (input) => DOMPurify.sanitize(input),
});
sanitizer: (content, source) =>
policy ? policy.createHTML(content) : DOMPurify.sanitize(content),
search
Source codeoptions.search : boolean | object
The search option configures the Search plugin.
You can set the search option to one of the following:
| Setting | Description |
|---|---|
false (default) | Disable the Search plugin |
true | Enable the Search plugin with the default configuration |
| An object | - Enable the Search plugin- Apply your custom configuration |
If you set the search option to an object, you can configure the following search options:
| Option | Possible settings | Description |
|---|---|---|
searchResultClass | A string | Add a custom CSS class name to search results |
queryMethod | A function | Add a custom query method |
callback | A function | Add a custom callback function |
Read more:
Default: false
Category: Search
Example
// enable the `Search` plugin with the default configuration
search: true,
// enable the `Search` plugin with a custom configuration
search: {
// add a `customClass` CSS class name to search results
searchResultClass: 'customClass',
// add a custom query method
queryMethod(queryStr, value) {
...
},
// add a custom callback function
callback(instance, row, column, value, result) {
...
}
}
searchInput
Source codeoptions.searchInput : boolean
The searchInput option configures whether the multiSelect editor's search input is visible.
Default: true
Category: Core
Since: 17.0.0
Example
columns: [{
type: 'multiSelect',
// hide the `multiSelect` editor's search input
searchInput: false,
}],
selectionMode
Source codeoptions.selectionMode : string
The selectionMode option configures how selection works.
You can set the selectionMode option to one of the following:
| Setting | Description |
|---|---|
'single' | Allow the user to select only one cell at a time. |
'range' | Allow the user to select one range of cells at a time. |
'multiple' | Allow the user to select multiple ranges of cells at a time. |
Read more:
Default: "multiple"
Category: Core
Example
// you can only select one cell at at a time
selectionMode: 'single',
// you can select one range of cells at a time
selectionMode: 'range',
// you can select multiple ranges of cells at a time
selectionMode: 'multiple',
selectOptions
Source codeoptions.selectOptions : Array<string> | object | function
The selectOptions option configures options that the end user can choose from in select cells.
You can set the selectOptions option to one of the following:
| Setting | Description |
|---|---|
| An array of strings | Each string is one option's value and label |
| An object with key-string pairs | - Each key is one option's value - The key's string is that option's label |
| A function | A function that returns an object with key-string pairs |
Read more:
Default: undefined
Category: Core
Example
columns: [
{
// set the `type` of each cell in this column to `select`
type: 'select',
// set the first option's value and label to `A`
// set the second option's value and label to `B`
// set the third option's value and label to `C`
selectOptions: ['A', 'B', 'C'],
},
{
// set the `type` of each cell in this column to `select`
type: 'select',
selectOptions: {
// set the first option's value to `value1` and label to `Label 1`
value1: 'Label 1',
// set the second option's value to `value2` and label to `Label 2`
value2: 'Label 2',
// set the third option's value to `value3` and label to `Label 3`
value3: 'Label 3',
},
},
{
// set the `type` of each cell in this column to `select`
type: 'select',
// set `selectOption` to a function that returns available options as an object
selectOptions(visualRow, visualColumn, prop) {
return {
value1: 'Label 1',
value2: 'Label 2',
value3: 'Label 3',
};
},
],
skipColumnOnPaste
Source codeoptions.skipColumnOnPaste : boolean
The skipColumnOnPaste option determines whether you can paste data into a given column.
You can only apply the skipColumnOnPaste option to an entire column, using the columns option.
You can set the skipColumnOnPaste option to one of the following:
| Setting | Description |
|---|---|
false (default) | Enable pasting data into this column |
true | - Disable pasting data into this column - On pasting, paste data into the next column to the right |
Read more:
Default: false
Category: Core
Example
columns: [
{
// disable pasting data into this column
skipColumnOnPaste: true
}
],
skipRowOnPaste
Source codeoptions.skipRowOnPaste : boolean
The skipRowOnPaste option determines whether you can paste data into a given row.
You can only apply the skipRowOnPaste option to an entire row, using the cells option.
You can set the skipRowOnPaste option to one of the following:
| Setting | Description |
|---|---|
false (default) | Enable pasting data into this row |
true | - Disable pasting data into this row - On pasting, paste data into the row below |
Read more:
Default: false
Category: Core
Example
cells(row, column) {
const cellProperties = {};
// disable pasting data into row 1
if (row === 1) {
cellProperties.skipRowOnPaste = true;
}
return cellProperties;
}
sortByRelevance
Source codeoptions.sortByRelevance : boolean
The sortByRelevance option configures whether autocomplete cells'
lists are sorted in the same order as provided in the source option.
You can set the sortByRelevance option to one of the following:
| Setting | Description |
|---|---|
true (default) | Sort options in the same order as provided in the source option |
false | Sort options alphabetically |
Read more:
Default: true
Category: Core
Example
columns: [{
// set the `type` of each cell in this column to `autocomplete`
type: 'autocomplete',
// set options available in every `autocomplete` cell of this column
source: ['D', 'C', 'B', 'A'],
// sort the `autocomplete` option in this order: D, C, B, A
sortByRelevance: true
}],
source
Source codeoptions.source : Array | function
The source option sets options available in autocomplete
and dropdown cells.
You can set the source option to one of the following:
- An array of string values
- An array of objects with
keyandvalueproperties - A function
Note: When defining the source option as an array of objects with key and value properties, the data format for that cell
needs to be an object with key and value properties as well.
Read more:
Default: undefined
Category: Core
Example
// set `source` to an array of string values
columns: [{
// set the `type` of each cell in this column to `autocomplete`
type: 'autocomplete',
// set options available in every `autocomplete` cell of this column
source: ['A', 'B', 'C', 'D']
}],
// set `source` to an array of objects with `key` and `value` properties
columns: [{
// set the `type` of each cell in this column to `autocomplete`
type: 'autocomplete',
// set options available in every `autocomplete` cell of this column
source: [{
key: 'A',
value: 'Label A'
}, {
key: 'B',
value: 'Label B'
}]
}],
// set `source` to a function
columns: [{
// set the `type` of each cell in this column to `autocomplete`
type: 'autocomplete',
// for every `autocomplete` cell in this column, fetch data from an external source
source(query, callback) {
fetch('https://example.com/query?q=' + query, function(response) {
callback(response.items);
})
}
}],
sourceDataValidator
Source codeoptions.sourceDataValidator : function
The sourceDataValidator option sets a function that validates values
when they are written to the source data layer. Validation runs on table initialization and when calling
loadData, updateData, or
setSourceDataAtCell. It does not run for the setData* family of methods.
Return true from the function to mark the value as valid, or false to mark it invalid. When a value is
invalid and allowInvalid is false, it is replaced with null in the
source (on initialization and when calling loadData or updateData). When allowInvalid is true, invalid
values are kept; a warning is still logged when the validator returns false. An exception:
setSourceDataAtCell - when the validator returns false, the write is
skipped and the cell is not nullified; the previous value in the source remains unchanged. Use
allowEmpty to treat null, undefined, or '' as valid when appropriate.
Optionally set sourceDataWarningMessage to customize the
message logged for invalid values.
Default: undefined
Category: Core
Since: 17.0.0
Example
sourceDataWarningMessage: 'The source data is invalid.',
sourceDataValidator: (value, cellMeta) => {
if (cellMeta.allowEmpty && value == null) {
return true;
}
if (typeof value === 'string') {
return true;
}
return false;
}
sourceDataWarningMessage
Source codeoptions.sourceDataWarningMessage : string
The sourceDataWarningMessage option sets the message used when
a value fails sourceDataValidator. When not set, no message is logged.
Default: undefined
Category: Core
Since: 17.0.0
Example
sourceDataWarningMessage: 'The source data is invalid.',
sourceSortFunction
Source codeoptions.sourceSortFunction : function
The sourceSortFunction option sets a function to sort the options available in multiSelect-typed cells.
Default: undefined
Category: Core
Since: 17.0.0
Example
columns: [{
// set the `type` of each cell in this column to `multiSelect`
type: 'multiSelect',
// set options available in every `multiSelect` cell of this column
source: ['A', 'B', 'C', 'D'],
// sort the `multiSelect` options in this order: D, C, B, A
sourceSortFunction: (entries) => {
return entries.sort((a, b) => b.localeCompare(a));
}
}],
startCols
Source codeoptions.startCols : number
If the data option is not set, the startCols option sets the initial number of empty columns.
The startCols option works only in Handsontable's constructor.
Default: 5
Category: Core
Example
// start with 15 empty columns
startCols: 15,
startRows
Source codeoptions.startRows : number
If the data option is not set, the startRows option sets the initial number of empty rows.
The startRows option works only in Handsontable's constructor.
Default: 5
Category: Core
Example
// start with 15 empty rows
startRows: 15,
stretchH
Source codeoptions.stretchH : string
The stretchH option determines what happens when the declared grid width
is different from the calculated sum of all column widths.
You can set the stretchH option to one of the following:
| Setting | Description |
|---|---|
'none' (default) | Don't fit the grid to the container (disable column stretching) |
'last' | Fit the grid to the container, by stretching only the last column |
'all' | Fit the grid to the container, by stretching all columns evenly |
Read more:
Default: "none"
Category: Core
Example
// fit the grid to the container
// by stretching all columns evenly
stretchH: 'all',
strict
Source codeoptions.strict : boolean
The strict option configures the behavior of autocomplete cells.
You can set the strict option to one of the following:
| Setting | Mode | Description |
|---|---|---|
true | Strict mode | The end user: - Can only choose one of suggested values - Can't enter a custom value |
false | Flexible mode | The end user: - Can choose one of suggested values - Can enter a custom value |
Read more:
Default: undefined
Category: Core
Example
columns: [
{
// set the `type` of each cell in this column to `autocomplete`
type: 'autocomplete',
// set options available in every `autocomplete` cell of this column
source: ['A', 'B', 'C'],
// values entered must match `A`, `B`, or `C`
strict: true
},
],
tableClassName
Source codeoptions.tableClassName : string | Array<string>
The tableClassName option lets you add CSS class names
to every Handsontable instance inside the container element.
You can set the tableClassName option to one of the following:
| Setting | Description |
|---|---|
| A string | Add a single CSS class name to every Handsontable instance inside the container element |
| An array of strings | Add multiple CSS class names to every Handsontable instance inside the container element |
Read more:
currentRowClassNamecurrentColClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamereadOnlyCellClassNamenoWordWrapClassNamecommentedCellClassNameclassName
Default: undefined
Category: Core
Example
// add a `your-class-name` CSS class name
// to every Handsontable instance inside the `container` element
tableClassName: 'your-class-name',
// add `first-class-name` and `second-class-name` CSS class names
// to every Handsontable instance inside the `container` element
tableClassName: ['first-class-name', 'second-class-name'],
tabMoves
Source codeoptions.tabMoves : object | function
The tabMoves option configures the action of the Tab key.
You can set the tabMoves option to an object with the following properties
(or to a function that returns such an object):
| Property | Type | Description |
|---|---|---|
row | Number | - On pressing Tab, move selection row rows down- On pressing Shift+Tab, move selection row rows up |
col | Number | - On pressing Tab, move selection col columns right- On pressing Shift+Tab, move selection col columns left |
Default: {row: 0, col: 1}
Category: Core
Example
// on pressing Tab, move selection 2 rows down and 2 columns right
// on pressing Shift+Tab, move selection 2 rows up and 2 columns left
tabMoves: {row: 2, col: 2},
// the same setting, as a function
// `event` is a DOM Event object received on pressing Tab
// you can use it to check whether the user pressed Tab or Shift+Tab
tabMoves(event) {
return {row: 2, col: 2};
},
tabNavigation
Source codeoptions.tabNavigation : boolean
When set to false, the tabNavigation option changes the behavior of the
Tab and Shift+Tab keyboard shortcuts. The Handsontable
no more captures that shortcuts to make the grid navigation available (tabNavigation: true)
but returns control to the browser so the native page navigation is possible.
Default: true
Category: Core
Since: 14.0.0
Example
// you can't navigate row and column headers using <kbd>Tab</kbd> or <kbd>Shift</kbd>+<kbd>Tab</kbd> keyboard shortcuts
tabNavigation: false,
// default behavior: you can navigate row and column headers using <kbd>Tab</kbd> or <kbd>Shift</kbd>+<kbd>Tab</kbd> keyboard shortcuts
tabNavigation: true,
textEllipsis
Source codeoptions.textEllipsis : boolean
The textEllipsis option configures whether the text content in the cells should be truncated with an ellipsis (three dots).
You can set the textEllipsis option to one of the following:
| Setting | Description |
|---|---|
false (default) | Don't truncate text content with an ellipsis |
true | Truncate text content with an ellipsis |
Default: false
Category: Core
Since: 16.0.0
Example
columns: [
{
// truncate text content with an ellipsis
textEllipsis: true,
},
{
// don't truncate text content with an ellipsis
textEllipsis: false,
}
],
theme
Source codeoptions.theme : ThemeBuilder | string | undefined
The theme option configures the visual theme for your Handsontable instance.
You can set the theme option to one of the following:
| Setting | Description |
|---|---|
undefined (default) | Don't apply any theme and use the default main theme |
A string (e.g., 'ht-theme-horizon') | Apply a registered theme by name (required to import CSS file) |
| A plain theme config object | Apply a theme with default settings (import and pass the config, e.g. horizonTheme) |
A ThemeBuilder object | Apply a theme with runtime configuration (recommended) |
When using a ThemeBuilder object, you can configure the theme at runtime using these methods:
| Method | Description |
|---|---|
setColorScheme(mode) | Sets the color scheme: 'light', 'dark', or 'auto' (default: 'auto') |
setDensityType(type) | Sets the row density: 'compact', 'default', or 'comfortable' (default: 'default') |
params(paramsObject) | Sets custom theme parameters e.g. icons, colors, tokens |
Read more:
Default: undefined
Category: Core
Since: 17.0.0
Example
// Enable a theme by class name (requires loading the theme CSS)
theme: 'ht-theme-horizon',
Example
// Pass a plain theme config object
import { horizonTheme } from 'handsontable/themes';
const hot = new Handsontable(container, {
theme: horizonTheme,
});
Example
// Pass a ThemeBuilder object (for customization before initialization)
import { horizonTheme, registerTheme } from 'handsontable/themes';
const theme = registerTheme(horizonTheme)
.setColorScheme('dark')
.setDensityType('compact')
.params({
tokens: {
fontSize: '14px',
iconSize: 'size_5',
borderColor: ['colors.palette.100', 'colors.palette.800'],
},
});
const hot = new Handsontable(container, {
theme,
});
themeName
Source codeoptions.themeName : string | undefined
The themeName option allows enabling a theme by that name.
Read more:
Default: undefined
Category: Core
Since: 15.0.0
Example
themeName: 'ht-theme-name',
timeFormat
Source codeoptions.timeFormat : string | object
Configures the time format for time cells. Accepts either a string (legacy, for time
cells) or an object of Intl.DateTimeFormat (opens new window)
options (for intl-time cells).
WARNING
The string form of timeFormat is deprecated and will be removed in the next major release.
It is used only by the time cell type. Use the intl-time cell type with an Intl.DateTimeFormat
options object instead.
Object form (Intl.DateTimeFormat options):
The object form is supported only when the cell type is intl-time. The locale is controlled separately
via the locale option.
Source data format
For intl-time cells, source data must be in 24-hour time format (HH:mm, HH:mm:ss, or HH:mm:ss.SSS), matching
the HTML input type="time" value. Otherwise operations such as sorting and filtering can be unstable or unpredictable.
The timeFormat object affects only how times are displayed; the underlying value should remain in that format.
Style shortcuts:
| Property | Possible values | Description |
|---|---|---|
timeStyle | 'full', 'long', 'medium', 'short' | Time formatting style (expands to hour, minute, second, timeZoneName) |
Time component options:
| Property | Possible values | Description |
|---|---|---|
hour | 'numeric', '2-digit' | Representation of the hour |
minute | 'numeric', '2-digit' | Representation of the minute |
second | 'numeric', '2-digit' | Representation of the second |
fractionalSecondDigits | 1, 2, 3 | Fraction-of-second digits |
dayPeriod | 'narrow', 'short', 'long' | Day period (e.g. "am", "noon") |
timeZoneName | 'long', 'short', 'shortOffset', 'longOffset', 'shortGeneric', 'longGeneric' | Time zone display |
Locale and other options:
| Property | Possible values | Description |
|---|---|---|
localeMatcher | 'best fit' (default), 'lookup' | Locale matching algorithm |
timeZone | IANA time zone (e.g. 'UTC', 'America/New_York') | Time zone for formatting |
hour12 | true, false | Use 12-hour vs 24-hour time |
hourCycle | 'h11', 'h12', 'h23', 'h24' | Hour cycle |
formatMatcher | 'basic', 'best fit' (default) | Format matching algorithm |
For complete reference, see MDN: Intl.DateTimeFormat (opens new window).
Read more:
Deprecated: string form
Passing a string (e.g. 'h:mm:ss a') is deprecated and works only with the time cell type.
Migrate to the intl-time cell type and pass an Intl.DateTimeFormat options object.
Migration example:
// Before (deprecated)
columns: [{
type: 'time',
timeFormat: 'h:mm:ss a'
}]
// After (recommended)
columns: [{
type: 'intl-time',
locale: 'en-US',
timeFormat: {
hour: 'numeric',
minute: '2-digit',
second: '2-digit',
hour12: true
}
}]
Default: "h:mm:ss a"
Category: Core
Example
// intl-time cell type with Intl options
columns: [
{
type: 'intl-time',
locale: 'en-US',
timeFormat: {
timeStyle: 'medium'
}
}
]
Example
// Legacy: time cell type with string format (deprecated)
columns: [
{
type: 'time',
timeFormat: 'h:mm:ss a'
}
]
title
Source codeoptions.title : string
The title option configures column header names.
You can set the title option to a string.
Read more:
Default: undefined
Category: Core
Example
columns: [
{
// set the first column header name to `First name`
title: 'First name',
type: 'text',
},
{
// set the second column header name to `Last name`
title: 'Last name',
type: 'text',
}
],
trimDropdown
Source codeoptions.trimDropdown : boolean
The trimDropdown option configures the width of the autocomplete
and dropdown lists.
You can set the trimDropdown option to one of the following:
| Setting | Description |
|---|---|
true (default) | Make the dropdown/autocomplete list's width the same as the edited cell's width |
false | Scale the dropdown/autocomplete list's width to the list's content |
Read more:
Default: true
Category: Core
Example
columns: [
{
type: 'autocomplete',
// for each cell of this column
// make the `autocomplete` list's width the same as the edited cell's width
trimDropdown: true,
},
{
type: 'dropdown',
// for each cell of this column
// scale the `dropdown` list's width to the list's content
trimDropdown: false,
}
],
trimRows
Source codeoptions.trimRows : boolean | Array<number>
The trimRows option configures the TrimRows plugin.
You can set the trimRows option to one of the following:
| Setting | Description |
|---|---|
false | Disable the TrimRows plugin |
true | Enable the TrimRows plugin |
| An array of physical row indexes | - Enable the TrimRows plugin- Trim selected rows at initialization |
Read more:
Default: undefined
Category: TrimRows
Example
// enable the `TrimRows` plugin
trimRows: true,
// enable the `TrimRows` plugin
// at Handsontable's initialization, trim rows 5, 10, and 15
trimRows: [5, 10, 15],
trimWhitespace
Source codeoptions.trimWhitespace : boolean
The trimWhitespace option configures automatic whitespace removal. This option
affects the cell renderer and the cell editor.
You can set the trimWhitespace option to one of the following:
| Setting | Description |
|---|---|
true (default) | Remove whitespace at the beginning and at the end of each cell |
false | Don't remove whitespace |
Default: true
Category: Core
Example
columns: [
{
// don't remove whitespace
// from any cell of this column
trimWhitespace: false
}
]
type
Source codeoptions.type : string
The type option lets you set the renderer, editor, and validator
options all at once, by selecting a cell type.
You can set the type option to one of the following:
| Cell type | Renderer, editor & validator |
|---|---|
| A custom cell type | Renderer: your custom cell renderer Editor: your custom cell editor Validator: your custom cell validator |
'autocomplete' | Renderer: AutocompleteRendererEditor: AutocompleteEditorValidator: AutocompleteValidator |
'checkbox' | Renderer: CheckboxRendererEditor: CheckboxEditorValidator: - |
'date' | Renderer: DateRendererEditor: DateEditorValidator: DateValidator |
'intl-date' | Renderer: IntlDateRendererEditor: IntlDateEditorValidator: IntlDateValidator |
'dropdown' | Renderer: DropdownRendererEditor: DropdownEditorValidator: DropdownValidator |
'handsontable' | Renderer: AutocompleteRendererEditor: HandsontableEditorValidator: - |
'numeric' | Renderer: NumericRendererEditor: NumericEditorValidator: NumericValidator |
'password' | Renderer: PasswordRendererEditor: PasswordEditorValidator: - |
'text' | Renderer: TextRendererEditor: TextEditorValidator: - |
'time' | Renderer: TimeRendererEditor: TimeEditorValidator: TimeValidator |
'intl-time' | Renderer: IntlTimeRendererEditor: IntlTimeEditorValidator: IntlTimeValidator |
Read more:
- Cell type
- Cell renderer
- Cell editor
- Cell validator
- Configuration options: Cascading configuration
renderereditorvalidatorvalueParservalueFormatter
Default: "text"
Category: Core
Example
// set the `numeric` cell type for each cell of the entire grid
type: `'numeric'`,
// apply the `type` option to individual columns
columns: [
{
// set the `autocomplete` cell type for each cell of this column
type: 'autocomplete'
},
{
// set the `myCustomCellType` cell type for each cell of this column
type: 'myCustomCellType'
}
]
uncheckedTemplate
Source codeoptions.uncheckedTemplate : boolean | string | number
The uncheckedTemplate option lets you configure what value
an unchecked checkbox cell has.
You can set the uncheckedTemplate option to one of the following:
| Setting | Description |
|---|---|
false (default) | If a checkbox cell is unchecked,the getDataAtCell method for this cell returns false |
| A string | If a checkbox cell is unchecked,the getDataAtCell method for this cell returns a string of your choice |
Read more:
Default: false
Category: Core
Example
columns: [
{
// set the `type` of each cell in this column to `checkbox`
// when unchecked, the cell's value is `false`
// when checked, the cell's value is `true`
type: 'checkbox',
},
{
// set the `type` of each cell in this column to `checkbox`
// when unchecked, the cell's value is `'No'`
// when checked, the cell's value is `'Yes'`
type: 'checkbox',
uncheckedTemplate: 'No'
checkedTemplate: 'Yes',
}
],
undo
Source codeoptions.undo : boolean
The undo option configures the UndoRedo plugin.
You can set the undo option to one of the following:
By default, the undo option is set to true,
To disable the UndoRedo plugin completely,
set the undo option to false.
Read more:
Default: undefined
Category: UndoRedo
Example
// enable the `UndoRedo` plugin
undo: true,
validator
Source codeoptions.validator : function | RegExp | string
The validator option sets a cell validator for a cell.
You can set the validator option to one of the following:
| Setting | Description |
|---|---|
| A string | A cell validator alias |
| A function | Your custom cell validator function |
| A regular expression | A regular expression used for cell validation |
By setting the validator option to a string,
you can use one of the following cell validator aliases:
| Alias | Cell validator function |
|---|---|
| A custom alias | Your custom cell validator |
'autocomplete' | AutocompleteValidator |
'date' | DateValidator |
'intl-date' | IntlDateValidator |
'dropdown' | DropdownValidator |
'numeric' | NumericValidator |
'time' | TimeValidator |
'intl-time' | IntlTimeValidator |
To set the editor, renderer, and validator
options all at once, use the type option.
Read more:
Default: undefined
Category: Core
Example
columns: [
{
// use a built-in `numeric` cell validator
validator: 'numeric'
},
{
// validate against a regular expression
validator: /^[0-9]$/
},
{
// add a custom cell validator function
validator(value, callback) {
...
}
},
],
valueFormatter
Source codeoptions.valueFormatter : function
The valueFormatter option sets a custom function for formatting cell values before display.
Unlike the renderer option, which is responsible for the complete cell rendering process
(DOM structure, performance-optimized content insertion via innerText/innerHTML, a11y attributes, applying
styles from className, readOnlyCellClassName, textEllipsis, and other options), the valueFormatter
focuses solely on transforming the cell's value.
The valueFormatter function is called by the rendering engine right before the actual renderer function is
called. Separating the value formatting from the renderer logic allows for more flexibility and reuse.
This simplifies common formatting use cases where you only need to transform
the displayed value (e.g., adding units, formatting dates, or applying custom text transformations).
When to use valueFormatter vs renderer:
| Use case | Recommended option |
|---|---|
| Transform displayed value (add prefix, units) | valueFormatter |
| Custom date/number/text formatting | valueFormatter |
| Modify DOM structure (add icons, custom elements) | renderer |
The function receives the raw value and cell properties, and should return the formatted value to be displayed. The formatting can be applied to a single cell, column, or the entire grid.
Function signature:
valueFormatter(value, cellProperties) => formattedValue
| Parameter | Type | Description |
|---|---|---|
value | * | The raw cell value |
cellProperties | object | The cell's meta object (see Core#getCellMeta) |
| Returns | * | The formatted value to display |
Read more:
Default: undefined
Category: Core
Since: 17.0.0
Example
// add a currency symbol to numeric values
valueFormatter(value, cellProperties) {
if (value === null || value === undefined) {
return '';
}
return `$${value}`;
}
// format dates in a custom format
valueFormatter(value, cellProperties) {
if (!value) {
return '';
}
const date = new Date(value);
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
}
// apply valueFormatter to individual columns
columns: [
{
// add "kg" suffix to weight values
valueFormatter(value) {
return value ? `${value} kg` : '';
}
},
{
// format percentages
valueFormatter(value) {
return value !== null ? `${(value * 100).toFixed(1)}%` : '';
}
}
]
valueGetter
Source codeoptions.valueGetter : function
The valueGetter option configures a function that defines what value will be used when displaying the cell content.
It can be used to modify the value of a cell before it is displayed (for example, for object-based data).
Default: undefined
Category: Core
Since: 16.1.0
Example
// use the `label` property of the value object with a fallback to the value itself
valueGetter: (value, row, column, cellMeta) => {
return value?.label ?? value;
}
| Param | Type | Description |
|---|---|---|
| value | * | The value to be displayed in the cell. |
| row | number | The visual row index of the cell. |
| column | number | The visual column index of the cell. |
| cellMeta | object | The cell meta object. |
valueParser
Source codeoptions.valueParser : function
The valueParser option sets a custom function for converting editor output into the source data format.
Unlike valueFormatter, which formats values for display, valueParser runs only when a
value comes from the cell editor - after the user finishes
editing. It maps whatever the editor returns (e.g. a localized date string, a formatted number) into the
canonical shape stored in the data source (e.g. ISO date string, raw number).
When to use valueParser vs valueFormatter:
| Use case | Option |
|---|---|
| Display: raw value -> shown text | valueFormatter |
| Edit: editor value -> source data | valueParser |
Function signature:
valueParser(value, cellProperties) => sourceValue
| Parameter | Type | Description |
|---|---|---|
value | * | The value produced by the editor |
cellProperties | object | The cell's meta object (see Core#getCellMeta) |
| Returns | * | The value to store in the source data |
Read more:
- Cell editor
editorrenderervalueFormattersourceDataValidator- Configuration options: Cascading configuration
Default: undefined
Category: Core
Since: 17.0.0
Example
// parse editor string to ISO date (e.g. intl-date: display format => source format)
valueParser(value, cellProperties) {
if (value == null || value === '') {
return null;
}
const date = new Date(value);
return Number.isNaN(date.getTime()) ? value : date.toISOString().slice(0, 10);
}
// parse formatted number string to number
valueParser(value, cellProperties) {
if (value == null || value === '') {
return null;
}
const num = Number(value.replace(/[^\d.-]/g, ''));
return Number.isNaN(num) ? value : num;
}
// apply valueParser per column
columns: [
{ data: 'date', valueParser: (value) => value ? new Date(value).toISOString().slice(0, 10) : null },
{ data: 'amount', valueParser: (value) => value != null ? Number(value) : null }
]
valueSetter
Source codeoptions.valueSetter : function
The valueSetter option configures a function that defines what value will be used when setting the cell content.
It can be used to modify the value of a cell before it is saved (for example, for object-based data).
Default: undefined
Category: Core
Since: 16.1.0
Example
// Modify the value of a cell before it is saved
valueSetter: (value, row, column, cellMeta) => {
return { id: value?.id ?? value, value: `${value?.value ?? value} at ${row}, ${column}` }
},
| Param | Type | Description |
|---|---|---|
| value | * | The value to be set to a cell. |
| row | number | The visual row index of the cell. |
| column | number | The visual column index of the cell. |
| cellMeta | object | The cell meta object. |
viewportColumnRenderingOffset
Source codeoptions.viewportColumnRenderingOffset : number | 'auto'
The viewportColumnRenderingOffset option configures the number of columns
to be rendered outside of the grid's viewport.
You can set the viewportColumnRenderingOffset option to one of the following:
| Setting | Description |
|---|---|
auto (default) | Use the offset calculated automatically by Handsontable |
| A number | Set the offset manually |
The viewportColumnRenderingOffset setting is ignored when renderAllColumns is set to true.
Read more:
Default: 'auto'
Category: Core
Example
// render 70 columns outside of the grid's viewport
viewportColumnRenderingOffset: 70,
viewportColumnRenderingThreshold
Source codeoptions.viewportColumnRenderingThreshold : number | 'auto'
The viewportColumnRenderingThreshold option configures what column number starting from the left or right
(depends on the scroll direction) should trigger the rendering of columns outside of the grid's viewport.
You can set the viewportColumnRenderingThreshold option to one of the following:
| Setting | Description |
|---|---|
auto | Triggers rendering at half the offset defined by viewportColumnRenderingOffset option |
| A number | Sets the offset manually (0 is a default) |
The viewportColumnRenderingThreshold setting is ignored when renderAllColumn is set to true.
Read more:
Default: 0
Category: Core
Since: 1.14.7
Example
// render 12 columns outside of the grid's viewport
viewportColumnRenderingOffset: 12,
// the columns outside of the viewport will be rendered when the user scrolls to the 8th column from/to
viewportColumnRenderingThreshold: 8,
viewportRowRenderingOffset
Source codeoptions.viewportRowRenderingOffset : number | 'auto'
The viewportRowRenderingOffset option configures the number of rows
to be rendered outside of the grid's viewport.
You can set the viewportRowRenderingOffset option to one of the following:
| Setting | Description |
|---|---|
auto (default) | Use the offset calculated automatically by Handsontable |
| A number | Set the offset manually |
The viewportRowRenderingOffset setting is ignored when renderAllRows is set to true.
Read more:
Default: 'auto'
Category: Core
Example
// render 70 rows outside of the grid's viewport
viewportRowRenderingOffset: 70,
viewportRowRenderingThreshold
Source codeoptions.viewportRowRenderingThreshold : number | 'auto'
The viewportRowRenderingThreshold option configures what row number starting from the top or bottom
(depends on the scroll direction) should trigger the rendering of rows outside of the grid's viewport.
You can set the viewportRowRenderingThreshold option to one of the following:
| Setting | Description |
|---|---|
auto | Triggers rendering at half the offset defined by viewportRowRenderingOffset option |
| A number | Sets the offset manually (0 is a default) |
The viewportRowRenderingThreshold setting is ignored when renderAllRows is set to true.
Read more:
Default: 0
Category: Core
Since: 1.14.7
Example
// render 12 rows outside of the grid's viewport
viewportRowRenderingOffset: 12,
// the rows outside of the viewport will be rendered when the user scrolls to the 8th row from/to
viewportRowRenderingThreshold: 8,
visibleRows
Source codeoptions.visibleRows : number
The visibleRows option sets the height of the autocomplete
, dropdown and multiSelect-typed cells' lists.
When the number of list options exceeds the visibleRows number, a scrollbar appears.
Read more:
Default: 10
Category: Core
Example
columns: [
{
type: 'autocomplete',
// set the `autocomplete` list's height to 15 options
// for each cell of this column
visibleRows: 15,
},
{
type: 'dropdown',
// set the `dropdown` list's height to 5 options
// for each cell of this column
visibleRows: 5,
},
{
type: 'multiSelect',
// set the `multiSelect` list's height to 5 options
// for each cell of this column
visibleRows: 5,
}
],
width
Source codeoptions.width : number | string | function
The width option configures the width of your grid.
You can set the width option to one of the following:
| Setting | Example |
|---|---|
| A number of pixels | width: 500 |
| A string with a CSS unit (opens new window) | width: '75vw' |
| A function that returns a valid number or string | width() { return 500; } |
Read more:
Default: undefined
Category: Core
Example
// set the grid's width to 500px
width: 500,
// set the grid's width to 75vw
width: '75vw',
// set the grid's width to 500px, using a function
width() {
return 500;
},
wordWrap
Source codeoptions.wordWrap : boolean
The wordWrap option configures whether content that exceeds a column's width is wrapped or not.
You can set the wordWrap option to one of the following:
| Setting | Description |
|---|---|
true (default) | If content exceeds the column's width, wrap the content |
false | Don't wrap content |
To style cells that don't wrap content, use the noWordWrapClassName option.
Read more:
Default: true
Category: Core
Example
// set column width for every column of the entire grid
colWidths: 100,
columns: [
{
// don't wrap content in this column
wordWrap: false,
},
{
// if content exceeds this column's width, wrap the content
wordWrap: true,
}
],
Methods
isEmptyCol
Source codeoptions.isEmptyCol(col) ⇒ boolean
The isEmptyCol option lets you define your own custom method
for checking if a column at a given visual index is empty.
The isEmptyCol setting overwrites the built-in isEmptyCol method.
Category: Core
Example
// overwrite the built-in `isEmptyCol` method
isEmptyCol(visualColumnIndex) {
// your custom method
...
},
| Param | Type | Description |
|---|---|---|
| col | number | Visual column index. |
isEmptyRow
Source codeoptions.isEmptyRow(row) ⇒ boolean
The isEmptyRow option lets you define your own custom method
for checking if a row at a given visual index is empty.
The isEmptyRow setting overwrites the built-in isEmptyRow method.
Category: Core
Example
// overwrite the built-in `isEmptyRow` method
isEmptyRow(visualRowIndex) {
// your custom method
...
},
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |