Skip to content

Autocomplete cell type

Collect user input with a list of choices, by using the autocomplete cell type.

The autocomplete cell type provides a text input with suggestions from a predefined list. Use it when users should choose from known values but can also type freely.

Overview

You can edit the autocomplete-typed cells in three different ways:

  • Flexible mode
  • Strict mode
  • Strict mode with asynchronous data

In all three modes, the source option can be provided in two formats:

  • An array of values
  • An array of objects with key and value properties

Autocomplete flexible mode

This example uses the autocomplete feature in the default flexible mode. In this mode, the user can choose one of the suggested options while typing or enter a custom value that is not included in the suggestions.

The visibleRows option sets how many suggestions the dropdown shows without scrolling. The default is 10 rows. The Chassis color column sets visibleRows: 4, so the dropdown shows only four suggestions at a time and scrolls to reveal the rest.

The trimDropdown option controls the dropdown’s width. By default (trimDropdown: true), the dropdown matches the width of the edited cell, which can truncate long suggestions. The Bumper color column sets trimDropdown: false, so the dropdown expands to fit its widest suggestion, even if that makes it wider than the cell.

JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
const colors = [
'yellow',
'red',
'orange and another color',
'green',
'blue',
'gray',
'black',
'white',
'purple',
'lime',
'olive',
'cyan',
];
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['BMW', 2017, 'black', 'black'],
['Nissan', 2018, 'blue', 'blue'],
['Chrysler', 2019, 'yellow', 'black'],
['Volvo', 2020, 'white', 'gray'],
]}
colHeaders={['Car', 'Year', 'Chassis color', 'Bumper color']}
columns={[
{
type: 'autocomplete',
source: ['BMW', 'Chrysler', 'Nissan', 'Suzuki', 'Toyota', 'Volvo'],
strict: false,
},
{ type: 'numeric' },
{
type: 'autocomplete',
source: colors,
strict: false,
visibleRows: 4,
},
{
type: 'autocomplete',
source: colors,
strict: false,
trimDropdown: false,
},
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
const colors = [
'yellow',
'red',
'orange and another color',
'green',
'blue',
'gray',
'black',
'white',
'purple',
'lime',
'olive',
'cyan',
];
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['BMW', 2017, 'black', 'black'],
['Nissan', 2018, 'blue', 'blue'],
['Chrysler', 2019, 'yellow', 'black'],
['Volvo', 2020, 'white', 'gray'],
]}
colHeaders={['Car', 'Year', 'Chassis color', 'Bumper color']}
columns={[
{
type: 'autocomplete',
source: ['BMW', 'Chrysler', 'Nissan', 'Suzuki', 'Toyota', 'Volvo'],
strict: false,
},
{ type: 'numeric' },
{
type: 'autocomplete',
source: colors,
strict: false,
visibleRows: 4,
},
{
type: 'autocomplete',
source: colors,
strict: false,
trimDropdown: false,
},
]}
/>
);
};
export default ExampleComponent;

Autocomplete strict mode

This is the same example as above, the difference being that autocomplete now runs in strict mode. In this mode, the autocomplete cells will only accept values that are defined in the source array. The mouse and keyboard bindings are identical to the handsontable cell type but with the differences below:

  • If there is at least one option visible, there always is a selection in HOT-in-HOT
  • When the first row is selected, pressing Arrow Up does not deselect HOT-in-HOT. Instead, it behaves as the Enter key but moves the selection in the main HOT upwards

In strict mode, the allowInvalid option determines the behaviour in the case of manual user input:

  • allowInvalid: true optional - allows manual input of a value that does not exist in the source, the field background is highlighted in red, and the selection advances to the next cell
  • allowInvalid: false - does not allow manual input of a value that does not exist in the source, the Enter key is ignored, and the editor field remains open
JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
const colors = [
'yellow',
'red',
'orange',
'green',
'blue',
'gray',
'black',
'white',
'purple',
'lime',
'olive',
'cyan',
];
const cars = ['BMW', 'Chrysler', 'Nissan', 'Suzuki', 'Toyota', 'Volvo'];
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['BMW', 2017, 'black', 'black'],
['Nissan', 2018, 'blue', 'blue'],
['Chrysler', 2019, 'yellow', 'black'],
['Volvo', 2020, 'white', 'gray'],
]}
colHeaders={['Car<br>(allowInvalid true)', 'Year', 'Chassis color', 'Bumper color<br>(allowInvalid true)']}
columns={[
{
type: 'autocomplete',
source: cars,
strict: true,
// allowInvalid: true // true is default
},
{},
{
type: 'autocomplete',
source: colors,
strict: true,
},
{
type: 'autocomplete',
source: colors,
strict: true,
allowInvalid: true, // true is default
},
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
const colors = [
'yellow',
'red',
'orange',
'green',
'blue',
'gray',
'black',
'white',
'purple',
'lime',
'olive',
'cyan',
];
const cars = ['BMW', 'Chrysler', 'Nissan', 'Suzuki', 'Toyota', 'Volvo'];
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['BMW', 2017, 'black', 'black'],
['Nissan', 2018, 'blue', 'blue'],
['Chrysler', 2019, 'yellow', 'black'],
['Volvo', 2020, 'white', 'gray'],
]}
colHeaders={['Car<br>(allowInvalid true)', 'Year', 'Chassis color', 'Bumper color<br>(allowInvalid true)']}
columns={[
{
type: 'autocomplete',
source: cars,
strict: true,
// allowInvalid: true // true is default
},
{},
{
type: 'autocomplete',
source: colors,
strict: true,
},
{
type: 'autocomplete',
source: colors,
strict: true,
allowInvalid: true, // true is default
},
]}
/>
);
};
export default ExampleComponent;

Autocomplete strict mode with asynchronous data

Autocomplete can also use asynchronous data sources. In the example below, suggestions for the “Car” column are loaded from the server with the Fetch API. To load data from a remote source, assign a function to the source option. The function receives the query string and the process callback. Call process() with the result array when the request completes.

JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['BMW', 2017, 'black', 'black'],
['Nissan', 2018, 'blue', 'blue'],
['Chrysler', 2019, 'yellow', 'black'],
['Volvo', 2020, 'white', 'gray'],
]}
colHeaders={['Car', 'Year', 'Chassis color', 'Bumper color']}
columns={[
{
type: 'autocomplete',
source(_query, process) {
fetch('/docs/scripts/json/autocomplete.json')
.then((response) => response.json())
.then((response) => process(response.data));
},
strict: true,
},
{},
{},
{}, // Bumper color is a default text column
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['BMW', 2017, 'black', 'black'],
['Nissan', 2018, 'blue', 'blue'],
['Chrysler', 2019, 'yellow', 'black'],
['Volvo', 2020, 'white', 'gray'],
]}
colHeaders={['Car', 'Year', 'Chassis color', 'Bumper color']}
columns={[
{
type: 'autocomplete',
source(_query, process) {
fetch('/docs/scripts/json/autocomplete.json')
.then((response) => response.json())
.then((response) => process(response.data));
},
strict: true,
},
{}, // Year is a default text column
{}, // Chassis color is a default text column
{}, // Bumper color is a default text column
]}
/>
);
};
export default ExampleComponent;

The source option

The source option can be provided in two formats:

Array of values

You can provide the source option as an array of values that will be used as the autocomplete suggestions.

JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
const shipmentKVData = [
['Electronics and Gadgets', 'Los Angeles International Airport'],
['Medical Supplies', 'John F. Kennedy International Airport'],
['Auto Parts', "Chicago O'Hare International Airport"],
['Fresh Produce', 'London Heathrow Airport'],
['Textiles', 'Charles de Gaulle Airport'],
['Industrial Equipment', 'Dubai International Airport'],
['Pharmaceuticals', 'Tokyo Haneda Airport'],
['Consumer Goods', 'Beijing Capital International Airport'],
['Machine Parts', 'Singapore Changi Airport'],
['Food Products', 'Amsterdam Airport Schiphol'],
];
const airportKVData = [
'Los Angeles International Airport',
'John F. Kennedy International Airport',
"Chicago O'Hare International Airport",
'London Heathrow Airport',
'Charles de Gaulle Airport',
'Dubai International Airport',
'Tokyo Haneda Airport',
'Beijing Capital International Airport',
'Singapore Changi Airport',
'Amsterdam Airport Schiphol',
'Frankfurt Airport',
'Seoul Incheon International Airport',
'Toronto Pearson International Airport',
'Madrid-Barajas Airport',
'Bangkok Suvarnabhumi Airport',
'Munich International Airport',
'Sydney Kingsford Smith Airport',
'Barcelona-El Prat Airport',
'Kuala Lumpur International Airport',
'Zurich Airport',
];
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={shipmentKVData}
columns={[
{
title: 'Shipment',
},
{
type: 'autocomplete',
source: airportKVData,
title: 'Airport',
},
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
const shipmentKVData = [
['Electronics and Gadgets', 'Los Angeles International Airport'],
['Medical Supplies', 'John F. Kennedy International Airport'],
['Auto Parts', "Chicago O'Hare International Airport"],
['Fresh Produce', 'London Heathrow Airport'],
['Textiles', 'Charles de Gaulle Airport'],
['Industrial Equipment', 'Dubai International Airport'],
['Pharmaceuticals', 'Tokyo Haneda Airport'],
['Consumer Goods', 'Beijing Capital International Airport'],
['Machine Parts', 'Singapore Changi Airport'],
['Food Products', 'Amsterdam Airport Schiphol'],
];
const airportKVData = [
'Los Angeles International Airport',
'John F. Kennedy International Airport',
"Chicago O'Hare International Airport",
'London Heathrow Airport',
'Charles de Gaulle Airport',
'Dubai International Airport',
'Tokyo Haneda Airport',
'Beijing Capital International Airport',
'Singapore Changi Airport',
'Amsterdam Airport Schiphol',
'Frankfurt Airport',
'Seoul Incheon International Airport',
'Toronto Pearson International Airport',
'Madrid-Barajas Airport',
'Bangkok Suvarnabhumi Airport',
'Munich International Airport',
'Sydney Kingsford Smith Airport',
'Barcelona-El Prat Airport',
'Kuala Lumpur International Airport',
'Zurich Airport',
];
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={shipmentKVData}
columns={[
{
title: 'Shipment',
},
{
type: 'autocomplete',
source: airportKVData,
title: 'Airport',
},
]}
/>
);
};
export default ExampleComponent;

Array of objects

You can provide the source option as an array of objects with key and value properties. The value property will be used as the autocomplete suggestion, while the entire object will be used as the value of the cell.

JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
const shipmentKVData = [
['Electronics and Gadgets', { key: 'LAX', value: 'Los Angeles International Airport' }],
['Medical Supplies', { key: 'JFK', value: 'John F. Kennedy International Airport' }],
['Auto Parts', { key: 'ORD', value: "Chicago O'Hare International Airport" }],
['Fresh Produce', { key: 'LHR', value: 'London Heathrow Airport' }],
['Textiles', { key: 'CDG', value: 'Charles de Gaulle Airport' }],
['Industrial Equipment', { key: 'DXB', value: 'Dubai International Airport' }],
['Pharmaceuticals', { key: 'HND', value: 'Tokyo Haneda Airport' }],
['Consumer Goods', { key: 'PEK', value: 'Beijing Capital International Airport' }],
['Machine Parts', { key: 'SIN', value: 'Singapore Changi Airport' }],
['Food Products', { key: 'AMS', value: 'Amsterdam Airport Schiphol' }],
];
const airportKVData = [
{ key: 'LAX', value: 'Los Angeles International Airport' },
{ key: 'JFK', value: 'John F. Kennedy International Airport' },
{ key: 'ORD', value: "Chicago O'Hare International Airport" },
{ key: 'LHR', value: 'London Heathrow Airport' },
{ key: 'CDG', value: 'Charles de Gaulle Airport' },
{ key: 'DXB', value: 'Dubai International Airport' },
{ key: 'HND', value: 'Tokyo Haneda Airport' },
{ key: 'PEK', value: 'Beijing Capital International Airport' },
{ key: 'SIN', value: 'Singapore Changi Airport' },
{ key: 'AMS', value: 'Amsterdam Airport Schiphol' },
{ key: 'FRA', value: 'Frankfurt Airport' },
{ key: 'ICN', value: 'Seoul Incheon International Airport' },
{ key: 'YYZ', value: 'Toronto Pearson International Airport' },
{ key: 'MAD', value: 'Madrid-Barajas Airport' },
{ key: 'BKK', value: 'Bangkok Suvarnabhumi Airport' },
{ key: 'MUC', value: 'Munich International Airport' },
{ key: 'SYD', value: 'Sydney Kingsford Smith Airport' },
{ key: 'BCN', value: 'Barcelona-El Prat Airport' },
{ key: 'KUL', value: 'Kuala Lumpur International Airport' },
{ key: 'ZRH', value: 'Zurich Airport' },
];
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={shipmentKVData}
columns={[
{
title: 'Shipment',
},
{
type: 'autocomplete',
source: airportKVData,
title: 'Airport',
},
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
const shipmentKVData = [
['Electronics and Gadgets', { key: 'LAX', value: 'Los Angeles International Airport' }],
['Medical Supplies', { key: 'JFK', value: 'John F. Kennedy International Airport' }],
['Auto Parts', { key: 'ORD', value: "Chicago O'Hare International Airport" }],
['Fresh Produce', { key: 'LHR', value: 'London Heathrow Airport' }],
['Textiles', { key: 'CDG', value: 'Charles de Gaulle Airport' }],
['Industrial Equipment', { key: 'DXB', value: 'Dubai International Airport' }],
['Pharmaceuticals', { key: 'HND', value: 'Tokyo Haneda Airport' }],
['Consumer Goods', { key: 'PEK', value: 'Beijing Capital International Airport' }],
['Machine Parts', { key: 'SIN', value: 'Singapore Changi Airport' }],
['Food Products', { key: 'AMS', value: 'Amsterdam Airport Schiphol' }],
];
const airportKVData = [
{ key: 'LAX', value: 'Los Angeles International Airport' },
{ key: 'JFK', value: 'John F. Kennedy International Airport' },
{ key: 'ORD', value: "Chicago O'Hare International Airport" },
{ key: 'LHR', value: 'London Heathrow Airport' },
{ key: 'CDG', value: 'Charles de Gaulle Airport' },
{ key: 'DXB', value: 'Dubai International Airport' },
{ key: 'HND', value: 'Tokyo Haneda Airport' },
{ key: 'PEK', value: 'Beijing Capital International Airport' },
{ key: 'SIN', value: 'Singapore Changi Airport' },
{ key: 'AMS', value: 'Amsterdam Airport Schiphol' },
{ key: 'FRA', value: 'Frankfurt Airport' },
{ key: 'ICN', value: 'Seoul Incheon International Airport' },
{ key: 'YYZ', value: 'Toronto Pearson International Airport' },
{ key: 'MAD', value: 'Madrid-Barajas Airport' },
{ key: 'BKK', value: 'Bangkok Suvarnabhumi Airport' },
{ key: 'MUC', value: 'Munich International Airport' },
{ key: 'SYD', value: 'Sydney Kingsford Smith Airport' },
{ key: 'BCN', value: 'Barcelona-El Prat Airport' },
{ key: 'KUL', value: 'Kuala Lumpur International Airport' },
{ key: 'ZRH', value: 'Zurich Airport' },
];
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={shipmentKVData}
columns={[
{
title: 'Shipment',
},
{
type: 'autocomplete',
source: airportKVData,
title: 'Airport',
},
]}
/>
);
};
export default ExampleComponent;

API methods

When working with object-based autocomplete data, you can use methods like getSourceData(), getSourceDataAtCell(), getSourceDataAtRow() etc., to get the data in its original object format with both key and value properties. The getData() method will return only the value property’s value.

The filter option

By default, the autocomplete dropdown hides options that don’t match what the user is typing. Set filter: false to always show the full list of source options, regardless of the current input. This is useful when you want to give users a visual reference of all available choices while they type.

The left column uses the default behavior (filter: true) — options are narrowed as you type. The right column has filter: false — all options remain visible no matter what you enter.

JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const fruits = [
'Apple',
'Apricot',
'Avocado',
'Banana',
'Blueberry',
'Cherry',
'Grape',
'Lemon',
'Lime',
'Mango',
'Orange',
'Peach',
'Pear',
'Pineapple',
'Plum',
'Raspberry',
'Strawberry',
'Watermelon',
];
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['Apple', 'Apple'],
['Banana', 'Banana'],
['Cherry', 'Cherry'],
['Mango', 'Mango'],
['Orange', 'Orange'],
]}
colHeaders={['Filter: true (default)', 'Filter: false']}
columns={[
{
type: 'autocomplete',
source: fruits,
strict: false,
// filter: true is the default — only matching options are shown
},
{
type: 'autocomplete',
source: fruits,
strict: false,
// don't hide options that don't match the search query
filter: false,
},
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const fruits: string[] = [
'Apple',
'Apricot',
'Avocado',
'Banana',
'Blueberry',
'Cherry',
'Grape',
'Lemon',
'Lime',
'Mango',
'Orange',
'Peach',
'Pear',
'Pineapple',
'Plum',
'Raspberry',
'Strawberry',
'Watermelon',
];
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['Apple', 'Apple'],
['Banana', 'Banana'],
['Cherry', 'Cherry'],
['Mango', 'Mango'],
['Orange', 'Orange'],
]}
colHeaders={['Filter: true (default)', 'Filter: false']}
columns={[
{
type: 'autocomplete',
source: fruits,
strict: false,
// filter: true is the default — only matching options are shown
},
{
type: 'autocomplete',
source: fruits,
strict: false,
// don't hide options that don't match the search query
filter: false,
},
]}
/>
);
};
export default ExampleComponent;

The filteringCaseSensitive option

By default, the autocomplete search is case-insensitive — typing "bl" matches both "Black" and "blue". Set filteringCaseSensitive: true to require an exact case match when filtering suggestions.

The left column uses the default case-insensitive behavior. The right column has filteringCaseSensitive: true — only options whose case matches the typed characters are shown.

JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const colors = [
'Black',
'Blue',
'brown',
'cyan',
'Gray',
'green',
'Lime',
'Magenta',
'Navy',
'olive',
'orange',
'Pink',
'Purple',
'Red',
'silver',
'Teal',
'White',
'Yellow',
];
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['Black', 'Black'],
['Blue', 'Blue'],
['Gray', 'Gray'],
['Red', 'Red'],
['White', 'White'],
]}
colHeaders={['Case-insensitive (default)', 'Case-sensitive']}
columns={[
{
type: 'autocomplete',
source: colors,
strict: false,
// filteringCaseSensitive: false is the default — typing "bl" matches "Black" and "blue"
},
{
type: 'autocomplete',
source: colors,
strict: false,
// match case while searching autocomplete options
filteringCaseSensitive: true,
},
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const colors: string[] = [
'Black',
'Blue',
'brown',
'cyan',
'Gray',
'green',
'Lime',
'Magenta',
'Navy',
'olive',
'orange',
'Pink',
'Purple',
'Red',
'silver',
'Teal',
'White',
'Yellow',
];
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['Black', 'Black'],
['Blue', 'Blue'],
['Gray', 'Gray'],
['Red', 'Red'],
['White', 'White'],
]}
colHeaders={['Case-insensitive (default)', 'Case-sensitive']}
columns={[
{
type: 'autocomplete',
source: colors,
strict: false,
// filteringCaseSensitive: false is the default — typing "bl" matches "Black" and "blue"
},
{
type: 'autocomplete',
source: colors,
strict: false,
// match case while searching autocomplete options
filteringCaseSensitive: true,
},
]}
/>
);
};
export default ExampleComponent;

The sortByRelevance option

By default, the autocomplete dropdown shows suggestions in the order you provide them in the source array. Set sortByRelevance: false to sort suggestions alphabetically instead.

The left column uses the default behavior (sortByRelevance: true) — suggestions keep the order from source. The right column has sortByRelevance: false — suggestions sort alphabetically.

JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const statuses = [
'Backlog',
'In progress',
'Blocked',
'Done',
'Cancelled',
];
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['Backlog', 'Backlog'],
['In progress', 'In progress'],
['Blocked', 'Blocked'],
['Done', 'Done'],
['Cancelled', 'Cancelled'],
]}
colHeaders={['Source order (default)', 'Alphabetical order']}
columns={[
{
type: 'autocomplete',
source: statuses,
strict: false,
// sortByRelevance: true is the default — suggestions keep the order from `source`
},
{
type: 'autocomplete',
source: statuses,
strict: false,
// sort suggestions alphabetically instead of using the `source` order
sortByRelevance: false,
},
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const statuses: string[] = [
'Backlog',
'In progress',
'Blocked',
'Done',
'Cancelled',
];
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
['Backlog', 'Backlog'],
['In progress', 'In progress'],
['Blocked', 'Blocked'],
['Done', 'Done'],
['Cancelled', 'Cancelled'],
]}
colHeaders={['Source order (default)', 'Alphabetical order']}
columns={[
{
type: 'autocomplete',
source: statuses,
strict: false,
// sortByRelevance: true is the default — suggestions keep the order from `source`
},
{
type: 'autocomplete',
source: statuses,
strict: false,
// sort suggestions alphabetically instead of using the `source` order
sortByRelevance: false,
},
]}
/>
);
};
export default ExampleComponent;

The allowHtml option

By default, the autocomplete dropdown and cell renderer display source values as plain text, so any HTML tags they contain show up literally. Set allowHtml: true to render source values as HTML instead, for example to show colored status labels.

The left column uses the default behavior (allowHtml: false) — HTML tags in source show up as plain text. The right column has allowHtml: true — the same source values render as colored labels.

JavaScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const stockStatuses = [
'<span style="color: #1a7f37">In stock</span>',
'<span style="color: #b35900">Low stock</span>',
'<span style="color: #c92a2a">Out of stock</span>',
'<span style="color: #495057">Backordered</span>',
'<span style="color: #495057">Discontinued</span>',
];
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
[stockStatuses[0], stockStatuses[0]],
[stockStatuses[1], stockStatuses[1]],
[stockStatuses[2], stockStatuses[2]],
[stockStatuses[3], stockStatuses[3]],
[stockStatuses[4], stockStatuses[4]],
]}
colHeaders={['allowHtml: false (default)', 'allowHtml: true']}
columns={[
{
type: 'autocomplete',
source: stockStatuses,
strict: false,
// allowHtml: false is the default — HTML tags in `source` are shown as plain text
},
{
type: 'autocomplete',
source: stockStatuses,
strict: false,
// render `source` values as HTML — only use with trusted, static data
allowHtml: true,
},
]}
/>
);
};
export default ExampleComponent;
TypeScript
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const stockStatuses: string[] = [
'<span style="color: #1a7f37">In stock</span>',
'<span style="color: #b35900">Low stock</span>',
'<span style="color: #c92a2a">Out of stock</span>',
'<span style="color: #495057">Backordered</span>',
'<span style="color: #495057">Discontinued</span>',
];
const ExampleComponent = () => {
return (
<HotTable
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
[stockStatuses[0], stockStatuses[0]],
[stockStatuses[1], stockStatuses[1]],
[stockStatuses[2], stockStatuses[2]],
[stockStatuses[3], stockStatuses[3]],
[stockStatuses[4], stockStatuses[4]],
]}
colHeaders={['allowHtml: false (default)', 'allowHtml: true']}
columns={[
{
type: 'autocomplete',
source: stockStatuses,
strict: false,
// allowHtml: false is the default — HTML tags in `source` are shown as plain text
},
{
type: 'autocomplete',
source: stockStatuses,
strict: false,
// render `source` values as HTML — only use with trusted, static data
allowHtml: true,
},
]}
/>
);
};
export default ExampleComponent;

Result

After configuring the autocomplete cell type, cells display a text input that shows matching suggestions as the user types. In strict mode, only values from the source list are accepted. In flexible mode, users can also enter custom values not in the list.

Keyboard shortcuts

The autocomplete cell editor shares its keyboard shortcuts with the handsontable editor. In strict mode, a few of these shortcuts behave differently — see Autocomplete strict mode.

Related guides

Configuration options

Core methods

Hooks