- Overview
- Documents
- Demos
Handsontable is a minimalistic approach to Excel-like table editor in HTML & jQuery. Requires jQuery 1.9+ or 2.0+ (may work with 1.7+ too, but there are known issues with IE10).
Runs in IE 8-11, Firefox, Chrome, Safari and Opera.
Usage
First, include all the dependencies. All the files that you need (apart from jQuery) are in the dist\ directory:
<script src="../lib/jquery.min.js"></script> <script src="dist/jquery.handsontable.full.js"></script> <link rel="stylesheet" media="screen" href="dist/jquery.handsontable.full.css">
Then, run handsontable() constructor on an empty div. After that, load some data if you wish:
<div id="dataTable"></div> <script> var data = [ ["", "Kia", "Nissan", "Toyota", "Honda"], ["2008", 10, 11, 12, 13], ["2009", 20, 11, 14, 13], ["2010", 30, 15, 12, 13] ]; $("#dataTable").handsontable({ data: data, startRows: 6, startCols: 8 }); </script>
Constructor options
Constructor options are applied using an object literal passed as a first argument to the Handsontable constructor. Example:
$('div#example1').handsontable({ data: myArray, width: 400, height: 300 })
List of options that are interpreted by handsontable() constructor:
-
data : Array of Arrays (default [ [] ])
data : Array of Objects
data : Function - Initial data source that will be bound to the data grid by reference (editing data grid alters the data source. See Understanding binding as reference
-
width : Number (default undefined)
width : Function - Width of the grid. Can be a number or a function that returns a number
-
height : Number (default undefined)
height : Function - Height of the grid. Can be a number or a function that returns a number
- minRows : Number (default 0)
- Minimum number of rows. At least that many of rows will be created during initialization
- minCols : Number (default 0)
- Minimum number of columns. At least that many of columns will be created during initialization
- maxRows : Number (default Infinity)
- Maximum number of rows
- maxCols : Number (default Infinity)
- Maximum number of columns
- startRows : Number (default 5)
- Initial number of rows. Notice: This option only has effect in Handsontable constructor and only if data option is not provided
- startCols : Number (default 5)
- Initial number of rows. Notice: This option only has effect in Handsontable constructor and only if data option is not provided
-
rowHeaders : Boolean (default false)
rowHeaders : Array [1, 2, 3, ...]
rowHeaders : Function function(index) { return ... } - Setting true or false will enable or disable the default row headers (1, 2, 3). You can also define an array ['One', 'Two', 'Three', ...] or a function to define the headers. If a function is set the index of the rowis passed as a parameter.
-
colHeaders: Boolean (default false)
colHeaders : Array [A, B, C, ...]
colHeaders : Function function(index) { return ... } - Setting true or false will enable or disable the default column headers (A, B, C). You can also define an array ['One', 'Two', 'Three', ...] or a function to define the headers. If a function is set the index of the column is passed as a parameter.
-
colWidths : Array (default [50, ..])
colWidths : Function (index)
colWidths : Number
colWidths : String - Defines column widths in pixels. Accepts number, string (that will be converted to number), array of numbers (if you want to define column width separately for each column) or a function (if you want to set column width dynamically on each render)
- columns : Array (default undefined)
-
Defines the cell properties and data binding for certain columns. Notice: Using this option sets a fixed number of columns (options startCols, minCols, maxCols will be ignored).
See Options section below for more detailed explanation
See demo/datasources.html for examples - cells : Function(row, col, prop) (default undefined)
-
Defines the cell properties for given row, col, prop coordinates
See Cells section below for more detailed explanation - dataSchema : Object (default like the first data row - Array or Object)
- Defines the structure of a new row when data source is an object. See demo/datasources.html for examples
- minSpareRows : Number (default 0)
- When set to 1 (or more), Handsontable will add a new row at the end of grid if there are no more empty rows
- minSpareCols : Number (default 0)
- When set to 1 (or more), Handsontable will add a new column at the end of grid if there are no more empty columns
- multiSelect : Boolean (default true)
- If true, selection of multiple cells using keyboard or mouse is allowed
-
fillHandle : Boolean (default true)
fillHandle : String - Defines if the fill handle (drag-down and copy-down) functionality should be enabled. Possible values: true (to enable in all directions), "vertical" or "horizontal" (to enable in one direction), false (to disable completely).
-
contextMenu : Boolean (default false)
contextMenu : Array -
Defines if the right-click context menu should be enabled. Context menu allows to create new row or column at any place in the grid. Possible values: true (to enable basic options), false (to disable completely) or array of any available strings: ["row_above", "row_below", "col_left", "col_right", "remove_row", "remove_col", "undo", "redo", "sep1", "sep2", "sep3"].
See demo/contextmenu.html for examples - undo : Boolean (default true)
- If true, undo/redo functionality is enabled
- outsideClickDeselects : Boolean (default true)
- If true, mouse click outside the grid will deselect the current selection
- enterBeginsEditing : Boolean (default true)
- If true, ENTER begins editing mode (like Google Docs). If false, ENTER moves to next row (like Excel) and adds new row if necessary. TAB adds new column if necessary.
-
enterMoves : Object (default {row: 1, col: 0})
enterMoves : Function(event) - Defines cursor move after ENTER is pressed (SHIFT+ENTER uses negative vector). Can be an object or a function that returns an object. The event argument passed to the function is a jQuery.Event object received after a ENTER key has been pressed. This event object can be used to check whether user pressed ENETR or SHIFT + ENTER.
-
tabMoves : Object (default {row: 0, col: 1})
tabMoves : Function - Defines cursor move after TAB is pressed (SHIFT+TAB uses negative vector). Can be an object or a function that returns an object. The event argument passed to the function is a jQuery.Event object received after a TAB key has been pressed. This event object can be used to check whether user pressed TAB or SHIFT + TAB.
- autoWrapRow : Boolean (default false)
- If true, pressing TAB or right arrow in the last column will move to first column in next row
- autoWrapCol : Boolean (default false)
- If true, pressing ENTER or down arrow in the last row will move to first row in next column
- autoComplete : Array (default undefined)
-
Autocomplete definitions.
See demo/autocomplete.html for examples and definitions. - copyRowsLimit : Number (default 1000)
- Maximum number of rows than can be copied to clipboard using CTRL+C
- copyColsLimit : Number (default 1000)
- Maximum number of columns than can be copied to clipboard using CTRL+C
- pasteMode : String (default "overwrite")
-
Defines paste (CTRL+V) behavior. Default value "overwrite" will paste clipboard value over current selection.
When set to "shift_down", clipboard data will be pasted in place of current selection, while all selected cells are moved down.
When set to "shift_right", clipboard data will be pasted in place of current selection, while all selected cells are moved right. - stretchH : String (default "hybrid")
- Column stretching mode. Possible values: "none", "hybrid", "last", "all". Hybrid mode works as "none" where there is no horizontal scrollbar, and as `last` when the horizontal scrollbar is present.
- isEmptyRow : Function(row) (default undefined)
- Lets you overwrite the default isEmptyRow method
- isEmptyCol : Function(col) (default undefined)
- Lets you overwrite the default isEmptyCol method
- manualColumnResize : Boolean (default false)
- Turn on Manual column resize
- manualColumnMove : Boolean (default false)
- Turn on Manual column move
- columnSorting : Boolean (default false)
- Turn on Column sorting
- persistentState : Boolean (default false)
- Turn on saving the state of column sorting, columns positions and columns sizes in local storage. For more information see How to save data localy.
- currentRowClassName : String (default undefined)
- Class name for all visible rows in current selection
- currentColClassName : String (default undefined)
- Class name for all visible columns in current selection
Column options
Column options are applied as columns property passed to the Handsontable constructor. Example:
$('div#example1').handsontable({ columns: [ { //column options for the first column type: 'numeric', format: '0,0.00 $' }, { //column options for the second column type: 'text', readOnly: true } ] })
The table below presents some, but not all column options. Additional options may exist, depending on the cell renderer/editor:
- type : String (default "text")
- Shortcut to define combination of cell renderer and editor for the column. Possible values: text, numeric, date, checkbox, autocomplete,handsontable.
- renderer : String|Function (default "text")
-
String or rendering function.
String may be one of the following predefined values: autocomplete, checkbox, text, numeric.
Function will receive the following arguments: function(instance, TD, row, col, prop, value, cellProperties) {}
You can map your own function to a string like this: Handsontable.cellLookup.renderer.myRenderer = myRenderer - editor : String|Function (default "text")
-
String or rendering function.
String may be one of the following predefined values: autocomplete, checkbox, text, date, handsontable.
Function will receive the following arguments: function(instance, td, row, col, prop, value, cellProperties) {}
You can map your own function to a string like this: Handsontable.cellLookup.renderer.myEditor = myEditor -
validator (value: Mixed, callback: Function)
validator : RegExp Object -
A usually small function or regular expression that validates the input. After you determine if the input is valid, execute callback(true) or callback(false) to proceed with the execution.
In function, this binds to cellProperties.
version added: 0.9.5 - allowInvalid : Boolean (default true)
-
If set to true, cells will accept value that is marked as invalid by cell validator, with a background color automatically applied using CSS class htInvalid.
If set to false, cells will not accept invalid value.
version added: 0.9.5 - readOnly : Boolean (default false)
- Make cell read only.
- copyable : Boolean (default true)
-
Make cell copyable (pressing CTRL+C on your keyboard moves its value to system clipboard).
Note: this setting is false by default for cells with type password.
version added: 0.10.2
Cell options
Any constructor or column option may be overwritten for a particular cell (row/column combination), using cells function property to the Handsontable constructor. Example:
$('div#example1').handsontable({ cells: function (row, col, prop) { var cellProperties = {} if(row === 0 && col === 0) { cellProperties.readOnly = true; } return cellProperties; } })
Methods
This document describes public methods of Handsontable 0.9
After Handsontable is constructed, you can modify the grid behavior using the available public methods.
How to call methods
These are 3 equal ways to call a Handsontable method:
//all following examples assume that you constructed Handsontable like this $('div#example1').handsontable(options); //now, to use setDataAtCell method, you can either: //1. get the instance using jQuery wrapper and then call method on the instance (RECOMMENDED) var ht = $('#example1').handsontable('getInstance'); ht.setDataAtCell(0, 0, 'new value'); //2. OR, call the method using jQuery wrapper (short but hard to read) $('#example1').handsontable('setDataAtCell', 0, 0, 'new value'); //3. OR, get the instance using $.data and then call method on the instance (obsolete) var ht = $('#example1').data('handsontable'); ht.setDataAtCell(0, 0, 'new value');
Methods
This is the list of available public methods, grouped by their functionality:
General methods
- updateSettings (options: Object)
- Use it if you need to change configuration after initialization
- loadData (data: Array)
- Reset all cells in the grid to contain data from the data array
- render ()
- Rerender the table
- destroy ()
- Remove grid from DOM
- validateCells (callback: Function)
- Validates all cells using their validator functions and calls callback when finished. Does not render the view.
Get data methods
-
getData ()
getData (row: Number, col: Number, row2: Number, col2: Number) - Return the current data object (the same that was passed by data configuration option or loadData method). Optionally you can provide cell range row, col, row2, col2 to get only a fragment of grid data
- getDataAtCell (row: Number, col: Number)
- Return cell value at row, col. Col is the index of visible column (note that if columns were reordered, the current order will be used)
- getDataAtRowProp (row: Number, prop: String)
- Same as above, except instead of col, you provide name of the object property (e.g. 'first.name')
- getDataAtRow (row: Number)
-
Returns a single row from the data source (array or object, depending on what you have).
version added: 0.9-beta2 - getDataAtCol (col: Number)
-
Returns array of column values from the data source.
version added: 0.9-beta2 - getDataAtProp (prop: String)
-
Given the object property name (e.g. 'first.name'), returns array of column values from the data source.
version added: 0.9-beta2
Set data methods
-
setDataAtCell (row: Number, col: Number, value: Mixed, source: String (Optional))
setDataAtCell (changes: Array, source: String (Optional)) - Set new value to a cell. To change many cells at once, pass an array of changes in format [ [row, col, value], ... ] as the only parameter. col is the index of visible column (note that if columns were reordered, the current order will be used). source is a flag for before/afterChange events. If you pass only array of changes then source could be set as second parameter.
-
setDataAtRowProp (row: Number, prop: String, value: Mixed, source: String (Optional))
setDataAtRowProp (changes: Array, source: String (Optional)) - Same as above, except instead of col, you provide name of the object property (e.g. [0, 'first.name', 'Jennifer']).
- populateFromArray (row: Number, col: Number, input: Array, endRow: Number, endCol: Number, source: String (Optional), populateMethod: String (Optional))
-
Populate cells at position with 2D input array (e.g. [ [1, 2], [3, 4] ]).
Use endRow, endCol when you want to cut input when certain row is reached.
Optional source parameter (default value "populateFromArray") is used to identify this call in the resulting events (beforeChange, afterChange).
Optional populateMethod parameter (default value "overwrite", possible values "shift_down" and "shift_right") has the same effect as pasteMethod option (see Options page)
version added: 0.9.0 - spliceCol (col: Number, index: Number, amount: Number, element1: Mixed, ..., elementN: Mixed)
-
Adds/removes data from the column. This function works is modelled after Array.splice. Parameter col is the index of column in which do you want to do splice. Parameter index is the row index at which to start changing the array. If negative, will begin that many elements from the end. Parameter amount, is the number of old array elements to remove. If the amount is 0, no elements are removed. Fourth and further parameters are the elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array.
version added: 0.9-beta2
Alter grid (create, remove rows and columns)
- alter ('insert_row', index: Number, amount: Number (Optional), source: String (Optional))
- Insert new row(s) above the row at given index. If index is null or undefined, the new row will be added after the current last row. Default amount equals 1
- alter ('insert_col', index: Number, amount: Number (Optional), source: String (Optional))
- Insert new column(s) before the column at given index. If index is null or undefined, the new column will be added after the current last column. Default amount equals 1
- alter ('remove_row', index: Number, amount: Number (Optional), source: String (Optional))
- Remove the row(s) at given index. Default amount equals 1
- alter ('remove_col', index: Number, amount: Number (Optional), source: String (Optional))
- Remove the column(s) at given index. Default amount equals 1
Cell methods
- getCell (row: Number, col: Number)
-
Returns TD element for given row, col if it is rendered on screen.
Returns null if the TD is not rendered on screen (probably because that part of table is not visible). - getCellMeta (row: Number, col: Number)
- Return cell properties for given row, col coordinates
- destroyEditor (revertOriginal: Boolean (Optional))
- Destroys current editor, renders and selects current cell. If revertOriginal == false, edited data is saved. Otherwise previous value is restored
Selection methods
- selectCell (row: Number, col: Number, row2: Number, col2: Number, scrollToSelection: Boolean (Optional))
- Select cell row, col or range finishing at row2, col2. By default, viewport will be scrolled to selection
- deselectCell ()
- Deselect current selection
- getSelected ()
- Return index of the currently selected cells as an array [startRow, startCol, endRow, endCol]. Start row and start col are the coordinates of the active cell (where the selection was started).
Grid information methods
- countRows ()
- Returns total number of rows in the grid
- countCols ()
- Returns total number of columns in the grid
- colToProp (column: Number)
- Returns property name that corresponds with the given column index
- rowOffset ()
- Returns index of first visible row
- colOffset ()
- Returns index of first visible column
- countVisibleRows ()
- Returns number of visible rows
- countVisibleCols ()
- Returns number of visible columns
- countEmptyRows (ending: Boolean (Optional))
- Returns number of empty rows. If the optional ending parameter is true, returns number of empty rows at the bottom of the table
- countEmptyCols (ending: Boolean (Optional))
- Returns number of empty columns. If the optional ending parameter is true, returns number of empty columns at right hand edge of the table
- isEmptyRow (row: Number)
- Returns true if the row at the given index is empty, false otherwise
- isEmptyCol (col: Number)
- Returns true if the column at the given index is empty, false otherwise
- getRowHeader (row: Number)
- Returns array of row headers (if they are enabled). If param row given, return header at given row as string
- getColHeader (col: Number)
- Returns array of col headers (if they are enabled). If param col given, return header at given col as string
- propToCol (property: String)
- Returns column index that corresponds with the given property
Undo/redo methods
- clearUndo ()
- Clear undo history
- isUndoAvailable ()
- Return true if undo can be performed, false otherwise
- isRedoAvailable ()
- Return true if redo can be performed, false otherwise
- undo ()
- Undo last edit
- redo ()
- Redo edit (used to reverse an undo)
Plugin specific methods
- sort (column: Number, order: Boolean)
- Sorts table content by cell values in given column, using order. column is a zero-based column index. Order of sorting can be either ascending (order = true) or descending (order = false).
Events
This document describes callbacks & plugin hooks in Handsontable 0.9
Handsontable events are the common interface that function in 2 ways: as callbacks and as plugin hooks.
Using events as callbacks (better example on pages Callbacks and Ajax):
$('div#example1').handsontable({ afterChange: function(changes, source) { $.ajax({ url: "save.php", data: change }); } });
Using events as plugin hooks:
$('#example1').handsontable({ 'myPlugin': true }); $('#example2').handsontable({ 'myPlugin': false }); //global hook Handsontable.PluginHooks.add('afterChange', function() { if(this.getSettings().myPlugin) { //function body - will only run in #example1 } }); //local hook (has same effect as a callback) $('#example2').handsontable('getInstance').addHook('afterChange', function() { //function body - will only run in #example2 });
Events available since 0.8
- onSelection (r: Number, p: Number, r2: Number, p2: Number)
- Deprecated! Now event is called afterSelection
- onSelectionByProp (r: Number, p: String, r2: Number, p2: String)
- Deprecated! Now event is called afterSelectionByProp
- onSelectionEnd (r: Number, c: Number, r2: Number, c2: Number)
- Deprecated! Now event is called afterSelectionEnd
- onSelectionEndByProp (r: Number, p: String, r2: Number, p2: String)
- Deprecated! Now event is called afterSelectionEndByProp
- onBeforeChange (changes: Array, source: String)
- Deprecated! Now event is called beforeChange
- onChange (changes: Array, source: String)
- Deprecated! Now event is called afterChange.
- onCopyLimit (selectedRowsCount: Number, selectedColsCount: Number, copyRowsLimit: Number, copyColsLimit: Number)
- Deprecated! Now event is called afterCopyLimit.
Events available in 0.9
- beforeInit ()
-
Callback fired before Handsontable instance is initiated.
Note: this can be set only by global PluginHooks instance. - beforeRender (isForced: Boolean)
-
Callback fired before Handsontable table is rendered. Parameters:
- isForced is true if rendering was triggered by a change of settings or data; or false if rendering was triggered by scrolling or moving selection.
- beforeChange (changes: Array, source: String)
-
Callback fired before one or more cells is changed. Its main purpose is to alter changes silently before input. Parameters:
-
changes is a 2D array containing information about each of the edited cells [ [row, prop, oldVal, newVal], ... ].
- To disregard a single change, set changes[i] to null or remove it from array using changes.splice(i, 1).
- To alter a single change, overwrite the desired value to changes[i][3].
- To cancel all edit, return false from the callback or set array length to 0 (changes.length = 0).
- source is the name of a source of changes.
-
changes is a 2D array containing information about each of the edited cells [ [row, prop, oldVal, newVal], ... ].
- beforeColumnSort (column: Number, order: Boolean)
- Callback fired before sorting the table. The column argument is a relative (displayed) index of a column that is about to be sorted. To get the absolute column index, just add the current column offset. You can get the offset by using colOffset() method.
- beforeGet (var: Object)
- Callback fired before getting single value from the data source array.
- beforeSet (var: Object)
- Callback fired before setting single value from the data source array
- beforeGetCellMeta (row: Number, col: Number, cellProperties: Object)
- Callback fired before getting cell settings.
- beforeAutofill (start: Object, end: Object, data: Array)
-
- start is an object containing information about first filled cell: { row : 2, col : 0 }.
- end is an object containing information about last filled cell: { row : 4, col : 1 }.
- data is an 2D array containing information about fill pattern: [ ["1", "Ted"], ["1", "John"] ].
- beforeKeyDown (event: Object)
-
Callback fired before keydown event is handled. It can be used to overwrite default key bindings. Caution - in your beforeKeyDown handler you need to call event.stopImmediatePropagation() to prevent default key behavior.
version added: 0.9.0 - beforeValidate (value: Mixed, row: Number, prop: String, source: String)
-
A plugin hook executed before validator function, only if validator function is defined. This can be used to manipulate value of changed cell before it is applied to the validator function. NOTICE: this will not affect values of changes. This will change value ONLY for validation!
version added: 0.9.5 - afterInit ()
- Callback fired after Handsontable instance is initiated.
- afterLoadData ()
- Callback fired after new data is loaded (by loadData method) into the data source array.
- afterRender (isForced: Boolean)
-
Callback fired after Handsontable table is rendered. Parameters:
- isForced is true if rendering was triggered by a change of settings or data; or false if rendering was triggered by scrolling or moving selection.
- afterChange (changes: Array, source: String)
-
Callback fired after one or more cells is changed. Its main use case is to save the input. Parameters:
- changes is a 2D array containing information about each of the edited cells [ [row, prop, oldVal, newVal], ... ].
- source is one of the strings: "alter", "empty", "edit", "populateFromArray", "loadData", "autofill", "paste".
- afterColumnSort (column: Number, order: Boolean)
- Callback fired after sorting the table. The column argument is a relative (displayed) index of a column that is about to be sorted. To get the absolute column index, just add the current column offset. You can get the offset by using colOffset() method.
- afterSelection (r: Number, c: Number, r2: Number, c2: Number)
-
Callback fired while one or more cells are being selected (on mouse move). Parameters:
- r selection start row
- c selection start column
- r2 selection end row
- c2 selection end column
- afterSelectionByProp (r: Number, p: String, r2: Number, p2: String)
- The same as above, but data source object property name is used instead of the column number
- afterSelectionEnd (r: Number, c: Number, r2: Number, c2: Number)
-
Callback fired after one or more cells are selected (on mouse up). Parameters:
- r selection start row
- c selection start column
- r2 selection end row
- c2 selection end column
- afterSelectionEndByProp (r: Number, p: String, r2: Number, p2: String)
- The same as above, but data source object property name is used instead of the column number
- afterDeselect ()
- Event called when current cell is deselected.
- afterGetCellMeta (row: Number, col: Number, cellProperties: Object)
- Callback fired after getting cell settings.
- afterGetColHeader (col: Number, TH: DOM Node)
- Callback fired after getting info about column header.
- afterGetColWidth (col: Number, response: Object)
- Callback fired after calculating column width.
- afterDestroy ()
- Callback fired after destroing Handsontable instance.
- afterCreateRow (index: Number, amount: Number)
-
Callback is fired when a new row is created.
- index represents the index of first newly created row in the data source array.
- amount number of newly created rows in the data source array.
- afterCreateCol (index: Number, amount: Number)
-
Callback is fired when a new column is created.
- index represents the index of first newly created column in the data source array.
- amount number of newly created columns in the data source array.
- beforeRemoveRow (index: Number, amount: Number)
-
Callback is fired when one or more rows are about to be removed. Parameters:
- index is an index of starter row.
- amount is an anount of rows to be removed.
- afterRemoveRow (index: Number, amount: Number)
-
Callback is fired when one or more rows are removed. Parameters:
- index is an index of starter row.
- amount is an anount of removed rows.
- beforeRemoveCol (index: Number, amount: Number)
-
Callback is fired when one or more columns are about to be removed. Parameters:
- index is an index of starter column.
- amount is an anount of columns to be removed.
- afterRemoveCol (index: Number, amount: Number)
-
Callback is fired when one or more columns are removed. Parameters:
- index is an index of starter column.
- amount is an anount of removed columns.
- afterColumnResize (col: Number, size: Number)
- Callback is fired after changing column size.
- afterColumnMove (oldIndex: Number, newIndex: Number)
- Callback is fired after changing column placement.
- afterCopyLimit (selectedRowsCount: Number, selectedColsCount: Number, copyRowsLimit: Number, copyColsLimit: Number)
- Callback fired if copyRowsLimit or copyColumnsLimit was reached.
- afterValidate (isValid: Boolean, value: Mixed, row: Number, prop: String, source: String)
-
A plugin hook executed after validator function, only if validator function is defined. Validation result is the first parameter. This can be used to determinate if validation passed successfully or not. You can cancel current change by returning false.
version added: 0.9.5
Examples and how-to's
Appearance
Integration