Core
Description
The Handsontable class (known as the Core) lets you modify the grid’s behavior by using Handsontable’s public API methods.
How to call a method
Options
activeHeaderClassName
core.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).
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Read more:
currentRowClassNamecurrentColClassNamecurrentHeaderClassNameinvalidCellClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: “ht__active_highlight”
Since: 0.38.2
Example
// add an `ht__active_highlight` CSS class name// to every currently-active, currently-selected headeractiveHeaderClassName: 'ht__active_highlight',allowEmpty
core.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 |
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
Default: true
Example
// allow empty values in each cell of the entire gridallowEmpty: true,
// orcolumns: [ { type: 'date', dateFormat: { day: '2-digit', month: '2-digit', year: 'numeric' }, // allow empty values in each cell of the 'date' column allowEmpty: true }],
// or, using the `cells` optioncells(row, col) { if (col === 2) { return { allowEmpty: false }; }},allowHtml
core.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
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
core.allowInsertColumn : boolean
If set to true, the allowInsertColumn option adds the following menu items to the context menu:
- Insert column left
- Insert column right
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Example
// hide the 'Insert column left' and 'Insert column right' menu items from the context menuallowInsertColumn: false,allowInsertRow
core.allowInsertRow : boolean
If set to true, the allowInsertRow option adds the following menu items to the context menu:
- Insert row above
- Insert row below
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Example
// hide the 'Insert row above' and 'Insert row below' menu items from the context menuallowInsertRow: false,allowInvalid
core.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
Example
// don't accept `invalid` values// don't allow the user to close the cell editor// don't save `invalid` values into the data sourceallowInvalid: false,allowRemoveColumn
core.allowRemoveColumn : boolean
If set to true, the allowRemoveColumn option adds the following menu items to the context menu:
- Remove column
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Read more:
Default: true
Example
// hide the 'Remove column' menu item from the context menuallowRemoveColumn: false,allowRemoveRow
core.allowRemoveRow : boolean
If set to true, the allowRemoveRow option adds the following menu items to the context menu:
- Remove row
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Example
// hide the 'Remove row' menu item from the context menuallowRemoveRow: false,ariaTags
core.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
Since: 14.0.0
autoWrapCol
core.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. |
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: false
Example
// when you select a bottom-most cell, pressing ⬇ doesn't do anything// when you select a top-most cell, pressing ⬆ doesn't do anythingautoWrapCol: 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 columnautoWrapCol: true,autoWrapRow
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: false
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 anythingautoWrapRow: 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 belowautoWrapRow: true,cell
core.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.
Each entry’s row and col are visual indexes. This differs from the cells
option, whose row and column are physical indexes.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: []
Example
// set the `cell` option to an array of objectscell: [ // make the cell with coordinates (0, 0) read-only { row: 0, col: 0, readOnly: true }],cells
core.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. |
Inside a regular (non-arrow) cells function, this is the cell meta object. Its
this.instance property is the Handsontable instance, so you can call core API methods
such as this.instance.toVisualRow(row) or this.instance.toVisualColumn(column) (as in
the example below). Arrow functions (cells: () => {}) do not bind this, so
this.instance is not available inside them – use a regular or shorthand function instead.
Read more:
- Configuration options: Implementing custom logic
- Configuration options: Setting row options
columnscell
Default: undefined
Example
// set the `cells` option to your custom functioncells(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; } else { cellProperties.readOnly = false; }
return cellProperties;},checkedTemplate
core.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 |
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
Read more:
Default: true
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
core.className : string | Array<string>
The className option lets you add CSS class names to every cell that has this option set.
You can set the className option to one of the following:
| Setting | Description |
|---|---|
| A string | Add a single CSS class name to every matching cell |
| An array of strings | Add multiple CSS class names to every matching cell |
To apply different CSS class names on different levels, use Handsontable’s cascading configuration.
Read more:
- Configuration options: Cascading configuration
currentRowClassNamecurrentColClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamecommentedCellClassNamenoWordWrapClassNamereadOnlyCellClassNameTableClassName
Default: undefined
Example
// add a `your-class-name` CSS class name to every cellclassName: 'your-class-name',
// add `first-class-name` and `second-class-name` CSS class names to every cellclassName: ['first-class-name', 'second-class-name'],colHeaders
core.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 |
To set the header label of an individual column, use that column’s title option.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: null
Example
// enable the default column headerscolHeaders: true,
// set your own column headerscolHeaders: ['One', 'Two', 'Three'],
// set your own column headers, using a functioncolHeaders: function(visualColumnIndex) { return `${visualColumnIndex} + : AB`;},columnHeaderHeight
core.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 |
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// set the same height for every column headercolumnHeaderHeight: 25,
// set different heights for individual column headerscolumnHeaderHeight: [25, 30, 55],columns
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// set the `columns` option to an array of objects// each object represents one columncolumns: [ { // column options for the first (by physical index) column type: 'numeric', numericFormat: { style: 'currency', currency: 'USD', minimumFractionDigits: 2, maximumFractionDigits: 2 } }, { // column options for the second (by physical index) column type: 'text', readOnly: true }],
// or set the `columns` option to a function, based on physical indexescolumns(index) { return { type: index > 0 ? 'numeric' : 'text', readOnly: index < 1 }}colWidths
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// set every column's width to 100pxcolWidths: 100,
// set every column's width to 100pxcolWidths: '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 functioncolWidths(visualColumnIndex) { return visualColumnIndex * 10;},commentedCellClassName
core.commentedCellClassName : string
The commentedCellClassName option lets you add a CSS class name to cells
that have comments.
Read more:
- Comments
commentsreadOnlyCellClassNamecurrentRowClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamereadOnlyCellClassNamenoWordWrapClassNameTableClassNameclassName
Default: “htCommentCell”
Example
// add a `has-comment` CSS class name// to each cell that has a commentcommentedCellClassName: 'has-comment',copyable
core.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
Example
// enable copying for each cell of the entire gridcopyable: true,
// enable copying for individual columnscolumns: [ { // enable copying for each cell of this column copyable: true }, { // disable copying for each cell of this column copyable: false }]
// enable copying for specific cellscell: [ { col: 0, row: 0, // disable copying for cell (0, 0) copyable: false, }],currentColClassName
core.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
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// add a `your-class-name` CSS class name// to each cell of the currently-visible, currently-selected columnscurrentColClassName: 'your-class-name',currentHeaderClassName
core.currentHeaderClassName : string
The currentHeaderClassName option lets you add a CSS class name
to every currently-visible, currently-selected header.
Read more:
currentRowClassNamecurrentColClassNameactiveHeaderClassNameinvalidCellClassNamereadOnlyCellClassNamecommentedCellClassNamenoWordWrapClassNameTableClassNameclassName
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: “ht__highlight”
Example
// add an `ht__highlight` CSS class name// to every currently-visible, currently-selected headercurrentHeaderClassName: 'ht__highlight',currentRowClassName
core.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
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// add a `your-class-name` CSS class name// to each cell of the currently-visible, currently-selected rowscurrentRowClassName: 'your-class-name',data
core.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.
When used inside the columns option, data has a different meaning: it acts as a property name
(or a dot-separated path) pointing to the field in each data row object that this column reads from and writes to.
In this context, data is not the full dataset but a column accessor string.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// as an array of arraysdata: [ ['A', 'B', 'C'], ['D', 'E', 'F'], ['G', 'H', 'J']]
// as an array of objectsdata: [ {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'},]
// as a column accessor inside `columns`columns: [ { data: 'id' }, { data: 'name' }]dataDotNotation
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Since: 14.4.0
Example
// All dots are interpreted as nested object pathsdataDotNotation: 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 keysdataDotNotation: false,data: [ { id: 1, 'name.first': 'Ted', 'user.address': '1234 Any Street' },],columns={[ { data: 'name.first' }, { data: 'user.address' },]},dataProvider
core.dataProvider : object
When set, the table loads data from an async provider (e.g. a REST API) instead of a static data array.
Use the object form with every key defined: rowId, fetchRows, onRowsCreate, onRowsUpdate,
and onRowsRemove. All five are required on that object so paging, row identity, and create, update, and remove
map cleanly to your backend. Pair with pagination for server-side paging.
Valid cell edits apply at once; if onRowsUpdate fails or beforeRowsMutation blocks the update, affected cells roll back.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Since: 17.1.0
Example
dataProvider: { rowId: 'id', fetchRows: async (queryParameters, { signal }) => { const { page, pageSize, sort, filters } = queryParameters; const params = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });
if (sort) { params.set('sortBy', sort.prop); params.set('sortDir', sort.order); }
const res = await fetch(`/api/products?${params}`, { signal }); const json = await res.json();
return { rows: json.data, totalRows: json.total }; }, onRowsCreate: async ({ position, referenceRowId, rowsAmount }) => { ... }, onRowsUpdate: async (rows) => { ... }, onRowsRemove: async (rowIds) => { ... },},dataSchema
core.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
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// with `dataSchema`, you can start with an empty griddata: 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: 1dateFormat
core.dateFormat : Intl.DateTimeFormatOptions
Configures the date format for date cells using an
Intl.DateTimeFormat
options object.
The locale is controlled separately via the locale option.
Style shortcuts:
| Property | Possible values | Description |
|---|---|---|
dateStyle | 'full', 'long', 'medium', 'short' | Date formatting style (expands to weekday, day, month, year, era) |
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.
Read more:
Default: { year: ‘numeric’, month: ‘2-digit’, day: ‘2-digit’ }
Example
columns: [ { type: 'date', locale: 'en-US', dateFormat: { dateStyle: 'short' } }]defaultDate
core.defaultDate : string
The defaultDate option configures the date pre-selected in the date picker editor
when opening an empty date cell for editing.
The option accepts a string in ISO 8601 format (YYYY-MM-DD).
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
Read more:
Default: undefined
Example
columns: [ { type: 'date', defaultDate: '2015-02-02' }],disableVisualSelection
core.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' |
When set to any non-false value, the second-click deselect behavior
(Ctrl/Cmd+click on an already-selected cell removing it from a multi-cell selection)
is also skipped. Without visible feedback, toggling layers off can cause unexpected
highlight jumps.
Read more:
Default: false
Example
// don't show single-cell selection// don't show range selection// don't show header selectiondisableVisualSelection: true,
// don't show single-cell selection// show range selection// show header selectiondisableVisualSelection: 'current',
// don't show single-cell selection// don't show range selection// show header selectiondisableVisualSelection: ['current', 'area'],editor
core.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.
When the editor option is set to false, you can still use these keyboard shortcuts:
| Shortcut | Action |
|---|---|
Delete / Backspace | Clear the contents of the selected cells |
Ctrl + Enter / Cmd + Enter | Fill selected cells with the value of the active cell |
To set the editor, renderer, and validator
options all at once, use the type option.
Read more:
Default: undefined
Example
// use the `numeric` editor for each cell of the entire grideditor: 'numeric',
// apply the `editor` option to individual columnscolumns: [ { // 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 }]enterBeginsEditing
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Example
// press Enter once to start editing// press Enter twice to move to another cellenterBeginsEditing: true,
// press Enter once to move to another cellenterBeginsEditing: false,enterCommits
core.enterCommits : boolean
The enterCommits option configures whether the Enter key closes the multiSelect editor.
Default: true
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
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: {col: 0, row: 1}
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 upenterMoves: {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+EnterenterMoves(event) { return {col: 1, row: 1};},fillHandle
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Example
// enable autofill in all directions// with `autoInsertRow` enabledfillHandle: true,
// enable vertical autofill// with `autoInsertRow` enabledfillHandle: 'vertical',
// enable horizontal autofill// with `autoInsertRow` enabledfillHandle: 'horizontal',
// enable autofill in all directions// with `autoInsertRow` disabledfillHandle: { autoInsertRow: false,},
// enable vertical autofill// with `autoInsertRow` disabledfillHandle: { autoInsertRow: false, direction: 'vertical'},filter
core.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
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: ['Apple', 'Apricot', 'Avocado', 'Banana', 'Blueberry'], // when the end user types in `a`, display options that contain `a` // when the end user types in `ap`, display only `Apple` and `Apricot` filter: true}],filteringCaseSensitive
core.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
Example
columns: [ { type: 'autocomplete', source: [ ... ], // match case while searching autocomplete options filteringCaseSensitive: true }, { type: 'multiselect', source: [ ... ], // match case while searching multiSelect options filteringCaseSensitive: true }],filterSelectedItems
core.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
Example
// filter out the selected items from the dropdownfilterSelectedItems: true,
// keep the selected items in the dropdownfilterSelectedItems: false,
### fixedColumnsLeft
<button type="button" class="ask-about-api-btn" data-option="fixedColumnsLeft" data-plugin="Core" aria-label="Ask AI about fixedColumnsLeft">Ask AI</button>
<a href="https://github.com/handsontable/handsontable/blob/09631ad550b9ef3fc4a818f1e57b4c6b2f02ab2f/handsontable/handsontable/tmp/dataMap/metaManager/metaSchema.ts#L2775" target="_blank" rel="noopener noreferrer" class="source-code-link">Source code</a>
_core.fixedColumnsLeft : number_
`fixedColumnsLeft` is a legacy option.
If your grid's [layout direction](/docs/vue-data-grid/layout-direction/) is LTR (default), `fixedColumnsLeft` acts like the [`fixedColumnsStart`](/docs/vue-data-grid/api/options/#fixedcolumnsstart) option.
If your grid's [layout direction](/docs/vue-data-grid/layout-direction/) is RTL, using `fixedColumnsLeft` throws an error.
Use [`fixedColumnsStart`](/docs/vue-data-grid/api/options/#fixedcolumnsstart), which works in any layout direction.
Read more:- [`fixedColumnsStart`](/docs/vue-data-grid/api/options/#fixedcolumnsstart)
This option can only be set at the [grid level](/docs/vue-data-grid/configuration-options/#set-grid-options).It has no effect when set in the [`columns`](/docs/vue-data-grid/api/options/#columns), [`cells`](/docs/vue-data-grid/api/options/#cells), or [`cell`](/docs/vue-data-grid/api/options/#cell) options.
**Default**: <code>0</code>**Example**```js// freeze the first 3 columns from the leftfixedColumnsLeft: 3,fixedColumnsStart
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
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` attributelayoutDirection: 'inherit',fixedColumnsStart: 3,
// when `layoutDirection` is set to `rtl`// freeze the first 3 columns from the right// regardless of your HTML document's `dir` attributelayoutDirection: 'rtl',fixedColumnsStart: 3,
// when `layoutDirection` is set to `ltr`// freeze the first 3 columns from the left// regardless of your HTML document's `dir` attributelayoutDirection: 'ltr',fixedColumnsStart: 3,fixedRowsBottom
core.fixedRowsBottom : number
The fixedRowsBottom option sets the number of frozen rows
at the bottom of the grid.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
Example
// freeze the bottom 3 rowsfixedRowsBottom: 3,fixedRowsTop
core.fixedRowsTop : number
The fixedRowsTop option sets the number of frozen rows at the top of the grid.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
Example
// freeze the top 3 rowsfixedRowsTop: 3,fragmentSelection
core.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 |
With fragmentSelection: true, copying text across multiple cells requires a
selectionMode that allows selecting more than one cell.
When selectionMode is set to 'single', copying is
limited to a single cell.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: false
Example
// enable text selection in multiple cells at a timefragmentSelection: true,
// enable text selection in one cell a timefragmentSelection: 'cell',hashLength
core.hashLength : number
The hashLength option sets a fixed display length for the hash mask used by the
password cell type.
By default, the hash length equals the actual value length. Set hashLength to a positive
integer to always display that many hash symbols regardless of the real value length.
Default: undefined
Example
columns: [ { type: 'password', hashLength: 10, },],hashRevealDelay
core.hashRevealDelay : number
The hashRevealDelay option enables a brief character-reveal on each keystroke in the
password cell type editor.
When set to a positive number (milliseconds), each typed character stays visible for that
duration and is then replaced by the hashSymbol. This lets the user confirm what they
typed without permanently exposing the value. Requires type: 'password'.
Default: undefined
Since: 17.2.0
Example
columns: [ { type: 'password', hashRevealDelay: 1000, },],hashSymbol
core.hashSymbol : string
The hashSymbol option sets the character used as the hash mask in the
password cell type renderer.
Defaults to '*'. You can use any character, HTML entity, or string.
Default: ”*“
Example
columns: [ { type: 'password', hashSymbol: '•', },],headerClassName
core.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
Since: 14.5.0
Example
// Adding class names to all column headersheaderClassName: 'htRight my-class',
columns: [ { // Adding class names to the column header of a single column headerClassName: 'htRight my-class', }]height
core.height : number | ‘auto’ | string | function
The height option configures the height of your grid.
You can set the height option to one of the following:
| Setting | Example |
|---|---|
| A number of pixels | height: 500 |
| A string with a CSS unit | height: '75vw' |
'auto' | height: 'auto' |
| A function that returns a valid number or string | height() { return 500; } |
How 'auto' differs from leaving height unset
When you set height: 'auto', Handsontable writes height: auto; overflow: clip;
as inline styles on the root element. The grid then grows to match its content height.
No internal vertical scrollbar is created, so the page itself scrolls when the grid
exceeds the viewport.
When you leave height unset, Handsontable does not touch the root element’s inline
styles. Sizing is governed by your CSS, and the nearest ancestor with overflow: auto
or overflow: hidden becomes the scroll parent. If no such ancestor exists, the window
scrolls. See the Grid size guide for
details.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// set the grid's height to 500pxheight: 500,
// set the grid's height to 75vhheight: '75vh',
// let the grid grow to fit all its rows (no internal vertical scroll)height: 'auto',
// set the grid's height to 500px, using a functionheight() { return 500;},imeFastEdit
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Since: 14.0.0
initialState
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Since: 16.1.0
Example
initialState: { // configure initial column order manualColumnMove: [1, 0],},injectCoreCss
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Since: 17.0.0
Example
// inject core CSS (default)injectCoreCss: true,
// skip injection when you load Handsontable CSS yourselfinjectCoreCss: false,invalidCellClassName
core.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”
Example
// add a `highlight-error` CSS class name// to every `invalid` cell`invalidCellClassName: 'highlight-error',label
core.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
Example
columns: [{ type: 'checkbox', // add 'My label:' after the checkbox label: { position: 'before', value: 'My label: ', separated: true }}],language
core.language : string
The language option configures Handsontable’s language settings.
This option controls the language used for all built-in UI strings, including context menu labels,
column sorting labels, validation messages, and other user-visible text. It does not affect the locale
used for number or date formatting - use the locale option for that.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
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”
Example
// set Handsontable's language to Polishlanguage: 'pl-PL',layout
core.layout : object
The layout option configures the order of plugin UI elements within the user-orderable
wrapper slots rendered around the grid: top and bottom. Each slot takes an ordered array
of element keys (for example 'pagination'). Keys you list are placed first in that order;
any remaining elements follow by their default weight. The grid and the overlays layer (the
modal layer, such as the dialog) are not orderable through this option. The license
notification is not orderable either; it always renders last in the bottom slot.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Since: 18.0.0
Example
// render pagination above a custom 'summary' element registered in the bottom slotlayout: { bottom: ['pagination', 'summary'],},layoutDirection
core.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 attribute |
rtl | Render Handsontable from the right to the left, even when your HTML document’s dir attribute is set to ltr |
ltr | Render Handsontable from the left to the right, even when your HTML document’s dir attribute is set to rtl |
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: “inherit”
Example
// inherit Handsontable's layout direction// from the value of your HTML document's `dir` attributelayoutDirection: '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
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// for commercial uselicenseKey: 'xxxxx-xxxxx-xxxxx-xxxxx-xxxxx', // your commercial license key
// for non-commercial uselicenseKey: 'non-commercial-and-evaluation',locale
core.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”
Example
// set the entire grid's locale to Polishlocale: 'pl-PL',
// set individual columns' localescolumns: [ { // set the first column's locale to Polish locale: 'pl-PL', }, { // set the second column's locale to German locale: 'de-DE', },],maxCols
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: Infinity
Example
// set the maximum number of columns to 300maxCols: 300,maxRows
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: Infinity
Example
// set the maximum number of rows to 300maxRows: 300,maxSelections
core.maxSelections : number
The maxSelections option sets a maximum number of selections for the multiSelect-typed cells.
Default: undefined
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,}],minCols
core.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
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
Example
// set the minimum number of columns to 10minCols: 10,minRowHeights
core.minRowHeights : number | Array<number> | string | Array<string> | Array<undefined> | function
Alias for the rowHeights option.
See the rowHeights option description for more information.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Since: 16.2.0
Example
// set every row's minimum height to 100pxminRowHeights: 100,
// set every row's minimum height to 100pxminRowHeights: '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 valueminRowHeights: [100, 120],
// set each row's minimum height individually, using a functionminRowHeights(visualRowIndex) { return visualRowIndex * 10;},minRows
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
Example
// set the minimum number of rows to 10minRows: 10,minSpareCols
core.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
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
Example
// at Handsontable's initialization, add at least 3 empty columns on the rightminSpareCols: 3,minSpareRows
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
Example
// at Handsontable's initialization, add at least 3 empty rows at the bottomminSpareRows: 3,navigableHeaders
core.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).
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: false
Since: 14.0.0
Example
// you can navigate row and column headers with the keyboardnavigableHeaders: true,
// default behavior: you can't navigate row and column headers with the keyboardnavigableHeaders: false,noWordWrapClassName
core.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”
Example
// add an `is-noWrapCell` CSS class name// to each cell that doesn't wrap contentnoWordWrapClassName: 'is-noWrapCell',numericFormat
core.numericFormat : object
Configures the number format for numeric
cells, including currency, units, precision, and other display options.
Since v17.0.0, this option accepts all properties of the
Intl.NumberFormatOptions
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.
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:
Default: undefined
Since: 0.35.0
Example
columns: [ { type: 'numeric', locale: 'en-US', numericFormat: { style: 'currency', currency: 'USD', } }],observeDOMVisibility
core.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.
Handsontable uses a MutationObserver to watch for CSS changes (such as display: none being removed)
on the container element and its ancestors. When visibility is restored after being hidden,
Handsontable automatically triggers a rerender to ensure correct layout and dimensions.
Set this option to false if you want to control rendering manually (e.g. by calling render() yourself).
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Example
// don't rerender the grid on visibility changesobserveDOMVisibility: false,outsideClickDeselects
core.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 |
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
Example
// on a mouse click outside of the grid, clear the current selectionoutsideClickDeselects: true,
// on a mouse click outside of the grid, keep the current selectionoutsideClickDeselects: 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;}placeholder
core.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
Example
// display 'Empty cell' text// in every empty cell of the entire gridplaceholder: 'Empty cell',
// orcolumns: [ { data: 'date', dateFormat: { day: '2-digit', month: '2-digit', year: 'numeric' }, // display 'Empty date cell' text // in every empty cell of the `date` column placeholder: 'Empty date cell' }],placeholderCellClassName
core.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”
Example
// add a `has-placeholder` CSS class name// to each cell that contains `placeholder` textplaceholderCellClassName: 'has-placeholder',preventOverflow
core.preventOverflow : string | boolean
The preventOverflow option configures preventing Handsontable
from overflowing outside of its parent element.
When enabled, Handsontable caps its own dimensions to match the parent container’s size in the specified direction,
preventing the grid from extending beyond the visible bounds of its parent.
This is useful when the parent element has overflow: hidden or a fixed size and you want the grid to fit within it.
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 |
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: false
Example
// prevent horizontal overflowingpreventOverflow: 'horizontal',readOnly
core.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
Example
// make the entire grid read-onlyconst configurationOptions = { columnSorting: true,};
// make the third column read-onlyconst configurationOptions = { columns: [ {}, {}, { readOnly: true, }, ],};
// make a specific cell read-onlyconst configurationOptions = { cell: [ { row: 0, col: 0, readOnly: true, },};readOnlyCellClassName
core.readOnlyCellClassName : string
The readOnlyCellClassName option lets you add a CSS class name to read-only cells.
Read more:
currentRowClassNamecurrentColClassNamecurrentHeaderClassNameactiveHeaderClassNameinvalidCellClassNameplaceholderCellClassNamecommentedCellClassNamenoWordWrapClassNamereadOnlyCellClassNameTableClassName
Default: “htDimmed”
Example
// add a `is-readOnly` CSS class name// to every read-only cellreadOnlyCellClassName: 'is-readOnly',renderAllColumns
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: false
Since: 14.1.0
Example
// disable column virtualizationrenderAllColumns: true,renderAllRows
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: false
Example
// disable row virtualizationrenderAllRows: true,renderer
core.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
Example
// use the `numeric` renderer for each cell of the entire gridrenderer: `'numeric'`,
// add a custom renderer functionrenderer(hotInstance, td, row, column, prop, value, cellProperties) { // your custom renderer's logic ...}
// apply the `renderer` option to individual columnscolumns: [ { // 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
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// enable the default row headersrowHeaders: true,
// set your own row headersrowHeaders: ['One', 'Two', 'Three'],
// set your own row headers, using a functionrowHeaders: function(visualRowIndex) { return `${visualRowIndex}: AB`;},rowHeaderWidth
core.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 |
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// set the same width for every row headerrowHeaderWidth: 25,
// set different widths for individual row headersrowHeaderWidth: [25, 30, 55],rowHeights
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// set every row's height to 100pxrowHeights: 100,
// set every row's height to 100pxrowHeights: '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 valuerowHeights: [100, 120, undefined],
// set each row's height individually, using a functionrowHeights(visualRowIndex) { return visualRowIndex * 10;},sanitizer
core.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).
By default (when no sanitizer is set), HTML is applied as-is (pass-through). You are responsible for XSS protection. 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).
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Since: 17.0.0
Example
// Allowlist-based sanitization using a custom librarysanitizer: (content, source) => myLibrary.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) => myLibrary.sanitize(input),});
sanitizer: (content, source) => policy ? policy.createHTML(content) : myLibrary.sanitize(content),searchInput
core.searchInput : boolean
The searchInput option configures whether the multiSelect editor’s search input is visible.
Default: true
Since: 17.0.0
Example
columns: [{ type: 'multiselect', // hide the `multiSelect` editor's search input searchInput: false,}],selectionMode
core.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. |
When selectionMode is set to 'single', copying with
fragmentSelection enabled is limited to a single cell.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: “multiple”
Example
// you can only select one cell at at a timeselectionMode: 'single',
// you can select one range of cells at a timeselectionMode: 'range',
// you can select multiple ranges of cells at a timeselectionMode: 'multiple',selectOptions
core.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
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
core.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. This option is not supported for the global table level settings.
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
Example
columns: [ { // disable pasting data into this column skipColumnOnPaste: true }],skipRowOnPaste
core.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. This option is not supported for the global table level settings.
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
Example
cells(row, column) { const cellProperties = {};
// disable pasting data into row 1 if (row === 1) { cellProperties.skipRowOnPaste = true; }
return cellProperties;}sortByRelevance
core.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
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
core.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
Example
// set `source` to an array of string valuescolumns: [{ // 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` propertiescolumns: [{ // 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 functioncolumns: [{ // 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
core.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.
Limitation: source-data validation only sees a sourceDataValidator (and a validating cell
type) that you define in the global settings, the
columns option, the cell option, or with
setCellMeta(). It does not run the cells
function or the beforeGetCellMeta /
afterGetCellMeta hooks, so a validator that you add only through those
is skipped. Define the validator in one of the supported places to validate the source data.
Default: undefined
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
core.sourceDataWarningMessage : string
The sourceDataWarningMessage option sets the message used when
a value fails sourceDataValidator. When not set, no message is logged.
Default: undefined
Since: 17.0.0
Example
sourceDataWarningMessage: 'The source data is invalid.',sourceSortFunction
core.sourceSortFunction : function
The sourceSortFunction option sets a function to sort the options available in multiSelect-typed cells.
Default: undefined
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
core.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 and only when data is not provided.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 5
Example
// start with 15 empty columnsstartCols: 15,startRows
core.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 and only when data is not provided.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 5
Example
// start with 15 empty rowsstartRows: 15,stretchH
core.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:
When used with manualColumnResize, columns that have a width set
through pre-defined manual sizes are excluded from stretching. Only the remaining columns
are stretched to fill the container.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: “none”
Example
// fit the grid to the container// by stretching all columns evenlystretchH: 'all',strict
core.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 |
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
Read more:
Default: undefined
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
core.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
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Example
// add a `your-class-name` CSS class name// to every Handsontable instance inside the `container` elementtableClassName: 'your-class-name',
// add `first-class-name` and `second-class-name` CSS class names// to every Handsontable instance inside the `container` elementtableClassName: ['first-class-name', 'second-class-name'],tabMoves
core.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 |
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: {row: 0, col: 1}
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 lefttabMoves: {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+TabtabMoves(event) { return {row: 2, col: 2};},tabNavigation
core.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.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: true
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 shortcutstabNavigation: false,
// default behavior: you can navigate row and column headers using <kbd>Tab</kbd> or <kbd>Shift</kbd>+<kbd>Tab</kbd> keyboard shortcutstabNavigation: true,textEllipsis
core.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
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
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
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 objectimport { 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
core.themeName : string | undefined
The themeName option allows enabling a theme by that name.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: undefined
Since: 15.0.0
Example
themeName: 'ht-theme-name',timeFormat
core.timeFormat : object
Configures the time format for intl-time cells using an
Intl.DateTimeFormat
options object. The locale is controlled separately via the locale option.
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.
Read more:
Default: { hour: ‘2-digit’, minute: ‘2-digit’ }
Example
columns: [ { type: 'intl-time', locale: 'en-US', timeFormat: { timeStyle: 'medium' } }]title
core.title : string
The title option configures column header names.
You can set the title option to a string.
To set the labels of all column headers at once, use the colHeaders option.
Read more:
This option can only be set at the columns level.
It has no effect when set at the grid level, or in the cells or cell options.
Default: undefined
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
core.trimDropdown : boolean
The trimDropdown option configures the width of the autocomplete
and dropdown lists.
When set to true (default), the list is trimmed to match the width of the edited cell,
which can truncate long option labels. When set to false, the list expands to fit its
longest option, which may make the list wider than the cell.
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 |
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
Read more:
Default: true
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, }],trimWhitespace
core.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
Example
columns: [ { // don't remove whitespace // from any cell of this column trimWhitespace: false }]type
core.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”
Example
// set the `numeric` cell type for each cell of the entire gridtype: `'numeric'`,
// apply the `type` option to individual columnscolumns: [ { // 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
core.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 |
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
Read more:
Default: false
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', }],validator
core.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 |
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
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
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) { callback(value >= 0 && value <= 100); } },],valueFormatter
core.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
Since: 17.0.0
Example
// add a currency symbol to numeric valuesvalueFormatter(value, cellProperties) { if (value === null || value === undefined) { return ''; }
return `$${value}`;}
// format dates in a custom formatvalueFormatter(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 columnscolumns: [ { // add "kg" suffix to weight values valueFormatter(value) { return value ? `${value} kg` : ''; } }, { // format percentages valueFormatter(value) { return value !== null ? `${(value * 100).toFixed(1)}%` : ''; } }]valueGetter
core.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
Since: 16.1.0
Example
// use the `label` property of the value object with a fallback to the value itselfvalueGetter: (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
core.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
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 numbervalueParser(value, cellProperties) { if (value == null || value === '') { return null; }
const num = Number(value.replace(/[^\d.-]/g, ''));
return Number.isNaN(num) ? value : num;}
// apply valueParser per columncolumns: [ { data: 'date', valueParser: (value) => value ? new Date(value).toISOString().slice(0, 10) : null }, { data: 'amount', valueParser: (value) => value != null ? Number(value) : null }]valueSetter
core.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
Since: 16.1.0
Example
// Modify the value of a cell before it is savedvalueSetter: (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
core.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 |
With auto, the option works in a dynamic overscan mode: Handsontable renders 1 extra
column on each side of the viewport and, while you scroll horizontally, extends the
rendered area by up to 8 extra columns in the scroll direction, so consecutive scroll
steps reuse the already-rendered columns instead of re-rendering them.
The scroll-direction overscan works only when Handsontable knows every column’s width up
front and all columns share the same width: set colWidths to a single
number. Features that measure or change individual column widths turn the overscan off for
the column axis – for example, autoColumnSize (enabled by default),
manualColumnResize, or hiddenColumns. The grid
then keeps the static offset of 1 column on each side.
An explicit number switches the option to a manual mode: exactly that many extra columns render on both sides, with no scroll-direction overscan.
The viewportColumnRenderingOffset setting is ignored when renderAllColumns is set to true.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: ‘auto’
Example
// render 70 columns outside of the grid's viewportviewportColumnRenderingOffset: 70,viewportColumnRenderingThreshold
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
Since: 1.14.7
Example
// render 12 columns outside of the grid's viewportviewportColumnRenderingOffset: 12,// the columns outside of the viewport will be rendered when the user scrolls to the 8th column from/toviewportColumnRenderingThreshold: 8,viewportRowRenderingOffset
core.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 |
With auto, the option works in a dynamic overscan mode: Handsontable renders 1 extra row
on each side of the viewport and, while you scroll vertically, extends the rendered area by
up to 4 extra rows in the scroll direction, so consecutive scroll steps reuse the
already-rendered rows instead of re-rendering them.
The scroll-direction overscan works only when Handsontable knows every row’s height up
front and all rows share the same height: keep the default rowHeights or
set it to a single number. Features that measure or change individual row heights turn the
overscan off for the row axis – for example, autoRowSize,
manualRowResize, or hiddenRows. The grid then keeps
the static offset of 1 row on each side.
An explicit number switches the option to a manual mode: exactly that many extra rows render on both sides, with no scroll-direction overscan.
The viewportRowRenderingOffset setting is ignored when renderAllRows is set to true.
Read more:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: ‘auto’
Example
// render 70 rows outside of the grid's viewportviewportRowRenderingOffset: 70,viewportRowRenderingThreshold
core.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:
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Default: 0
Since: 1.14.7
Example
// render 12 rows outside of the grid's viewportviewportRowRenderingOffset: 12,// the rows outside of the viewport will be rendered when the user scrolls to the 8th row from/toviewportRowRenderingThreshold: 8,visibleRows
core.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.
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
Read more:
Default: 10
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
core.width : number | ‘auto’ | 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 | width: '75vw' |
'auto' | width: 'auto' |
| A function that returns a valid number or string | width() { return 500; } |
With width: 'auto', Handsontable writes width: auto as an inline style on the root
element. The grid then follows the width of its parent container. Use this value when
you want the grid to stay flexible horizontally while still setting an explicit
height.
Read more:
Default: undefined
Example
// set the grid's width to 500pxwidth: 500,
// set the grid's width to 75vwwidth: '75vw',
// let the grid follow its parent container's widthwidth: 'auto',
// set the grid's width to 500px, using a functionwidth() { return 500;},wordWrap
core.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.
This option can be set at any level of the cascading configuration:
the grid level, the columns level, the cells level, and the cell level.
Read more:
Default: true
Example
// set column width for every column of the entire gridcolWidths: 100,
columns: [ { // don't wrap content in this column wordWrap: false, }, { // if content exceeds this column's width, wrap the content wordWrap: true, }],Members
columnIndexMapper
core.columnIndexMapper : IndexMapper
Instance of index mapper which is responsible for managing the column indexes.
columnsSettingIndexes
Core~columnsSettingIndexes
Caches the index translation that getColHeader derives from the columns option when that
option is a function: the source column indexes for which columns(index) returns a truthy
settings object. Only the membership array is cached — titles are still read live from the
columns function. Rebuilt when the function reference or the column count changes; cleared
by updateSettings.
isDestroyed
core.isDestroyed : boolean
A boolean to tell if the Handsontable has been fully destroyed. This is set to true
after afterDestroy hook is called.
rowIndexMapper
core.rowIndexMapper : IndexMapper
Instance of index mapper which is responsible for managing the row indexes.
Methods
isEmptyCol
core.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.
The function receives a visual column index and must return a boolean.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Example
// overwrite the built-in `isEmptyCol` methodisEmptyCol(visualColumnIndex) { // your custom method ...},| Param | Type | Description |
|---|---|---|
| col | number | Visual column index. |
isEmptyRow
core.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.
The function receives a visual row index and must return a boolean.
This option can only be set at the grid level.
It has no effect when set in the columns, cells, or cell options.
Example
// overwrite the built-in `isEmptyRow` methodisEmptyRow(visualRowIndex) { // your custom method ...},| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
addHook
core.addHook(key, callback, [orderIndex])
Adds listener to the specified hook name (only for this Handsontable instance).
See: Hooks#add
Example
hot.addHook('beforeInit', myCallback);| Param | Type | Description |
|---|---|---|
| key | string | Hook name (see Hooks). |
| callback | function Array | Function or array of functions. |
| [orderIndex] | number | optional Order index of the callback. If > 0, the callback will be added after the others, for example, with an index of 1, the callback will be added before the ones with an index of 2, 3, etc., but after the ones with an index of 0 and lower. If < 0, the callback will be added before the others, for example, with an index of -1, the callback will be added after the ones with an index of -2, -3, etc., but before the ones with an index of 0 and higher. If 0 or no order index is provided, the callback will be added between the “negative” and “positive” indexes. |
addHookOnce
core.addHookOnce(key, callback, [orderIndex])
Adds listener to specified hook name (only for this Handsontable instance). After the listener is triggered, it will be automatically removed.
See: Hooks#once
Example
hot.addHookOnce('beforeInit', myCallback);| Param | Type | Description |
|---|---|---|
| key | string | Hook name (see Hooks). |
| callback | function Array | Function or array of functions. |
| [orderIndex] | number | optional Order index of the callback. If > 0, the callback will be added after the others, for example, with an index of 1, the callback will be added before the ones with an index of 2, 3, etc., but after the ones with an index of 0 and lower. If < 0, the callback will be added before the others, for example, with an index of -1, the callback will be added after the ones with an index of -2, -3, etc., but before the ones with an index of 0 and higher. If 0 or no order index is provided, the callback will be added between the “negative” and “positive” indexes. |
alter
core.alter(action, [index], [amount], [source], [keepEmptyRows])
The alter() method lets you alter the grid’s structure
by adding or removing rows and columns at specified positions.
// above row 10 (by visual index), insert 1 new rowhot.alter('insert_row_above', 10);| Action | With index | Without index |
|---|---|---|
'insert_row_above' | Inserts rows above the index row. | Inserts rows above the first row. |
'insert_row_below' | Inserts rows below the index row. | Inserts rows below the last row. |
'remove_row' | Removes rows, starting from the index row. | Removes rows, starting from the last row. |
'insert_col_start' | Inserts columns before the index column. | Inserts columns before the first column. |
'insert_col_end' | Inserts columns after the index column. | Inserts columns after the last column. |
'remove_col' | Removes columns, starting from the index column. | Removes columns, starting from the last column. |
Additional information about 'insert_col_start' and 'insert_col_end':
- Their behavior depends on your
layoutDirection. - If the provided
indexis higher than the actual number of columns, Handsontable doesn’t generate the columns missing in between. Instead, the new columns are inserted next to the last column.
Example
// above row 10 (by visual index), insert 1 new rowhot.alter('insert_row_above', 10);
// below row 10 (by visual index), insert 3 new rowshot.alter('insert_row_below', 10, 3);
// in the LTR layout direction: to the left of column 10 (by visual index), insert 3 new columns// in the RTL layout direction: to the right of column 10 (by visual index), insert 3 new columnshot.alter('insert_col_start', 10, 3);
// in the LTR layout direction: to the right of column 10 (by visual index), insert 1 new column// in the RTL layout direction: to the left of column 10 (by visual index), insert 1 new columnhot.alter('insert_col_end', 10);
// remove 2 rows, starting from row 10 (by visual index)hot.alter('remove_row', 10, 2);
// remove 2 columns, starting from column 3 (by visual index)hot.alter('remove_col', 3, 2);
// remove 3 rows, starting from row 1 (by visual index)// remove 2 rows, starting from row 5 (by visual index)hot.alter('remove_row', [[1, 3], [5, 2]]);
// pass a custom source string to hookshot.addHook('afterCreateRow', (index, amount, source) => { if (source === 'inventory-import') { // Run logic only for rows created by the inventory import. }});hot.alter('insert_row_above', 0, 1, 'inventory-import');
// remove a row without immediately adding empty rows required by `minRows` or `minSpareRows`hot.alter('remove_row', 4, 1, 'inventory-cleanup', true);| Param | Type | Description |
|---|---|---|
| action | string | Available operations:
|
| [index] | number Array<number> | optional A visual index of the row/column before or after which the new row/column will be inserted or removed. Can also be an array of arrays, in format [[index, amount],...]. |
| [amount] | number | optional The amount of rows or columns to be inserted or removed (default: 1). |
| [source] | string | optional Source indicator passed to related hooks. |
| [keepEmptyRows] | boolean | optional If set to true, skips the automatic adjustment that normally adds empty rows or columns after the operation to satisfy minRows, minSpareRows, minCols, or minSpareCols. |
batch
core.batch(wrappedOperations) ⇒ *
It batches the rendering process and index recalculations. The method aggregates multi-line API calls into a callback and postpones the table rendering process as well aggregates the table logic changes such as index changes into one call after which the cache is updated. After the execution of the operations, the table is rendered, and the cache is updated once. As a result, it improves the performance of wrapped operations.
Since: 8.3.0
Example
hot.batch(() => { hot.alter('insert_row_above', 5, 45); hot.alter('insert_col_start', 10, 40); hot.setDataAtCell(1, 1, 'x'); hot.setDataAtCell(2, 2, 'c'); hot.setDataAtCell(3, 3, 'v'); hot.setDataAtCell(4, 4, 'b'); hot.setDataAtCell(5, 5, 'n'); hot.selectCell(0, 0);
const filters = hot.getPlugin('filters');
filters.addCondition(2, 'contains', ['3']); filters.filter(); hot.getPlugin('columnSorting').sort({ column: 1, sortOrder: 'desc' }); // The table will be re-rendered and cache will be recalculated once after executing the callback});| Param | Type | Description |
|---|---|---|
| wrappedOperations | function | Batched operations wrapped in a function. |
Returns: * - Returns result from the wrappedOperations callback.
batchExecution
core.batchExecution(wrappedOperations, [forceFlushChanges]) ⇒ *
The method aggregates multi-line API calls into a callback and postpones the table execution process. After the execution of the operations, the internal table cache is recalculated once. As a result, it improves the performance of wrapped operations. Without batching, a similar case could trigger multiple table cache rebuilds.
Since: 8.3.0
Example
hot.batchExecution(() => { const filters = hot.getPlugin('filters');
filters.addCondition(2, 'contains', ['3']); filters.filter(); hot.getPlugin('columnSorting').sort({ column: 1, sortOrder: 'desc' }); // The table cache will be recalculated once after executing the callback});| Param | Type | Default | Description |
|---|---|---|---|
| wrappedOperations | function | Batched operations wrapped in a function. | |
| [forceFlushChanges] | boolean | false | optional If true, the table internal data cache is recalculated after the execution of the batched operations. For nested calls, it can be a desire to recalculate the table after each batch. |
Returns: * - Returns result from the wrappedOperations callback.
batchRender
core.batchRender(wrappedOperations) ⇒ *
The method aggregates multi-line API calls into a callback and postpones the table rendering process. After the execution of the operations, the table is rendered once. As a result, it improves the performance of wrapped operations. Without batching, a similar case could trigger multiple table render calls.
Since: 8.3.0
Example
hot.batchRender(() => { hot.alter('insert_row_above', 5, 45); hot.alter('insert_col_start', 10, 40); hot.setDataAtCell(1, 1, 'John'); hot.setDataAtCell(2, 2, 'Mark'); hot.setDataAtCell(3, 3, 'Ann'); hot.setDataAtCell(4, 4, 'Sophia'); hot.setDataAtCell(5, 5, 'Mia'); hot.selectCell(0, 0); // The table will be rendered once after executing the callback});| Param | Type | Description |
|---|---|---|
| wrappedOperations | function | Batched operations wrapped in a function. |
Returns: * - Returns result from the wrappedOperations callback.
clear
core.clear()
Clears the data from the table (the table settings remain intact) and clears the current selection.
colToProp
core.colToProp(column) ⇒ string | number
Returns the property name that corresponds with the given column index. If the data source is an array of arrays, it returns the columns index.
| Param | Type | Description |
|---|---|---|
| column | number | Visual column index. |
Returns: string | number - Column property or physical column index.
countColHeaders
core.countColHeaders() ⇒ number
Returns the number of rendered column headers.
Since: 14.0.0
Returns: number - Number of column headers.
countCols
core.countCols() ⇒ number
Returns the total number of rendered columns. If the columns option is defined, it returns the number of columns set in that configuration, not the number of columns in the data source.
Returns: number - Total number of columns.
countEmptyCols
core.countEmptyCols([ending]) ⇒ number
Returns the number of empty columns. If the optional ending parameter is true, returns the number of empty
columns at right hand edge of the table.
| Param | Type | Default | Description |
|---|---|---|---|
| [ending] | boolean | false | optional If true, will only count empty columns at the end of the data source row. |
Returns: number - Count empty cols.
countEmptyRows
core.countEmptyRows([ending]) ⇒ number
Returns the number of empty rows. If the optional ending parameter is true, returns the
number of empty rows at the bottom of the table.
| Param | Type | Default | Description |
|---|---|---|---|
| [ending] | boolean | false | optional If true, will only count empty rows at the end of the data source. |
Returns: number - Count empty rows.
countRenderedCols
core.countRenderedCols() ⇒ number
Returns the number of rendered rows including columns that are partially or fully rendered outside the table viewport.
Returns: number - Returns -1 if table is not visible.
countRenderedRows
core.countRenderedRows() ⇒ number
Returns the number of rendered rows including rows that are partially or fully rendered outside the table viewport.
Returns: number - Returns -1 if table is not visible.
countRowHeaders
core.countRowHeaders() ⇒ number
Returns the number of rendered row headers.
Since: 14.0.0
Returns: number - Number of row headers.
countRows
core.countRows() ⇒ number
Returns the total number of visual rows in the table.
Returns: number - Total number of rows.
countSourceCols
core.countSourceCols() ⇒ number
Returns the total number of columns in the data source. It will take value either from schema, columns settings or the first row from the data set. Unlike countCols(), this value is not affected by the columns configuration option.
Returns: number - Total number of columns.
countSourceRows
core.countSourceRows() ⇒ number
Returns the total number of rows in the data source.
Returns: number - Total number of rows.
countVisibleCols
core.countVisibleCols() ⇒ number
Returns the number of rendered columns that are only visible in the table viewport. The columns that are partially visible are not counted.
Returns: number - Number of visible columns or -1.
countVisibleRows
core.countVisibleRows() ⇒ number
Returns the number of rendered rows that are only visible in the table viewport. The rows that are partially visible are not counted.
Returns: number - Number of visible rows or -1.
deselectCell
core.deselectCell()
Deselects the current cell selection on the table.
destroy
core.destroy()
Removes the table from the DOM and destroys the instance of the Handsontable.
Emits: Hooks#event:afterDestroy
destroyEditor
core.destroyEditor([revertOriginal], [prepareEditorIfNeeded])
Destroys the current editor, render the table and prepares the editor of the newly selected cell.
| Param | Type | Default | Description |
|---|---|---|---|
| [revertOriginal] | boolean | false | optional If true, the previous value will be restored. Otherwise, the edited value will be saved. |
| [prepareEditorIfNeeded] | boolean | true | optional If true, the editor under the selected cell will be prepared to open. |
emptySelectedCells
core.emptySelectedCells([source])
Erases content from cells that have been selected in the table.
Emits: Hooks#event:beforeChange, Hooks#event:afterChange
Since: 0.36.0
| Param | Type | Description |
|---|---|---|
| [source] | string | optional String that identifies how this change will be described in the changes array (useful in Hooks#afterChange or Hooks#beforeChange callbacks). Set to ‘edit’ if left empty. |
getActiveEditor
core.getActiveEditor() ⇒ BaseEditor | undefined
Returns the active editor class instance.
The active editor is the editor instance associated with the currently selected cell.
An editor becomes active when a cell is selected and the editor is prepared (but not
necessarily open). If no cell is selected, the method returns undefined.
Returns: BaseEditor | undefined - The active editor instance, or undefined if no cell is selected.
getActiveSelectionLayerIndex
core.getActiveSelectionLayerIndex() ⇒ number
Returns the index of the active selection layer. Active selection layer is the layer that has visible focus highlight.
Since: 16.1.0
Returns: number - The index of the active selection layer. 0 to N where 0 is the last (oldest) layer and N is the first (newest) layer.
getCell
core.getCell(row, column, [topmost]) ⇒ HTMLTableCellElement | null
Returns a TD element for the given row and column arguments, if it is rendered on screen.
Returns null if the TD is not rendered on screen (probably because that part of the table is not visible).
| Param | Type | Default | Description |
|---|---|---|---|
| row | number | Visual row index. | |
| column | number | Visual column index. | |
| [topmost] | boolean | false | optional If set to true, it returns the TD element from the topmost overlay. For example, if the wanted cell is in the range of fixed rows, it will return a TD element from the top overlay. |
Returns: HTMLTableCellElement | null - The cell’s TD element.
getCellEditor
core.getCellEditor(rowOrMeta, column) ⇒ function | boolean
Returns the cell editor class by the provided row and column arguments.
Example
// Get cell editor class using `row` and `column` coordinates.hot.getCellEditor(1, 1);// Get cell editor class using cell meta object.hot.getCellEditor(hot.getCellMeta(1, 1));| Param | Type | Description |
|---|---|---|
| rowOrMeta | number | Visual row index or cell meta object (see Core#getCellMeta). |
| column | number | Visual column index. |
Returns: function | boolean - Returns the editor class or false is cell editor is disabled.
getCellMeta
core.getCellMeta(row, column, options) ⇒ object
Returns the cell properties object for the given row and column coordinates.
The returned object reflects the effective cell configuration after cascading configuration (grid, column, and cell levels). To read global grid settings only, use [[getSettings]]. To read column-level meta, use [[getColumnMeta]].
Emits: Hooks#event:beforeGetCellMeta, Hooks#event:afterGetCellMeta
| Param | Type | Default | Description |
|---|---|---|---|
| row | number | Visual row index. | |
| column | number | Visual column index. | |
| options | object | Execution options for the getCellMeta method. | |
| [options.skipMetaExtension] | boolean | false | optional If true, skips extending the cell meta object. This means, the cells function, as well as the afterGetCellMeta and beforeGetCellMeta hooks, will not be called. |
Returns: object - The cell properties object.
getCellMetaAtRow
core.getCellMetaAtRow(row) ⇒ Array
Returns an array of cell meta objects for specified physical row index.
| Param | Type | Description |
|---|---|---|
| row | number | Physical row index. |
getCellMetaTransient
core.getCellMetaTransient(row, column) ⇒ object
Returns the cell properties object for the given row and column coordinates without
retaining it in the cell meta cache.
Like [[getCellMeta]], the returned object reflects the effective cell configuration after
cascading configuration
and dynamic extension (the cells function and the beforeGetCellMeta/afterGetCellMeta
hooks run). Unlike getCellMeta, when the cell has no stored meta object the extension runs
on a temporary object that is not saved, so scanning many cells (for example, a whole column
or the entire dataset) does not permanently allocate one meta object per visited cell. Cells
that already carry stored meta (for example, written by [[setCellMeta]] or the cell option)
return their stored object, exactly as getCellMeta would.
Use this method for read-only bulk scans. Do not write to the returned object - for cells
without stored meta the write lands on the temporary object and is lost; use setCellMeta
to persist values.
Emits: Hooks#event:beforeGetCellMeta, Hooks#event:afterGetCellMeta
Since: 18.1.0
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
| column | number | Visual column index. |
Returns: object - The cell properties object.
getCellRenderer
core.getCellRenderer(rowOrMeta, column) ⇒ function
Returns the cell renderer function by given row and column arguments.
Example
// Get cell renderer using `row` and `column` coordinates.hot.getCellRenderer(1, 1);// Get cell renderer using cell meta object.hot.getCellRenderer(hot.getCellMeta(1, 1));| Param | Type | Description |
|---|---|---|
| rowOrMeta | number object | Visual row index or cell meta object (see Core#getCellMeta). |
| column | number | Visual column index. |
Returns: function - Returns the renderer function.
getCellsMeta
core.getCellsMeta() ⇒ Array
Get all the cells meta settings at least once generated in the table (in order of cell initialization).
Returns: Array - Returns an array of ColumnSettings object instances.
getCellValidator
core.getCellValidator(rowOrMeta, column) ⇒ function | RegExp | undefined
Returns the cell validator by row and column.
Example
// Get cell validator using `row` and `column` coordinates.hot.getCellValidator(1, 1);// Get cell validator using cell meta object.hot.getCellValidator(hot.getCellMeta(1, 1));| Param | Type | Description |
|---|---|---|
| rowOrMeta | number object | Visual row index or cell meta object (see Core#getCellMeta). |
| column | number | Visual column index. |
Returns: function | RegExp | undefined - The validator function.
getColHeader
core.getColHeader([column], [headerLevel]) ⇒ Array | string | number
Gets the values of column headers (if column headers are enabled).
To get an array with the values of all
bottom-most column headers,
call getColHeader() with no arguments.
To get the value of the bottom-most header of a specific column, use the column parameter.
To get the value of a specific-level header
of a specific column, use the column and headerLevel parameters.
Read more:
// get the contents of all bottom-most column headershot.getColHeader();
// get the contents of the bottom-most header of a specific columnhot.getColHeader(5);
// get the contents of a specific column header at a specific levelhot.getColHeader(5, -2);Emits: Hooks#event:modifyColHeader, Hooks#event:modifyColumnHeaderValue
| Param | Type | Default | Description |
|---|---|---|---|
| [column] | number | optional A visual column index. | |
| [headerLevel] | number | -1 | optional (Since 12.3.0) Header level index. Accepts positive (0 to n) and negative (-1 to -n) values. For positive values, 0 points to the topmost header. For negative values, -1 points to the bottom-most header (the header closest to the cells). |
Returns: Array | string | number - Column header values.
getColumnMeta
core.getColumnMeta(column) ⇒ object
Returns the meta information for the provided column.
The returned object reflects the column-level configuration after cascading configuration (grid and column levels). To read global grid settings only, use [[getSettings]]. To read the effective configuration for a specific cell, use [[getCellMeta]].
Since: 14.5.0
| Param | Type | Description |
|---|---|---|
| column | number | Visual column index. |
getColWidth
core.getColWidth(column, [source]) ⇒ number
Returns the width of the requested column.
Emits: Hooks#event:modifyColWidth
| Param | Type | Description |
|---|---|---|
| column | number | Visual column index. |
| [source] | string | optional The source of the call. |
Returns: number - Column width.
getCoords
core.getCoords(element) ⇒ CellCoords | null
Returns the coordinates of the cell, provided as a HTML table cell element.
Example
hot.getCoords(hot.getCell(1, 1));// it returns CellCoords object instance with props row: 1 and col: 1.| Param | Type | Description |
|---|---|---|
| element | HTMLTableCellElement | The HTML Element representing the cell. |
Returns: CellCoords | null - Visual coordinates object.
getCopyableData
core.getCopyableData(row, column) ⇒ string
Returns the data’s copyable value at specified row and column index.
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
| column | number | Visual column index. |
getCopyableSourceData
core.getCopyableSourceData(row, column) ⇒ string
Returns the source data’s copyable value at specified row and column index.
Since: 16.1.0
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
| column | number | Visual column index. |
getCopyableText
core.getCopyableText(startRow, startCol, endRow, endCol) ⇒ string
Returns a string value of the selected range. Each column is separated by tab, each row is separated by a new line character.
| Param | Type | Description |
|---|---|---|
| startRow | number | From visual row index. |
| startCol | number | From visual column index. |
| endRow | number | To visual row index. |
| endCol | number | To visual column index. |
getCurrentThemeName
core.getCurrentThemeName() ⇒ string | undefined
Gets the name of the currently used theme.
Since: 15.0.0
Returns: string | undefined - The name of the currently used theme.
getData
core.getData([row], [column], [row2], [column2]) ⇒ Array<Array>
Returns the current visual data as a 2D array.
Unlike the source data (which may be an array of objects), getData() always
returns an array of arrays regardless of the original data format. The returned
data reflects the current visual state of the grid: rows and columns are in their
current visual order, after any sorting, filtering, or reordering.
To retrieve the data in its original source format, use the Core#getSourceData method instead.
Optionally you can provide a cell range by defining row, column, row2, column2
to get only a fragment of the data.
Example
// Get all data (in order how it is rendered in the table).hot.getData();// Get data fragment (from top-left 0, 0 to bottom-right 3, 3).hot.getData(3, 3);// Get data fragment (from top-left 2, 1 to bottom-right 3, 3).hot.getData(2, 1, 3, 3);| Param | Type | Description |
|---|---|---|
| [row] | number | optional From visual row index. |
| [column] | number | optional From visual column index. |
| [row2] | number | optional To visual row index. |
| [column2] | number | optional To visual column index. |
Returns: Array<Array> - A 2D array of cell values in the current visual order.
getDataAtCell
core.getDataAtCell(row, column) ⇒ *
Returns the cell value at row, column.
Note: If data is reordered, sorted or trimmed, the currently visible order will be used.
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
| column | number | Visual column index. |
Returns: * - Data at cell.
getDataAtCol
core.getDataAtCol(column) ⇒ Array
Returns array of column values from the data source.
Note: If columns were reordered or sorted, the currently visible order will be used.
| Param | Type | Description |
|---|---|---|
| column | number | Visual column index. |
Returns: Array - Array of cell values.
getDataAtProp
core.getDataAtProp(prop) ⇒ Array
Given the object property name (e.g. 'first.name' or '0'), returns an array of column’s values from the table data.
You can also provide a column index as the first argument.
| Param | Type | Description |
|---|---|---|
| prop | string number | Property name or physical column index. |
Returns: Array - Array of cell values.
getDataAtRow
core.getDataAtRow(row) ⇒ Array
Returns a single row of the data.
Note: If rows were reordered, sorted or trimmed, the currently visible order will be used.
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
Returns: Array - Array of row’s cell data.
getDataAtRowProp
core.getDataAtRowProp(row, prop) ⇒ *
Returns value at visual row and prop indexes.
Note: If data is reordered, sorted or trimmed, the currently visible order will be used.
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
| prop | string | Property name. |
Returns: * - Cell value.
getDataType
core.getDataType(rowFrom, columnFrom, rowTo, columnTo) ⇒ string
Returns a data type defined in the Handsontable settings under the type key (Options#type).
If there are cells with different types in the selected range, it returns 'mixed'.
Note: If data is reordered, sorted or trimmed, the currently visible order will be used.
| Param | Type | Description |
|---|---|---|
| rowFrom | number | From visual row index. |
| columnFrom | number | From visual column index. |
| rowTo | number | To visual row index. |
| columnTo | number | To visual column index. |
Returns: string - Cell type (e.q: 'mixed', 'text', 'numeric', 'autocomplete').
getDirectionFactor
core.getDirectionFactor() ⇒ number
Returns 1 for LTR; -1 for RTL. Useful for calculations.
Since: 12.0.0
Returns: number - Returns 1 for LTR; -1 for RTL.
getFirstFullyVisibleColumn
core.getFirstFullyVisibleColumn() ⇒ number | null
Returns the first fully visible column in the table viewport. When the table has overlays the method returns the first row of the main table that is not overlapped by overlay.
Since: 14.6.0
getFirstFullyVisibleRow
core.getFirstFullyVisibleRow() ⇒ number | null
Returns the first fully visible row in the table viewport. When the table has overlays the method returns the first row of the main table that is not overlapped by overlay.
Since: 14.6.0
getFirstPartiallyVisibleColumn
core.getFirstPartiallyVisibleColumn() ⇒ number | null
Returns the first partially visible column in the table viewport. When the table has overlays the method returns the first row of the main table that is not overlapped by overlay.
Since: 14.6.0
getFirstPartiallyVisibleRow
core.getFirstPartiallyVisibleRow() ⇒ number | null
Returns the first partially visible row in the table viewport. When the table has overlays the method returns the first row of the main table that is not overlapped by overlay.
Since: 14.6.0
getFirstRenderedVisibleColumn
core.getFirstRenderedVisibleColumn() ⇒ number | null
Returns the first rendered column in the DOM (usually, it is not visible in the table’s viewport).
When the MergeCells plugin is enabled with its default virtualized: false setting, a merged
cell that crosses the viewport edge extends the rendered column range, so this method can return a
column index further from the viewport than usual. For the actual visible viewport, use
Core#getFirstFullyVisibleColumn or Core#getFirstPartiallyVisibleColumn.
Since: 14.6.0
getFirstRenderedVisibleRow
core.getFirstRenderedVisibleRow() ⇒ number | null
Returns the first rendered row in the DOM (usually, it is not visible in the table’s viewport).
When the MergeCells plugin is enabled with its default virtualized: false setting, a merged
cell that crosses the viewport edge extends the rendered row range, so this method can return a row
index further from the viewport than usual. For the actual visible viewport, use
Core#getFirstFullyVisibleRow or Core#getFirstPartiallyVisibleRow.
Since: 14.6.0
getFocusManager
core.getFocusManager() ⇒ FocusManager
Return the Focus Manager responsible for managing the browser’s focus in the table.
Since: 14.0.0
getFocusScopeManager
core.getFocusScopeManager() ⇒ FocusScopeManager
Returns the Focus Scope Manager. The module allows to register focus scopes for different parts of the grid e.g. for dialogs, pagination, and other plugins that have own UI elements and need separate context.
Since: 16.2.0
Example
hot.getFocusScopeManager().registerScope('myPluginName', containerElement, { shortcutsContextName: 'plugin:myPluginName', onActivate: (focusSource) => { // Focus the internal focusable element within the plugin UI element // depends on the activation focus source. },});Returns: FocusScopeManager - Instance of FocusScopeManager
getInstance
core.getInstance() ⇒ Handsontable
Returns the Handsontable instance.
Returns: Handsontable - The Handsontable instance.
getLastFullyVisibleColumn
core.getLastFullyVisibleColumn() ⇒ number | null
Returns the last fully visible column in the table viewport. When the table has overlays the method returns the first row of the main table that is not overlapped by overlay.
Since: 14.6.0
getLastFullyVisibleRow
core.getLastFullyVisibleRow() ⇒ number | null
Returns the last fully visible row in the table viewport. When the table has overlays the method returns the first row of the main table that is not overlapped by overlay.
Since: 14.6.0
getLastPartiallyVisibleColumn
core.getLastPartiallyVisibleColumn() ⇒ number | null
Returns the last partially visible column in the table viewport. When the table has overlays the method returns the first row of the main table that is not overlapped by overlay.
Since: 14.6.0
getLastPartiallyVisibleRow
core.getLastPartiallyVisibleRow() ⇒ number | null
Returns the last partially visible row in the table viewport. When the table has overlays the method returns the first row of the main table that is not overlapped by overlay.
Since: 14.6.0
getLastRenderedVisibleColumn
core.getLastRenderedVisibleColumn() ⇒ number | null
Returns the last rendered column in the DOM (usually, it is not visible in the table’s viewport).
When the MergeCells plugin is enabled with its default virtualized: false setting, a merged
cell that crosses the viewport edge extends the rendered column range, so this method can return a
column index further from the viewport than usual. For the actual visible viewport, use
Core#getLastFullyVisibleColumn or Core#getLastPartiallyVisibleColumn.
Since: 14.6.0
getLastRenderedVisibleRow
core.getLastRenderedVisibleRow() ⇒ number | null
Returns the last rendered row in the DOM (usually, it is not visible in the table’s viewport).
When the MergeCells plugin is enabled with its default virtualized: false setting, a merged
cell that crosses the viewport edge extends the rendered row range, so this method can return a row
index further from the viewport than usual. For the actual visible viewport, use
Core#getLastFullyVisibleRow or Core#getLastPartiallyVisibleRow.
Since: 14.6.0
getLayoutManager
core.getLayoutManager() ⇒ LayoutManager
Returns the Layout Manager. The module manages the order of plugin UI elements within the
user-orderable wrapper slots (top, bottom). Use it to add or remove custom UI and
order it via weights or the layout setting. Only available for the main instance.
Since: 18.0.0
Example
hot.getLayoutManager().register('myToolbar', toolbarElement, { side: 'top', weight: 100 });Returns: LayoutManager - Instance of LayoutManager
getPlugin
core.getPlugin(pluginName) ⇒ BasePlugin | undefined
Returns plugin instance by provided its name.
| Param | Type | Description |
|---|---|---|
| pluginName | string | The plugin name. |
Returns: BasePlugin | undefined - The plugin instance or undefined if there is no plugin.
getRowHeader
core.getRowHeader([row]) ⇒ Array | string | number
Returns an array of row headers’ values (if they are enabled). If param row was given, it returns the header of the given row as a string.
Emits: Hooks#event:modifyRowHeader
| Param | Type | Description |
|---|---|---|
| [row] | number | optional Visual row index. |
Returns: Array | string | number - Array of header values / single header value.
getRowHeight
core.getRowHeight(row, [source]) ⇒ number | undefined
Returns a row’s height, as recognized by Handsontable.
Depending on your configuration, the method returns (in order of priority):
- The row height set by the
ManualRowResizeplugin (if the plugin is enabled). - The row height set by the
rowHeightsconfiguration option (if the option is set). - The row height as measured in the DOM by the
AutoRowSizeplugin (if the plugin is enabled). undefined, if neitherManualRowResize, norrowHeights, norAutoRowSizeis used.
The height returned includes 1 px of the row’s bottom border.
Mind that this method is different from the
getRowHeight() method
of the AutoRowSize plugin.
Emits: Hooks#event:modifyRowHeight
| Param | Type | Description |
|---|---|---|
| row | number | A visual row index. |
| [source] | string | optional The source of the call. |
Returns: number | undefined - The height of the specified row, in pixels.
getSchema
core.getSchema() ⇒ object
Returns schema provided by constructor settings. If it doesn’t exist then it returns the schema based on the data structure in the first row.
Returns: object - Schema object.
getSelected
core.getSelected() ⇒ Array<Array> | undefined
Returns indexes of the currently selected cells as an array of arrays [[startRow, startCol, endRow, endCol],...].
Start row and start column are the coordinates of the active cell (where the selection was started).
The version 0.36.0 adds a non-consecutive selection feature. Since this version, the method returns an array of arrays.
Additionally to collect the coordinates of the currently selected area (as it was previously done by the method)
you need to use getSelectedLast method.
Returns: Array<Array> | undefined - An array of arrays of the selection’s coordinates.
getSelectedActive
core.getSelectedActive() ⇒ Array<number> | undefined
Returns the range coordinates of the active selection layer as an array. Active selection layer is the layer that has visible focus highlight.
Since: 16.1.0
Returns: Array<number> | undefined - Selected range as an array of coordinates or undefined if there is no selection.
getSelectedLast
core.getSelectedLast() ⇒ Array | undefined
Returns the last coordinates applied to the table as a an array [startRow, startCol, endRow, endCol].
Since: 0.36.0
Returns: Array | undefined - An array of the selection’s coordinates.
getSelectedRange
core.getSelectedRange() ⇒ Array<CellRange> | undefined
Returns the current selection as an array of CellRange objects.
The version 0.36.0 adds a non-consecutive selection feature. Since this version, the method returns an array of arrays.
Additionally to collect the coordinates of the active selected area (as it was previously done by the method)
you need to use getSelectedRangeActive() method.
Returns: Array<CellRange> | undefined - Selected range object or undefined if there is no selection.
getSelectedRangeActive
core.getSelectedRangeActive() ⇒ CellRange | undefined
Returns the range coordinates of the active selection layer. Active selection layer is the layer that has visible focus highlight.
Since: 16.1.0
Returns: CellRange | undefined - Selected range object or undefined if there is no selection.
getSelectedRangeLast
core.getSelectedRangeLast() ⇒ CellRange | undefined
Returns the last coordinates applied to the table as a CellRange object.
Since: 0.36.0
Returns: CellRange | undefined - Selected range object or undefined if there is no selection.
getSettings
core.getSettings() ⇒ TableMeta
Returns the current global grid settings object.
The returned object contains the settings passed to the constructor or the most recent
updateSettings() call. It reflects the
grid-level
configuration only.
It does not include merged per-cell or per-column values. Configuration options cascade from grid to column to cell (see Cascading configuration). To read the effective value for a specific cell, use [[getCellMeta]]. To read column-level meta, use [[getColumnMeta]].
Example
const hot = new Handsontable(container, { readOnly: false, columns: (index) => ({ readOnly: index === 2 || index === 8, }),});
// returns `false` (global grid-level setting)hot.getSettings().readOnly;
// returns `true` for column 2 (merged column and cell meta)hot.getCellMeta(0, 2).readOnly;Returns: TableMeta - Object containing the current global grid settings.
getShortcutManager
core.getShortcutManager() ⇒ ShortcutManager
Returns instance of a manager responsible for handling shortcuts stored in some contexts. It run actions after pressing key combination in active Handsontable instance.
Since: 12.0.0
Returns: ShortcutManager - Instance of ShortcutManager
getSourceData
core.getSourceData([row], [column], [row2], [column2]) ⇒ Array<Array> | Array<object>
Returns a clone of the source data object.
Optionally you can provide a cell range by using the row, column, row2, column2 arguments, to get only a
fragment of the table data.
Note: This method does not participate in data transformation. If the visual data of the table is reordered, sorted or trimmed only physical indexes are correct.
Note: This method may return incorrect values for cells that contain
formulas. This is because getSourceData()
operates on source data (physical indexes),
whereas formulas operate on visual data (visual indexes).
| Param | Type | Description |
|---|---|---|
| [row] | number | optional From physical row index. |
| [column] | number | optional From physical column index (or visual index, if data type is an array of objects). |
| [row2] | number | optional To physical row index. |
| [column2] | number | optional To physical column index (or visual index, if data type is an array of objects). |
Returns: Array<Array> | Array<object> - The table data.
getSourceDataArray
core.getSourceDataArray([row], [column], [row2], [column2]) ⇒ Array
Returns the source data object as an arrays of arrays format even when source data was provided in another format.
Optionally you can provide a cell range by using the row, column, row2, column2 arguments, to get only a
fragment of the table data.
Note: This method does not participate in data transformation. If the visual data of the table is reordered, sorted or trimmed only physical indexes are correct.
| Param | Type | Description |
|---|---|---|
| [row] | number | optional From physical row index. |
| [column] | number | optional From physical column index (or visual index, if data type is an array of objects). |
| [row2] | number | optional To physical row index. |
| [column2] | number | optional To physical column index (or visual index, if data type is an array of objects). |
Returns: Array - An array of arrays.
getSourceDataAtCell
core.getSourceDataAtCell(row, column) ⇒ *
Returns a single value from the data source.
| Param | Type | Description |
|---|---|---|
| row | number | Physical row index. |
| column | number | Visual column index. |
Returns: * - Cell data.
getSourceDataAtCol
core.getSourceDataAtCol(column) ⇒ Array
Returns an array of column values from the data source.
| Param | Type | Description |
|---|---|---|
| column | number | Visual column index. |
Returns: Array - Array of the column’s cell values.
getSourceDataAtRow
core.getSourceDataAtRow(row) ⇒ Array | object
Returns a single row of the data (array or object, depending on what data format you use).
Note: This method does not participate in data transformation. If the visual data of the table is reordered, sorted or trimmed only physical indexes are correct.
| Param | Type | Description |
|---|---|---|
| row | number | Physical row index. |
Returns: Array | object - Single row of data.
getTableHeight
core.getTableHeight() ⇒ number
Gets the table’s root container element height.
Since: 16.0.0
getTableWidth
core.getTableWidth() ⇒ number
Gets the table’s root container element width.
Since: 16.0.0
getTranslatedPhrase
core.getTranslatedPhrase(dictionaryKey, extraArguments) ⇒ string
Get language phrase for specified dictionary key.
Since: 0.35.0
| Param | Type | Description |
|---|---|---|
| dictionaryKey | string | Constant which is dictionary key. |
| extraArguments | * | Arguments which will be handled by formatters. |
getValue
core.getValue() ⇒ *
Gets the value of the currently focused cell.
For column headers and row headers, returns null.
Returns: * - The value of the focused cell.
hasColHeaders
core.hasColHeaders() ⇒ boolean
Returns information about if this table is configured to display column headers.
Returns: boolean - true if the instance has the column headers enabled, false otherwise.
hasHook
core.hasHook(key) ⇒ boolean
Check if for a specified hook name there are added listeners (only for this Handsontable instance). All available hooks you will find Hooks.
See: Hooks#has
Example
const hasBeforeInitListeners = hot.hasHook('beforeInit');| Param | Type | Description |
|---|---|---|
| key | string | Hook name. |
hasRowHeaders
core.hasRowHeaders() ⇒ boolean
Returns information about if this table is configured to display row headers.
Returns: boolean - true if the instance has the row headers enabled, false otherwise.
initializeThemeManager
Core~initializeThemeManager(theme)
Initializes the ThemeManager with the given theme configuration.
| Param | Type | Description |
|---|---|---|
| theme | object boolean | The theme configuration object or true to use the default theme. |
isColumnModificationAllowed
core.isColumnModificationAllowed() ⇒ boolean
Checks if your data format and configuration options allow for changing the number of columns.
Returns false when your data is an array of objects,
or when you use the columns option.
Otherwise, returns true.
isEmptyCol
core.isEmptyCol(column) ⇒ boolean
Check if all cells in the the column declared by the column argument are empty.
| Param | Type | Description |
|---|---|---|
| column | number | Column index. |
Returns: boolean - true if the column at the given col is empty, false otherwise.
isEmptyRow
core.isEmptyRow(row) ⇒ boolean
Check if all cells in the row declared by the row argument are empty.
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
Returns: boolean - true if the row at the given row is empty, false otherwise.
isExecutionSuspended
core.isExecutionSuspended() ⇒ boolean
Checks if the table indexes recalculation process was suspended. See explanation in Core#suspendExecution.
Since: 8.3.0
isListening
core.isListening() ⇒ boolean
Returns true if the current Handsontable instance is listening to keyboard input on document body.
Returns: boolean - true if the instance is listening, false otherwise.
isLtr
core.isLtr() ⇒ boolean
Checks if the grid is rendered using the left-to-right layout direction.
Since: 12.0.0
Returns: boolean - True if LTR.
isRenderSuspended
core.isRenderSuspended() ⇒ boolean
Checks if the table rendering process was suspended. See explanation in Core#suspendRender.
Since: 8.3.0
isRtl
core.isRtl() ⇒ boolean
Checks if the grid is rendered using the right-to-left layout direction.
Since: 12.0.0
Returns: boolean - True if RTL.
listen
core.listen()
Listen to the keyboard input on document body. This allows Handsontable to capture keyboard events and respond in the right way.
Emits: Hooks#event:afterListen
loadData
core.loadData(data, [source])
The loadData() method replaces Handsontable’s data with a new dataset.
Additionally, the loadData() method:
- Resets cells’ states (e.g. cells’ formatting and cells’
readOnlystates) - Resets rows’ states (e.g. row order)
- Resets columns’ states (e.g. column order)
To replace Handsontable’s data without resetting states, use the updateData() method.
Read more:
Emits: Hooks#event:beforeLoadData, Hooks#event:afterLoadData, Hooks#event:afterChange
| Param | Type | Description |
|---|---|---|
| data | Array | An array of arrays, or an array of objects, that contains Handsontable’s data. |
| [source] | string | optional The source of the loadData() call. |
populateFromArray
core.populateFromArray(row, column, input, [endRow], [endCol], [source], [method]) ⇒ object | undefined
Populates cells at position with 2D input array (e.g. [[1, 2], [3, 4]]). Use endRow, endCol when you
want to cut input when a certain row is reached.
The populateFromArray() method can’t change readOnly cells.
Optional method argument has the same effect as pasteMode option (see Options#pasteMode).
| Param | Type | Default | Description |
|---|---|---|---|
| row | number | Start visual row index. | |
| column | number | Start visual column index. | |
| input | Array | 2d array. | |
| [endRow] | number | optional End visual row index (use when you want to cut input when certain row is reached). | |
| [endCol] | number | optional End visual column index (use when you want to cut input when certain column is reached). | |
| [source] | string | ”populateFromArray” | optional Used to identify this call in the resulting events (beforeChange, afterChange). |
| [method] | string | ”overwrite” | optional Populate method, possible values: 'shift_down', 'shift_right', 'overwrite'. |
Returns: object | undefined - Ending td in pasted area (only if any cell was changed).
propToCol
core.propToCol(prop) ⇒ number
Returns column index that corresponds with the given property.
| Param | Type | Description |
|---|---|---|
| prop | string number | Property name or physical column index. |
Returns: number - Visual column index.
refreshDimensions
core.refreshDimensions()
Updates dimensions of the table. The method compares previous dimensions with the current ones and updates accordingly.
Emits: Hooks#event:beforeRefreshDimensions, Hooks#event:afterRefreshDimensions
removeCellMeta
core.removeCellMeta(row, column, key)
Remove a property defined by the key argument from the cell meta object for the provided row and column coordinates.
Emits: Hooks#event:beforeRemoveCellMeta, Hooks#event:afterRemoveCellMeta
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
| column | number | Visual column index. |
| key | string | Property name. |
removeHook
core.removeHook(key, callback)
Removes the hook listener previously registered with Core#addHook.
See: Hooks#remove
Example
hot.removeHook('beforeInit', myCallback);| Param | Type | Description |
|---|---|---|
| key | string | Hook name. |
| callback | function | Reference to the function which has been registered using Core#addHook. |
render
core.render()
Rerender the table. Calling this method starts the process of recalculating, redrawing and applying the changes to the DOM. While rendering the table all cell renderers are recalled.
Calling this method manually is not recommended. Handsontable tries to render itself by choosing the most optimal moments in its lifecycle. After setCellMeta() changes visual cell properties, call this method to apply them, or wrap multiple calls in batch().
resolveRenderableScrollTarget
Core~resolveRenderableScrollTarget(row, col) ⇒ Object | false
Resolves renderable row and column indexes for scrolling, accounting for hidden indexes.
| Param | Type | Description |
|---|---|---|
| row | number undefined | Visual row index. |
| col | number undefined | Visual column index. |
Returns: Object | false - Resolved
renderable indexes, or false when scrolling target is not reachable.
resumeExecution
core.resumeExecution([forceFlushChanges])
Resumes the execution process. In combination with the Core#suspendExecution method it allows aggregating the table logic changes after which the cache is updated. Resuming the state automatically invokes the table cache updating process.
The method is intended to be used by advanced users. Suspending the execution process could cause visual glitches caused by not updated the internal table cache.
Since: 8.3.0
Example
hot.suspendExecution();const filters = hot.getPlugin('filters');
filters.addCondition(2, 'contains', ['3']);filters.filter();hot.getPlugin('columnSorting').sort({ column: 1, sortOrder: 'desc' });hot.resumeExecution(); // It updates the cache internally| Param | Type | Default | Description |
|---|---|---|---|
| [forceFlushChanges] | boolean | false | optional If true, the table internal data cache is recalculated after the execution of the batched operations. For nested Core#batchExecution calls, it can be desire to recalculate the table after each batch. |
resumeRender
core.resumeRender()
Resumes the rendering process. In combination with the Core#suspendRender method it allows aggregating the table render cycles triggered by API calls or UI actions (or both) and calls the “render” once in the end. When the table is in the suspend state, most operations will have no visual effect until the rendering state is resumed. Resuming the state automatically invokes the table rendering.
The method is intended to be used by advanced users. Suspending the rendering process could cause visual glitches when wrongly implemented.
Every suspendRender() call needs to correspond with one resumeRender() call.
For example, if you call suspendRender() 5 times, you need to call resumeRender() 5 times as well.
Since: 8.3.0
Example
hot.suspendRender();hot.alter('insert_row_above', 5, 45);hot.alter('insert_col_start', 10, 40);hot.setDataAtCell(1, 1, 'John');hot.setDataAtCell(2, 2, 'Mark');hot.setDataAtCell(3, 3, 'Ann');hot.setDataAtCell(4, 4, 'Sophia');hot.setDataAtCell(5, 5, 'Mia');hot.selectCell(0, 0);hot.resumeRender(); // It re-renders the table internallyrunHooks
core.runHooks(key, [p1], [p2], [p3], [p4], [p5], [p6]) ⇒ *
Run the callbacks for the hook provided in the key argument using the parameters given in the other arguments.
See: Hooks#run
Example
// Run built-in hookhot.runHooks('beforeInit');// Run custom hookhot.runHooks('customAction', 10, 'foo');| Param | Type | Description |
|---|---|---|
| key | string | Hook name. |
| [p1] | * | optional Argument passed to the callback. |
| [p2] | * | optional Argument passed to the callback. |
| [p3] | * | optional Argument passed to the callback. |
| [p4] | * | optional Argument passed to the callback. |
| [p5] | * | optional Argument passed to the callback. |
| [p6] | * | optional Argument passed to the callback. |
scrollToFocusedCell
core.scrollToFocusedCell([callback]) ⇒ boolean
Scrolls the viewport to coordinates specified by the currently focused cell.
Emits: Hooks#event:afterScroll
Since: 14.0.0
| Param | Type | Description |
|---|---|---|
| [callback] | function | optional The callback function to call after the viewport is scrolled. |
Returns: boolean - true if the viewport was scrolled, false otherwise.
scrollViewportTo
core.scrollViewportTo(options, [callback]) ⇒ boolean
Scroll viewport to coordinates specified by the row and/or col object properties.
The object-based signature was introduced in v14.0.0. The positional arguments form is retained for backward compatibility.
// scroll the viewport to the visual row index (leave the horizontal scroll untouched)hot.scrollViewportTo({ row: 50 });
// scroll the viewport to the passed coordinates so that the cell at 50, 50 will be snapped to// the bottom-end table's edge.hot.scrollViewportTo({ row: 50, col: 50, verticalSnap: 'bottom', horizontalSnap: 'end',}, () => { // callback function executed after the viewport is scrolled});
// scroll the viewport using the backward-compatible positional arguments formhot.scrollViewportTo(50, 50, true, true);| Param | Type | Default | Description |
|---|---|---|---|
| options | object | A dictionary containing the following parameters: | |
| [options.row] | number | optional Specifies the number of visual rows along the Y axis to scroll the viewport. | |
| [options.col] | number | optional Specifies the number of visual columns along the X axis to scroll the viewport. | |
| [options.verticalSnap] | 'top' 'bottom' | optional Determines to which edge of the table the viewport will be scrolled based on the passed coordinates. This option is a string which must take one of the following values: - top: The viewport will be scrolled to a row in such a way that it will be positioned on the top of the viewport; - bottom: The viewport will be scrolled to a row in such a way that it will be positioned on the bottom of the viewport; - If the property is not defined the vertical auto-snapping is enabled. Depending on where the viewport is scrolled from, a row will be positioned at the top or bottom of the viewport. | |
| [options.horizontalSnap] | 'start' 'end' | optional Determines to which edge of the table the viewport will be scrolled based on the passed coordinates. This option is a string which must take one of the following values: - start: The viewport will be scrolled to a column in such a way that it will be positioned on the start (left edge or right, if the layout direction is set to rtl) of the viewport; - end: The viewport will be scrolled to a column in such a way that it will be positioned on the end (right edge or left, if the layout direction is set to rtl) of the viewport; - If the property is not defined the horizontal auto-snapping is enabled. Depending on where the viewport is scrolled from, a column will be positioned at the start or end of the viewport. | |
| [options.considerHiddenIndexes] | boolean | true | optional If true, we handle visual indexes, otherwise we handle only indexes which may be rendered when they are in the viewport (we don’t consider hidden indexes as they aren’t rendered). |
| [callback] | function | optional The callback function to call after the viewport is scrolled. |
Returns: boolean - true if viewport was scrolled, false otherwise.
selectAll
core.selectAll([includeRowHeaders], [includeColumnHeaders], [options])
Select all cells in the table excluding headers and corner elements.
The previous selection is overwritten.
// Select all cells in the table along with row headers, including all headers and the corner cell.// Doesn't select column headers and corner elements.hot.selectAll();
// Select all cells in the table, including row headers but excluding the corner cell and column headers.hot.selectAll(true, false);
// Select all cells in the table, including all headers and the corner cell, but move the focus.// highlight to position 2, 1hot.selectAll(-2, -1, { focusPosition: { row: 2, col: 1 }});
// Select all cells in the table, without headers and corner elements.hot.selectAll(false);Since: 0.38.2
| Param | Type | Default | Description |
|---|---|---|---|
| [includeRowHeaders] | boolean | false | optional If true, includes the row headers in the selection. |
| [includeColumnHeaders] | boolean | false | optional If true, includes the column headers in the selection. |
| [options] | object | optional Additional object with options. Since 14.0.0. | |
| [options.focusPosition] | Object boolean | optional The argument allows changing the cell/header focus position. The value takes an object with a row and col properties from -N to N, where negative values point to the headers and positive values point to the cell range. If false, the focus position won’t be changed. When the Options#navigableHeaders option is disabled (the default), a focusPosition that points to a header is relocated to the nearest cell in the data set. Example: js hot.selectAll(0, 0, { focusPosition: { row: 0, col: 1 }, disableHeadersHighlight: true }) | |
| [options.disableHeadersHighlight] | boolean | optional If true, disables highlighting the headers even when the logical coordinates points on them. This only suppresses the highlight shown on headers of a fully-selected row or column. It doesn’t affect the focus indicator on the individual cell or header that holds the focus, which stays visible even when Options#navigableHeaders moves the focus onto a header. |
selectCell
core.selectCell(row, column, [endRow], [endColumn], [scrollToCell], [changeListener]) ⇒ boolean
Select a single cell, or a single range of adjacent cells.
To select a cell, pass its visual row and column indexes, for example: selectCell(2, 4).
To select a range, pass the visual indexes of the first and last cell in the range, for example: selectCell(2, 4, 3, 5).
If your columns have properties, you can pass those properties’ values instead of column indexes, for example: selectCell(2, 'first_name').
By default, selectCell() also:
- Scrolls the viewport to the newly-selected cells.
- Switches the keyboard focus to Handsontable (by calling Handsontable’s
listen()method).
Example
// select a single cellhot.selectCell(2, 4);
// select a range of cellshot.selectCell(2, 4, 3, 5);
// select a single cell, using a column propertyhot.selectCell(2, 'first_name');
// select a range of cells, using column propertieshot.selectCell(2, 'first_name', 3, 'last_name');
// select a range of cells, without scrolling to themhot.selectCell(2, 4, 3, 5, false);
// select a range of cells, without switching the keyboard focus to Handsontablehot.selectCell(2, 4, 3, 5, null, false);| Param | Type | Default | Description |
|---|---|---|---|
| row | number | A visual row index. | |
| column | number string | A visual column index (number), or a column property’s value (string). | |
| [endRow] | number | optional If selecting a range: the visual row index of the last cell in the range. | |
| [endColumn] | number string | optional If selecting a range: the visual column index (or a column property’s value) of the last cell in the range. | |
| [scrollToCell] | boolean | true | optional If true, scrolls the viewport to the newly-selected cells. If false, keeps the previous viewport. |
| [changeListener] | boolean | true | optional If true, switches the keyboard focus to Handsontable. If false, keeps the previous keyboard focus. If an element outside Handsontable (such as a custom input) currently owns the browser focus, it remains focused after the call. |
Returns: boolean - true: the selection was successful, false: the selection failed.
selectCells
core.selectCells(coords, [scrollToCell], [changeListener]) ⇒ boolean
Select multiple cells or ranges of cells, adjacent or non-adjacent.
You can pass one of the below:
- An array of arrays (which matches the output of Handsontable’s
getSelected()method). - An array of
CellRangeobjects (which matches the output of Handsontable’sgetSelectedRange()method).
To select multiple cells, pass the visual row and column indexes of each cell, for example: hot.selectCells([[1, 1], [5, 5]]).
To select multiple ranges, pass the visual indexes of the first and last cell in each range, for example: hot.selectCells([[1, 1, 2, 2], [6, 2, 0, 2]]).
If your columns have properties, you can pass those properties’ values instead of column indexes, for example: hot.selectCells([[1, 'first_name'], [5, 'last_name']]).
By default, selectCell() also:
- Scrolls the viewport to the newly-selected cells.
- Switches the keyboard focus to Handsontable (by calling Handsontable’s
listen()method).
Since: 0.38.0
Example
// select non-adjacent cellshot.selectCells([[1, 1], [5, 5], [10, 10]]);
// select non-adjacent ranges of cellshot.selectCells([[1, 1, 2, 2], [10, 10, 20, 20]]);
// select cells and ranges of cellshot.selectCells([[1, 1, 2, 2], [3, 3], [6, 2, 0, 2]]);
// select cells, using column propertieshot.selectCells([[1, 'id', 2, 'first_name'], [3, 'full_name'], [6, 'last_name', 0, 'first_name']]);
// select multiple ranges, using an array of `CellRange` objectsconst selected = hot.getSelectedRange();
selected[0].from.row = 0;selected[0].from.col = 0;selected[0].to.row = 5;selected[0].to.col = 5;
selected[1].from.row = 10;selected[1].from.col = 10;selected[1].to.row = 20;selected[1].to.col = 20;
hot.selectCells(selected);| Param | Type | Default | Description |
|---|---|---|---|
| coords | Array<Array> Array<CellRange> | Visual coordinates, passed either as an array of arrays ([[rowStart, columnStart, rowEnd, columnEnd], ...]) or as an array of CellRange objects. | |
| [scrollToCell] | boolean | true | optional If true, scrolls the viewport to the newly-selected cells. If false, keeps the previous viewport. |
| [changeListener] | boolean | true | optional If true, switches the keyboard focus to Handsontable. If false, keeps the previous keyboard focus. If an element outside Handsontable (such as a custom input) currently owns the browser focus, it remains focused after the call. |
Returns: boolean - true: the selection was successful, false: the selection failed.
selectColumns
core.selectColumns(startColumn, [endColumn], [focusPosition]) ⇒ boolean
Select column specified by startColumn visual index, column property or a range of columns finishing at endColumn.
Since: 0.38.0
Example
// Select column using visual index.hot.selectColumns(1);// Select column using column property.hot.selectColumns('id');// Select range of columns using visual indexes.hot.selectColumns(1, 4);// Select range of columns using visual indexes and mark the first header as highlighted.hot.selectColumns(1, 2, -1);// Select range of columns using visual indexes and mark the second cell as highlighted.hot.selectColumns(2, 1, 1);// Select range of columns using visual indexes and move the focus position somewhere in the middle of the range.hot.selectColumns(2, 5, { row: 2, col: 3 });// Select range of columns using column properties.hot.selectColumns('id', 'last_name');| Param | Type | Default | Description |
|---|---|---|---|
| startColumn | number string | The visual column index or column property from which the selection starts. | |
| [endColumn] | number string | startColumn | optional The visual column index or column property to which the selection finishes. If endColumn is not defined the column defined by startColumn will be selected. |
| [focusPosition] | number Object CellCoords | 0 | optional The argument allows changing the cell/header focus position. The value can take visual row index from -N to N, where negative values point to the headers and positive values point to the cell range. An object with row and col properties also can be passed to change the focus position horizontally. |
Returns: boolean - true if selection was successful, false otherwise.
selectRows
core.selectRows(startRow, [endRow], [focusPosition]) ⇒ boolean
Select row specified by startRow visual index or a range of rows finishing at endRow.
Since: 0.38.0
Example
// Select row using visual index.hot.selectRows(1);// select a range of rows, using visual indexes.hot.selectRows(1, 4);// select a range of rows, using visual indexes, and mark the header as highlighted.hot.selectRows(1, 2, -1);// Select range of rows using visual indexes and mark the second cell as highlighted.hot.selectRows(2, 1, 1);// Select range of rows using visual indexes and move the focus position somewhere in the middle of the range.hot.selectRows(2, 5, { row: 2, col: 3 });| Param | Type | Default | Description |
|---|---|---|---|
| startRow | number | The visual row index from which the selection starts. | |
| [endRow] | number | startRow | optional The visual row index to which the selection finishes. If endRow is not defined the row defined by startRow will be selected. |
| [focusPosition] | number Object CellCoords | 0 | optional The argument allows changing the cell/header focus position. The value can take visual row index from -N to N, where negative values point to the headers and positive values point to the cell range. An object with row and col properties also can be passed to change the focus position vertically. |
Returns: boolean - true if selection was successful, false otherwise.
setCellMeta
core.setCellMeta(row, column, key, value)
Sets a property defined by the key property to the meta object of a cell corresponding to params row and column.
This method updates internal cell metadata only. It does not repaint the grid. To reflect visual changes (such as
className, type, or readOnly), call render() afterward, or wrap multiple calls in
batch().
Emits: Hooks#event:beforeSetCellMeta, Hooks#event:afterSetCellMeta
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
| column | number | Visual column index. |
| key | string | Property name. |
| value | string | Property value. |
setCellMetaObject
core.setCellMetaObject(row, column, prop)
Set cell meta data object defined by prop to the corresponding params row and column.
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
| column | number | Visual column index. |
| prop | object | Meta object. |
setDataAtCell
core.setDataAtCell(row, [column], [value], [source])
Set new value to a cell. To change many cells at once (recommended way), pass an array of changes in format
[[row, col, value],...] as the first argument.
Emits: Hooks#event:beforeChange, Hooks#event:afterChange
| Param | Type | Description |
|---|---|---|
| row | number Array | Visual row index or array of changes in format [[row, col, value],...]. |
| [column] | number | optional Visual column index. |
| [value] | string | optional New value. |
| [source] | string | optional String that identifies how this change will be described in the changes array (useful in Hooks#afterChange or Hooks#beforeChange callbacks). Set to ‘edit’ if left empty. |
setDataAtRowProp
core.setDataAtRowProp(row, prop, value, [source])
Set new value to a cell. To change many cells at once (recommended way), pass an array of changes in format
[[row, prop, value],...] as the first argument.
Emits: Hooks#event:beforeChange, Hooks#event:afterChange
| Param | Type | Description |
|---|---|---|
| row | number Array | Visual row index or array of changes in format [[row, prop, value], ...]. |
| prop | string | Property name or the source string (e.g. 'first.name' or '0'). |
| value | string | Value to be set. |
| [source] | string | optional String that identifies how this change will be described in changes array (useful in Hooks#afterChange or Hooks#beforeChange callbacks). |
setSourceDataAtCell
core.setSourceDataAtCell(row, column, value, [source])
Set the provided value in the source data set at the provided coordinates.
| Param | Type | Description |
|---|---|---|
| row | number Array | Physical row index or array of changes in format [[row, prop, value], ...]. |
| column | number string | Physical column index / prop name. |
| value | * | The value to be set at the provided coordinates. |
| [source] | string | optional Source of the change as a string. |
spliceCellsMeta
core.spliceCellsMeta(visualIndex, [deleteAmount], […cellMetaRows])
Removes or adds one or more rows of the cell meta objects to the cell meta collections.
Since: 0.30.0
| Param | Type | Default | Description |
|---|---|---|---|
| visualIndex | number | A visual index that specifies at what position to add/remove items. | |
| [deleteAmount] | number | 0 | optional The number of items to be removed. If set to 0, no cell meta objects will be removed. |
| […cellMetaRows] | object | optional The new cell meta row objects to be added to the cell meta collection. |
spliceCol
core.spliceCol(column, index, amount, […elements]) ⇒ Array
Adds/removes data from the column. This method works the same as Array.splice for arrays.
| Param | Type | Description |
|---|---|---|
| column | number | Index of the column in which do you want to do splice. |
| index | number | Index at which to start changing the array. If negative, will begin that many elements from the end. |
| amount | number | An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed. |
| […elements] | number | optional The elements to add to the array. If you don’t specify any elements, spliceCol simply removes elements from the array. |
Returns: Array - Returns removed portion of columns.
spliceRow
core.spliceRow(row, index, amount, […elements]) ⇒ Array
Adds/removes data from the row. This method works the same as Array.splice for arrays.
| Param | Type | Description |
|---|---|---|
| row | number | Index of column in which do you want to do splice. |
| index | number | Index at which to start changing the array. If negative, will begin that many elements from the end. |
| amount | number | An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed. |
| […elements] | number | optional The elements to add to the array. If you don’t specify any elements, spliceCol simply removes elements from the array. |
Returns: Array - Returns removed portion of rows.
suspendExecution
core.suspendExecution()
Suspends the execution process. It’s helpful to wrap the table logic changes such as index changes into one call after which the cache is updated. As a result, it improves the performance of wrapped operations.
The method is intended to be used by advanced users. Suspending the execution process could cause visual glitches caused by not updated the internal table cache.
Since: 8.3.0
Example
hot.suspendExecution();const filters = hot.getPlugin('filters');
filters.addCondition(2, 'contains', ['3']);filters.filter();hot.getPlugin('columnSorting').sort({ column: 1, sortOrder: 'desc' });hot.resumeExecution(); // It updates the cache internallysuspendRender
core.suspendRender()
Suspends the rendering process. It’s helpful to wrap the table render cycles triggered by API calls or UI actions (or both) and call the “render” once in the end. As a result, it improves the performance of wrapped operations. When the table is in the suspend state, most operations will have no visual effect until the rendering state is resumed. Resuming the state automatically invokes the table rendering. To make sure that after executing all operations, the table will be rendered, it’s highly recommended to use the Core#batchRender method or Core#batch, which additionally aggregates the logic execution that happens behind the table.
The method is intended to be used by advanced users. Suspending the rendering process could cause visual glitches when wrongly implemented.
Every suspendRender() call needs to correspond with one resumeRender() call.
For example, if you call suspendRender() 5 times, you need to call resumeRender() 5 times as well.
Since: 8.3.0
Example
hot.suspendRender();hot.alter('insert_row_above', 5, 45);hot.alter('insert_col_start', 10, 40);hot.setDataAtCell(1, 1, 'John');hot.setDataAtCell(2, 2, 'Mark');hot.setDataAtCell(3, 3, 'Ann');hot.setDataAtCell(4, 4, 'Sophia');hot.setDataAtCell(5, 5, 'Mia');hot.selectCell(0, 0);hot.resumeRender(); // It re-renders the table internallytoHTML
core.toHTML() ⇒ string
Converts instance into outerHTML of HTMLTableElement.
Since: 7.1.0
toPhysicalColumn
core.toPhysicalColumn(column) ⇒ number
Translate visual column index into physical.
This method is useful when you want to retrieve physical column index based on a visual index which can be reordered, moved or trimmed.
| Param | Type | Description |
|---|---|---|
| column | number | Visual column index. |
Returns: number - Returns physical column index.
toPhysicalRow
core.toPhysicalRow(row) ⇒ number
Translate visual row index into physical.
This method is useful when you want to retrieve physical row index based on a visual index which can be reordered, moved or trimmed.
| Param | Type | Description |
|---|---|---|
| row | number | Visual row index. |
Returns: number - Returns physical row index.
toTableElement
core.toTableElement() ⇒ HTMLTableElement
Converts instance into HTMLTableElement.
Since: 7.1.0
toVisualColumn
core.toVisualColumn(column) ⇒ number
Translate physical column index into visual.
This method is useful when you want to retrieve visual column index which can be reordered, moved or trimmed based on a physical index.
| Param | Type | Description |
|---|---|---|
| column | number | Physical column index. |
Returns: number - Returns visual column index.
toVisualRow
core.toVisualRow(row) ⇒ number
Translate physical row index into visual.
This method is useful when you want to retrieve visual row index which can be reordered, moved or trimmed based on a physical index.
| Param | Type | Description |
|---|---|---|
| row | number | Physical row index. |
Returns: number - Returns visual row index.
unlisten
core.unlisten()
Stop listening to keyboard input on the document body. Calling this method makes the Handsontable inactive for any keyboard events.
updateData
core.updateData(data, [source])
The updateData() method replaces Handsontable’s data with a new dataset.
The updateData() method:
- Keeps cells’ states (e.g. cells’ formatting and cells’
readOnlystates) - Keeps rows’ states (e.g. row order)
- Keeps columns’ states (e.g. column order)
To replace Handsontable’s data and reset states, use the loadData() method.
Read more:
Emits: Hooks#event:beforeUpdateData, Hooks#event:afterUpdateData, Hooks#event:afterChange
Since: 11.1.0
| Param | Type | Description |
|---|---|---|
| data | Array | An array of arrays, or an array of objects, that contains Handsontable’s data. |
| [source] | string | optional The source of the updateData() call. |
updateSettings
core.updateSettings(settings, [init])
Use it if you need to change configuration after initialization. The settings argument is an object containing the changed
settings, declared the same way as in the initial settings object.
Note, that although the updateSettings method doesn’t overwrite the previously declared settings, it might reset
the settings made post-initialization. (for example - ignore changes made using the columnResize feature).
Passing columns inside the settings object resets the states corresponding to rows and columns
(for example, row/column sequence, column width, row height, frozen columns etc.). Passing data does not reset these states.
After initialization, passing data calls updateData() internally.
The resulting beforeUpdateData and
afterUpdateData hooks receive "updateSettings" as their
source, while afterChange receives null as its changes
argument and "updateData" as its source. If you call updateSettings with data inside
afterChange, check the hook’s source to prevent an infinite loop.
Cell meta set imperatively through [[setCellMeta]] (for example, by the user or the context menu) is preserved across
updateSettings, even when settings includes cell, cells, or columns. On a direct conflict, a value re-stated
through the declarative cell option takes precedence over the preserved imperative value.
Cell meta set imperatively through [[setCellMeta]] (for example, by the user or the context menu) is preserved across
updateSettings, even when settings includes cell, cells, or columns. On a direct conflict, a value re-stated
through the declarative cell option takes precedence over the preserved imperative value.
When [[Hooks#hasExternalDataSource]] is true, Handsontable clears and rebinds the placeholder dataset only during
initialization or when settings includes data or dataProvider. Other keys alone (for example height) do not clear loaded rows.
If only columns changes, the column map is rebuilt without clearing rows.
Emits: Hooks#event:afterCellMetaReset, Hooks#event:afterUpdateSettings
Example
hot.updateSettings({ contextMenu: true, colHeaders: true, fixedRowsTop: 2});| Param | Type | Default | Description |
|---|---|---|---|
| settings | object | A settings object (see Options). Only provide the settings that are changed, not the whole settings object that was used for initialization. | |
| [init] | boolean | false | optional Internally used during initialization. |
useTheme
core.useTheme(themeName)
Use the theme specified by the provided name.
Since: 15.0.0
| Param | Type | Description |
|---|---|---|
| themeName | string boolean undefined | The name of the theme to use. |
validateCell
core.validateCell(value, cellProperties, callback, source)
Validate a single cell.
| Param | Type | Description |
|---|---|---|
| value | string number | The value to validate. |
| cellProperties | object | The cell meta which corresponds with the value. |
| callback | function | The callback function. |
| source | string | The string that identifies source of the validation. |
validateCells
core.validateCells([callback])
Validates every cell in the data set, using a validator function configured for each cell.
Doesn’t validate cells that are currently trimmed, hidden, or filtered, as such cells are not included in the data set until you bring them back again.
After the validation, the callback function is fired, with the valid argument set to:
truefor valid cellsfalsefor invalid cells
Example
hot.validateCells((valid) => { if (valid) { // ... code for validated cells }})| Param | Type | Description |
|---|---|---|
| [callback] | function | optional The callback function. |
validateColumns
core.validateColumns([columns], [callback])
Validates columns using their validator functions and calls callback when finished.
If one of the cells is invalid, the callback will be fired with 'valid' arguments as false - otherwise it
would equal true.
Example
hot.validateColumns([3, 4, 5], (valid) => { if (valid) { // ... code for validated columns }})| Param | Type | Description |
|---|---|---|
| [columns] | Array | optional Array of validation target visual columns indexes. |
| [callback] | function | optional The callback function. |
validateRows
core.validateRows([rows], [callback])
Validates rows using their validator functions and calls callback when finished.
If one of the cells is invalid, the callback will be fired with 'valid' arguments as false - otherwise it
would equal true.
Example
hot.validateRows([3, 4, 5], (valid) => { if (valid) { // ... code for validated rows }})| Param | Type | Description |
|---|---|---|
| [rows] | Array | optional Array of validation target visual row indexes. |
| [callback] | function | optional The callback function. |