Skip to content

Migrate from Handsontable 8.4 to Handsontable 9.0, released on June 1, 2021.

More information about this release can be found in the 9.0.0 release blog post.
For a detailed list of changes in this release, see the Changelog.

Overview

The purpose of this guide is to make it easier to migrate from v8.4.0 to v9.0.0. In the version 9.0 we have introduced a new formula engine with has completely replaced the previous one. There is a breaking change in the formula API - even in the way the plugin itself is initialized.

Plugin initialization

The plugin uses HyperFormula, which is meant to be passed in as an external dependency every time you want to initialize the plugin. HyperFormula installation guide is available here.

Before 9.0 (legacy plugin)After 9.0 (new plugin)
formulas={true}import { HyperFormula } from 'hyperformula';

formulas={{
            engine: HyperFormula
}}

See other available initialization methods here.

Available methods

Method nameBefore 9.0 (legacy plugin)After 9.0 (new plugin)
destroyhot.getPlugin('formulas').destroy()Unchanged. This method will destroy the HyperFormula instance only after it is disconnected from all Handsontable instances.
disablePluginhot.getPlugin('formulas').disablePlugin()Unchanged.
enablePluginhot.getPlugin('formulas').enablePlugin()Unchanged, but do keep in mind that if you didn’t pass in the plugin’s config through either updateSettings or during Handsontable initialization this method will not do anything.
getCellValuehot.getPlugin('formulas').getCellValue(row, column)Use base Handsontable API instead, for example hot.getDataAtCell(row, column).
getVariablehot.getPlugin('formulas').getVariable(variableName)”Variables” in the plugin have been replaced by a more powerful alternative, named expressions.
hasComputedCellValuehot.getPlugin('formulas').hasComputedCellValue(row, column)hot.getPlugin('formulas').getCellType(row, column) === 'FORMULA'
isEnabledhot.getPlugin('formulas').isEnabled()Unchanged.
recalculatehot.getPlugin('formulas').recalculate()hot.getPlguin('formulas').engine.rebuildAndRecalculate()
recalculateFullhot.getPlugin('formulas').recalculateFull()hot.getPlguin('formulas').engine.rebuildAndRecalculate()
recalculateOptimizedhot.getPlugin('formulas').recalculateOptimized()hot.getPlguin('formulas').engine.rebuildAndRecalculate()
setVariablehot.getPlugin('formulas').setVariable(variableName, value)”Variables” in the plugin have been replaced by a more powerful alternative, named expressions.

Available functions

The list of available functions can be found here.

Autofill hooks

To make autofill hooks more consistent and more powerful, beforeAutofill and afterAutofill hooks have had their signatures changed.

Before 9.0.0:

<HotTable
data={data}
beforeAutofill={(start, end, data) {}}
afterAutofill={(start, end, data) {}}
/>

After:

<HotTable
data={data}
beforeAutofill={(selectionData, sourceRange, targetRange, direction) {
const start = targetRange.from // used to be `start`
const end = targetRange.to // used to be `end`
const data = selectionData // used to be `data`
}}
afterAutofill={(fillData, sourceRange, targetRange, direction) {
const start = targetRange.from // used to be `start`
const end = targetRange.to // used to be `end`
const data = fillData // used to be `data`
}}
/>

In beforeAutofill instead of mutating data, you can now just return a new array of arrays with your desired fill pattern.

Removed plugins

In Handsontable 9.0.0 we removed the following, previously-deprecated plugins:

  • Header Tooltips
  • Observe Changes

Header Tooltips

To implement functionality similar to that of the Header Tooltips plugin, you can utilize the afterGetColHeader and afterGetRowHeader hooks to add a title attribute to the headers. See the snippet below for example implementation.

const onAfterGetHeader = function(index, TH) {
TH.setAttribute('title', TH.querySelector('span').textContent);
};
<HotTable
data={[
['A1', 'B1', 'C1'],
['A2', 'B2', 'C2'],
['A3', 'B3', 'C3'],
]}
rowHeights={23}
autoColumnSize={true}
rowHeaders={['1st', '2nd', '3rd']}
colHeaders={['First Column', 'Second Column', 'Third Column']}
licenseKey="non-commercial-and-evaluation"
afterGetColHeader={onAfterGetHeader}
afterGetRowHeader={onAfterGetHeader}
/>

Observe Changes

The plugin fired the afterChangesObserved hook. Be sure to stop listening to it after updating to version >=9.0.0.