Handsontable is a comprehensive JavaScript data grid component that provides spreadsheet-like functionality for web applications. It offers extensive cell editing capabilities, data grid features like sorting and filtering, virtualization for performance with large datasets, and built-in accessibility support. The library integrates seamlessly with React, Angular, and Vue through dedicated wrapper components.
npm install handsontableimport Handsontable from "handsontable";
import "handsontable/dist/handsontable.full.min.css";For CommonJS:
const Handsontable = require("handsontable");
require("handsontable/dist/handsontable.full.min.css");For specific components:
import { CellCoords, CellRange } from "handsontable";
import { NumericEditor } from "handsontable/editors";
import { checkboxRenderer } from "handsontable/renderers";
import { numericValidator } from "handsontable/validators";import Handsontable from "handsontable";
import "handsontable/dist/handsontable.full.min.css";
// Create a data grid
const container = document.getElementById('hot-container');
const data = [
['Tesla', 'Model S', 2017, 100000, true],
['Tesla', 'Model 3', 2018, 50000, true],
['Toyota', 'Prius', 2019, 24000, false]
];
const hot = new Handsontable(container, {
data: data,
columns: [
{ title: 'Brand', type: 'text' },
{ title: 'Model', type: 'text' },
{ title: 'Year', type: 'numeric' },
{ title: 'Price', type: 'numeric', numericFormat: { pattern: '$0,0.00' } },
{ title: 'Electric', type: 'checkbox' }
],
colHeaders: true,
rowHeaders: true,
contextMenu: true,
manualColumnResize: true,
manualRowResize: true,
columnSorting: true,
filters: true
});Handsontable is built around several key architectural components:
Essential data grid functionality including initialization, data management, and basic interactions. The Core class provides 180+ methods for comprehensive grid control.
/**
* Main Handsontable constructor
* @param rootElement - HTML element to render the grid
* @param userSettings - Configuration options for the grid
*/
function Handsontable(rootElement: HTMLElement, userSettings: GridSettings): Core;
/**
* Alternative Core constructor
* @param rootElement - HTML element container
* @param userSettings - Grid configuration options
*/
Handsontable.Core: (rootElement: HTMLElement, userSettings?: GridSettings) => Core;
// Key data management methods
interface Core {
// Data operations
loadData(data: any[][], source?: ChangeSource): void;
updateData(data: any[][], source?: ChangeSource): void;
getData(row?: number, col?: number, row2?: number, col2?: number): any[][];
getDataAtCell(row: number, col: number): CellValue;
getDataAtRow(row: number): any[];
getDataAtCol(col: number): any[];
setDataAtCell(row: number, col: number, value: CellValue, source?: ChangeSource): void;
// Selection methods
selectAll(): void;
selectCell(row: number, col: number, endRow?: number, endCol?: number, scrollToCell?: boolean): boolean;
selectCells(coordsArray: [number, number, number, number][]): void;
getSelected(): [number, number, number, number][] | undefined;
getSelectedRange(): CellRange[] | undefined;
deselectCell(): void;
// Grid dimensions
countRows(): number;
countCols(): number;
countVisibleRows(): number;
countVisibleCols(): number;
// Rendering and lifecycle
render(): void;
destroy(): void;
updateSettings(settings: GridSettings): void;
getSettings(): GridSettings;
// Data manipulation
alter(action: 'insert_row' | 'insert_col' | 'remove_row' | 'remove_col', index: number, amount?: number, source?: ChangeSource): void;
clear(): void;
// Validation
validateCell(value: CellValue, cellProperties: CellProperties, callback: (valid: boolean) => void): void;
validateCells(callback?: (valid: boolean) => void): void;
// Undo/Redo
undo(): void;
redo(): void;
isUndoAvailable(): boolean;
isRedoAvailable(): boolean;
}
interface GridSettings {
data?: any[][];
columns?: ColumnSettings[];
colHeaders?: boolean | string[] | ((col: number) => string);
rowHeaders?: boolean | string[] | ((row: number) => string);
width?: number | string;
height?: number | string;
minRows?: number;
minCols?: number;
maxRows?: number;
maxCols?: number;
readOnly?: boolean;
contextMenu?: boolean | ContextMenuSettings;
// Plugin configurations
columnSorting?: boolean | ColumnSortingSettings;
filters?: boolean | FiltersSettings;
manualColumnResize?: boolean;
manualRowResize?: boolean;
autoColumnSize?: boolean | AutoColumnSizeSettings;
autoRowSize?: boolean | AutoRowSizeSettings;
[key: string]: any;
}
interface ColumnSettings {
type?: string;
title?: string;
data?: string | number | ((row: any, value?: any) => any);
readOnly?: boolean;
width?: number;
className?: string;
renderer?: string | RendererType;
editor?: string | EditorType;
validator?: string | ValidatorType;
numericFormat?: NumericFormatOptions;
dateFormat?: string;
source?: string[] | ((query: string, callback: (items: string[]) => void) => void);
[key: string]: any;
}
interface ContextMenuSettings {
items?: object;
callback?: (key: string, selection: object, clickEvent: MouseEvent) => void;
}
interface NumericFormatOptions {
pattern?: string;
culture?: string;
}
interface AutoColumnSizeSettings {
syncLimit?: number;
}
interface AutoRowSizeSettings {
syncLimit?: number;
}Comprehensive cell type system with built-in editors for different data types including text, numeric, date, dropdown, and custom types.
// Built-in cell types
const cellTypes = {
text: TextCellType,
numeric: NumericCellType,
checkbox: CheckboxCellType,
date: DateCellType,
dropdown: DropdownCellType,
autocomplete: AutocompleteCellType,
password: PasswordCellType,
select: SelectCellType,
time: TimeCellType,
handsontable: HandsontableCellType
};
// Registry functions
function registerCellType(name: string, cellType: CellType): void;
function getCellType(name: string): CellType;Advanced data grid functionality including sorting, filtering, column/row manipulation, and data operations.
// Plugin configuration examples
interface ColumnSortingSettings {
enabled?: boolean;
indicator?: boolean;
headerAction?: boolean;
compareFunctionFactory?: (sortOrder: string, columnMeta: object) => Function;
}
interface FiltersSettings {
enabled?: boolean;
indicators?: boolean;
dropdownMenu?: boolean | object;
}User interface components and interaction features including context menus, selection handling, and accessibility.
// Selection and coordinates
class CellCoords {
constructor(row: number, col: number);
row: number;
col: number;
isEqual(coords: CellCoords): boolean;
isSouthEastOf(coords: CellCoords): boolean;
isNorthWestOf(coords: CellCoords): boolean;
}
class CellRange {
constructor(highlight: CellCoords, from?: CellCoords, to?: CellCoords);
highlight: CellCoords;
from: CellCoords;
to: CellCoords;
getAll(): CellCoords[];
}Multi-language support with built-in translations and custom language dictionary registration.
// Language functions
function registerLanguageDictionary(languageCode: string, dictionary: LanguageDictionary): void;
function getLanguageDictionary(languageCode: string): LanguageDictionary;
function getTranslatedPhrase(languageCode: string, dictionaryKey: string, argumentsArray?: any[]): string;
interface LanguageDictionary {
[key: string]: string | ((...args: any[]) => string);
}Comprehensive utility functions for data manipulation, DOM operations, and common programming tasks accessible via
Handsontable.helperHandsontable.dom// Handsontable.helper namespace contains all general utilities
interface HandsontableHelper {
// Array manipulation utilities
arrayEach<T>(array: T[], iteratee: (value: T, index: number) => boolean | void): void;
arrayMap<T, U>(array: T[], iteratee: (value: T, index: number) => U): U[];
arrayFilter<T>(array: T[], predicate: (value: T, index: number) => boolean): T[];
arrayReduce<T, U>(array: T[], iteratee: (accumulator: U, value: T, index: number) => U, accumulator: U): U;
// String utilities
toUpperCaseFirst(string: string): string;
substitute(template: string, object: object): string;
// Number utilities
rangeEach(rangeFrom: number, rangeTo: number, iteratee: (index: number) => boolean | void): void;
// Object utilities
objectEach<T>(object: T, iteratee: (value: any, key: string, object: T) => boolean | void): void;
deepClone<T>(object: T): T;
deepExtend<T>(...objects: any[]): T;
// Data transformation utilities
pivot(array: any[][]): any[][];
// Date utilities
getNormalizedDate(dateString: string): Date;
// Browser detection utilities
isIE(): boolean;
isChrome(): boolean;
isSafari(): boolean;
isMobileBrowser(): boolean;
// Feature detection utilities
isRightClick(event: MouseEvent): boolean;
isLeftClick(event: MouseEvent): boolean;
[key: string]: any;
}
// Handsontable.dom namespace contains DOM utilities
interface HandsontableDOM {
// Element manipulation
addClass(element: HTMLElement, className: string): void;
removeClass(element: HTMLElement, className: string): void;
hasClass(element: HTMLElement, className: string): boolean;
empty(element: HTMLElement): void;
// Element positioning and dimensions
offset(element: HTMLElement): { top: number; left: number };
getScrollTop(element: HTMLElement): number;
getScrollLeft(element: HTMLElement): number;
outerWidth(element: HTMLElement): number;
outerHeight(element: HTMLElement): number;
// Event handling
addEvent(element: HTMLElement, event: string, callback: Function): void;
removeEvent(element: HTMLElement, event: string, callback: Function): void;
[key: string]: any;
}
// Access via namespaces
declare const helper: HandsontableHelper;
declare const dom: HandsontableDOM;Modular plugin architecture with 35+ built-in plugins for extending grid functionality.
// Plugin registry system
function registerPlugin(name: string, pluginClass: typeof BasePlugin): void;
function getPlugin(name: string): typeof BasePlugin;
// Base plugin class
class BasePlugin {
constructor(hotInstance: Core);
static get PLUGIN_KEY(): string;
isEnabled(): boolean;
enablePlugin(): void;
disablePlugin(): void;
updatePlugin(): void;
destroy(): void;
}
// Access to registered plugins
interface HandsontablePlugins {
// Column/Row manipulation
AutoColumnSize: typeof BasePlugin;
AutoRowSize: typeof BasePlugin;
ManualColumnResize: typeof BasePlugin;
ManualRowResize: typeof BasePlugin;
ManualColumnMove: typeof BasePlugin;
ManualRowMove: typeof BasePlugin;
// Sorting and filtering
ColumnSorting: typeof BasePlugin;
MultiColumnSorting: typeof BasePlugin;
Filters: typeof BasePlugin;
// UI enhancements
ContextMenu: typeof BasePlugin;
DropdownMenu: typeof BasePlugin;
Comments: typeof BasePlugin;
CustomBorders: typeof BasePlugin;
MergeCells: typeof BasePlugin;
// Data features
UndoRedo: typeof BasePlugin;
CopyPaste: typeof BasePlugin;
Autofill: typeof BasePlugin;
Search: typeof BasePlugin;
registerPlugin: typeof registerPlugin;
getPlugin: typeof getPlugin;
[key: string]: any;
}Comprehensive event system with 200+ hooks for lifecycle management and customization.
// Hook management system
interface Hooks {
add(key: string, callback: Function, context?: object): void;
once(key: string, callback: Function, context?: object): void;
remove(key: string, callback: Function): void;
run(key: string, ...args: any[]): any;
has(key: string): boolean;
destroy(): void;
}
// Core lifecycle hooks
type CoreHooks =
| 'beforeInit' | 'afterInit'
| 'beforeRender' | 'afterRender'
| 'beforeChange' | 'afterChange'
| 'beforeLoadData' | 'afterLoadData'
| 'beforeUpdateSettings' | 'afterUpdateSettings'
| 'beforeSelection' | 'afterSelection'
| 'beforeKeyDown' | 'afterKeyDown'
| 'beforeValidate' | 'afterValidate'
// And 180+ more hooks...
;
// Access via instance
declare const hooks: Hooks;Global Handsontable properties and utilities.
// Version and build information
declare const version: string;
declare const buildDate: string;
declare const packageName: string;
// Default configuration
declare const DefaultSettings: GridSettings;
// Utility classes
declare const EventManager: typeof EventManager;// Core types
type CellValue = string | number | boolean | Date | null | undefined;
type CellChange = [number, string | number, CellValue, CellValue];
type ChangeSource = 'alter' | 'empty' | 'edit' | 'populateFromArray' | 'loadData' | 'autofill' | 'paste';
interface CellProperties {
row: number;
col: number;
visualRow: number;
visualCol: number;
type: string;
source: any;
readOnly: boolean;
[key: string]: any;
}
// Editor and renderer types
type EditorType = typeof BaseEditor;
type RendererType = (instance: Core, TD: HTMLElement, row: number, col: number, prop: string | number, value: CellValue, cellProperties: CellProperties) => HTMLElement;
type ValidatorType = (value: CellValue, callback: (valid: boolean) => void) => void;
// Event system (enhanced)
interface Hooks {
add(key: string, callback: Function, context?: object): void;
once(key: string, callback: Function, context?: object): void;
remove(key: string, callback: Function): void;
run(key: string, ...args: any[]): any;
has(key: string): boolean;
destroy(): void;
}
// Cell meta interface
interface CellMeta extends CellProperties {
valid?: boolean;
comment?: string;
isSearchResult?: boolean;
skipColumnOnPaste?: boolean;
}
// Plugin-specific interfaces
interface ColumnSortingSettings {
enabled?: boolean;
indicator?: boolean;
headerAction?: boolean;
compareFunctionFactory?: (sortOrder: string, columnMeta: object) => Function;
}
interface FiltersSettings {
enabled?: boolean;
indicators?: boolean;
dropdownMenu?: boolean | object;
}