Skip to content

A cell function is one of three components — renderer, editor, or validator — that controls how a cell displays, accepts, and validates data.

Overview

Every Handsontable cell has three associated functions that handle distinct concerns:

FunctionRoleImplemented as
rendererControls how a cell looks: DOM structure, CSS classes, HTML contentA plain function
editorControls how a cell is edited: input element, keyboard handling, open/close lifecycleA class extending BaseEditor
validatorDecides whether a cell value is acceptableA function or RegExp

The three functions are independent. You can mix and match any combination: use the built-in numeric editor with a custom renderer, override just the validator while keeping a built-in type, or write all three from scratch.

Function signatures

// renderer — called for every visible cell on every render
renderer(hotInstance, td, row, col, prop, value, cellProperties)
// hotInstance – Handsontable instance
// td – HTMLTableCellElement to modify
// row, col – visual row and column indexes
// prop – data property name (string) or column index (number)
// value – current cell value
// cellProperties – merged cell configuration object
// validator — may be synchronous or asynchronous
validator(value, callback)
// value – value to validate
// callback – call with true (valid) or false (invalid)
// RegExp alternative: /pattern/.test(value) must return true
// editor — a class; see the Cell editor guide for the full lifecycle API
class MyEditor extends BaseEditor { ... }

validator is optional. If no validator is defined for a cell, the cell is skipped entirely during validation — afterValidate will not fire for it, and it will not contribute to the validation cycle.

allowInvalid

By default, allowInvalid: true — invalid cells are accepted into the data source but marked with the htInvalid CSS class. Set allowInvalid: false to reject invalid values and keep the editor open until a valid value is entered.

Cell types bundle all three

A cell type is a preset that assigns a matching renderer, editor, and validator together under a single type alias. Using type: 'numeric' is shorthand for:

{
renderer: Handsontable.renderers.NumericRenderer,
editor: Handsontable.editors.NumericEditor,
validator: Handsontable.validators.NumericValidator,
}

Built-in types: text, numeric, checkbox, date, time, dropdown, autocomplete, password, handsontable.

When you set an explicit renderer, editor, or validator alongside a type, the explicit function always takes precedence over the type for that function only:

columns: [{
type: 'numeric', // sets NumericEditor + NumericValidator
renderer: myRenderer, // overrides only NumericRenderer; editor and validator stay numeric
}]

When to use a type vs individual functions:

  • Use type when you want the standard, bundled behavior for a data kind (numbers, dates, checkboxes).
  • Override a single function from a type when one aspect needs customizing but the rest is fine as-is.
  • Set individual renderer/editor/validator directly when no built-in type fits or you need full control.

Configuration priority

Cell functions resolve using the cascading configuration model. The most specific level wins:

cell[row][col] > column > global (root settings)

Mixing renderer, editor, and validator

The example below shows a product inventory table. Each column uses a different function configuration:

  • Producttype: 'text' bundles text renderer, text editor, and no validator.
  • Pricetype: 'numeric' bundles numeric renderer (formatted as currency), numeric editor, and numeric validator.
  • Stock — custom renderer (progress bar), built-in 'numeric' editor, and a custom range validator. All three come from different sources.

Double-click any Stock cell to edit it with the numeric editor. The bar renderer updates on save. Enter a value outside 0–1000 to see the validator reject it (cell turns red when allowInvalid: false).

Performance

Renderers are called separately for every displayed cell on every table render. A table can render many times during its lifetime — after scrolling, sorting, editing, and more. Keep renderer functions as simple and fast as possible to avoid performance drops, especially with large datasets.

Getting cell functions programmatically

Use getCellMeta(row, col) to read all properties of a cell at once, or the dedicated getters for individual functions:

Dedicated getters:

MethodReturns
getCellRenderer(row, col)The resolved renderer function for the cell
getCellEditor(row, col)The resolved editor class for the cell
getCellValidator(row, col)The resolved validator function or RegExp for the cell

If a cell’s functions are defined through a cell type, the getters return the resolved functions, not the type string:

Related guides

Configuration options

  • Cell renderer — how to control cell display using renderer functions
  • Cell editor — how to control cell editing using editor classes
  • Cell validator — how to enforce data rules using validator functions