Skip to content

Display modal dialogs, alerts, loading indicators, and notifications to enhance user interaction and provide feedback in your data grid application.

Overview

The Dialog plugin provides a modal dialog system for Handsontable that allows you to display custom content in modal dialogs that overlay the table. This is useful for showing notifications, error messages, loading indicators, or any other interactive content that requires user attention.

The dialog system is designed to be flexible and customizable, supporting various content types including plain text, HTML, and DOM elements. It also provides options for styling, animations, and user interaction controls.

Basic configuration

To enable the Dialog plugin, set the dialog option to true or provide a configuration object.

TypeScript
/* file: app.component.ts */
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
@Component({
selector: 'app-example1',
template: `
<hot-table
#hotTable
[settings]="hotSettings!"
[data]="hotData"
>
</hot-table>
`,
standalone: false
})
export class AppComponent implements AfterViewInit {
@ViewChild('hotTable') hotTable!: HotTableComponent;
readonly hotData = [
{ model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true },
{ model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false },
{ model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true },
{ model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false },
{ model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true },
{ model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true },
{ model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false },
{ model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false },
{ model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true },
{ model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true },
{ model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false },
{ model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true },
{ model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false },
{ model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false },
{ model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false },
{ model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false },
{ model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true },
{ model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true },
{ model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false },
{ model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false },
];
readonly hotSettings: GridSettings = {
columns: [
{
title: 'Model',
type: 'text',
data: 'model',
width: 150,
headerClassName: 'htLeft',
},
{
title: 'Price',
type: 'numeric',
data: 'price',
width: 80,
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
},
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Date',
type: 'intl-date',
data: 'sellDate',
width: 130,
locale: 'en-US',
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Time',
type: 'intl-time',
data: 'sellTime',
width: 90,
locale: 'en-US',
timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'In stock',
type: 'checkbox',
data: 'inStock',
className: 'htCenter',
headerClassName: 'htCenter',
},
],
width: '100%',
height: 300,
stretchH: 'all',
contextMenu: true,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
autoRowSize: true,
dialog: true,
};
ngAfterViewInit() {
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
// Show dialog after initialization
const dialogPlugin = hotInstance.getPlugin('dialog');
dialogPlugin.show({
content: 'This is a basic dialog with default configuration.',
closable: true,
});
}
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { AppComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ AppComponent ],
providers: [...appConfig.providers],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<app-example1></app-example1>
</div>

Content types

The dialog supports multiple content types including plain text, HTML strings, and DOM elements.

Plain text content

TypeScript
/* file: app.component.ts */
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
@Component({
selector: 'app-example2',
template: `
<hot-table
#hotTable
[settings]="hotSettings!"
[data]="hotData"
>
</hot-table>
`,
standalone: false
})
export class AppComponent implements AfterViewInit {
@ViewChild('hotTable') hotTable!: HotTableComponent;
readonly hotData = [
{ model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true },
{ model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false },
{ model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true },
{ model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false },
{ model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true },
{ model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true },
{ model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false },
{ model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false },
{ model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true },
{ model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true },
{ model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false },
{ model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true },
{ model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false },
{ model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false },
{ model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false },
{ model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false },
{ model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true },
{ model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true },
{ model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false },
{ model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false },
];
readonly hotSettings: GridSettings = {
columns: [
{
title: 'Model',
type: 'text',
data: 'model',
width: 150,
headerClassName: 'htLeft',
},
{
title: 'Price',
type: 'numeric',
data: 'price',
width: 80,
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
},
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Date',
type: 'intl-date',
data: 'sellDate',
width: 130,
locale: 'en-US',
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Time',
type: 'intl-time',
data: 'sellTime',
width: 90,
locale: 'en-US',
timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'In stock',
type: 'checkbox',
data: 'inStock',
className: 'htCenter',
headerClassName: 'htCenter',
},
],
width: '100%',
height: 300,
stretchH: 'all',
contextMenu: true,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
autoRowSize: true,
dialog: {
content: 'This is a simple text message displayed in the dialog.',
closable: true,
},
};
ngAfterViewInit() {
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
// Show dialog after initialization
const dialogPlugin = hotInstance.getPlugin('dialog');
dialogPlugin.show();
}
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { AppComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ AppComponent ],
providers: [...appConfig.providers],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<app-example2></app-example2>
</div>

HTML content

TypeScript
/* file: app.component.ts */
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
@Component({
selector: 'app-example3',
template: `
<hot-table
#hotTable
[settings]="hotSettings!"
[data]="hotData"
>
</hot-table>
`,
standalone: false
})
export class AppComponent implements AfterViewInit {
@ViewChild('hotTable') hotTable!: HotTableComponent;
readonly hotData = [
{ model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true },
{ model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false },
{ model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true },
{ model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false },
{ model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true },
{ model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true },
{ model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false },
{ model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false },
{ model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true },
{ model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true },
{ model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false },
{ model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true },
{ model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false },
{ model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false },
{ model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false },
{ model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false },
{ model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true },
{ model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true },
{ model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false },
{ model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false },
];
readonly hotSettings: GridSettings = {
columns: [
{
title: 'Model',
type: 'text',
data: 'model',
width: 150,
headerClassName: 'htLeft',
},
{
title: 'Price',
type: 'numeric',
data: 'price',
width: 80,
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
},
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Date',
type: 'intl-date',
data: 'sellDate',
width: 130,
locale: 'en-US',
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Time',
type: 'intl-time',
data: 'sellTime',
width: 90,
locale: 'en-US',
timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'In stock',
type: 'checkbox',
data: 'inStock',
className: 'htCenter',
headerClassName: 'htCenter',
},
],
width: '100%',
height: 300,
stretchH: 'all',
contextMenu: true,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
autoRowSize: true,
dialog: {
content: '<p>This dialog contains <strong>HTML</strong> content with formatting.</p><button id="example3-button">Hide dialog</button>',
closable: true,
},
};
ngAfterViewInit() {
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
// Show dialog after initialization
const dialogPlugin = hotInstance.getPlugin('dialog');
dialogPlugin.show();
document.getElementById('example3-button')?.addEventListener('click', () => {
dialogPlugin.hide();
});
}
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { AppComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ AppComponent ],
providers: [...appConfig.providers],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<app-example3></app-example3>
</div>

Template types

As the content option allows you to use plain text, HTML strings, and DOM elements, the template option allows you to use predefined dialog templates instead of custom content which can be useful for displaying alerts, confirmations, and other common ready-to-use dialogs.

The plugin offers two new methods to display predefined dialog templates: showAlert and showConfirm. For users looking for more customizability, the show method allows using templates with other options that the dialog offers, such as background variants, content background, and more.

TypeScript
/* file: app.component.ts */
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
@Component({
selector: 'app-example4',
template: `
<div style="margin-bottom: 16px; display: flex; gap: 10px;">
<button (click)="showAlert()">Show Alert</button>
<button (click)="showConfirm()">Show Confirm</button>
<button (click)="showCustomConfirm()">Show custom Confirm (with solid background)</button>
</div>
<hot-table
#hotTable
[settings]="hotSettings!"
[data]="hotData"
>
</hot-table>
`,
standalone: false
})
export class AppComponent implements AfterViewInit {
@ViewChild('hotTable') hotTable!: HotTableComponent;
readonly hotData = [
{ model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true },
{ model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false },
{ model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true },
{ model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false },
{ model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true },
{ model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true },
{ model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false },
{ model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false },
{ model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true },
{ model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true },
{ model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false },
{ model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true },
{ model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false },
{ model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false },
{ model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false },
{ model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false },
{ model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true },
{ model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true },
{ model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false },
{ model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false },
];
readonly hotSettings: GridSettings = {
columns: [
{
title: 'Model',
type: 'text',
data: 'model',
width: 150,
headerClassName: 'htLeft',
},
{
title: 'Price',
type: 'numeric',
data: 'price',
width: 80,
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
},
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Date',
type: 'intl-date',
data: 'sellDate',
width: 130,
locale: 'en-US',
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Time',
type: 'intl-time',
data: 'sellTime',
width: 90,
locale: 'en-US',
timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'In stock',
type: 'checkbox',
data: 'inStock',
className: 'htCenter',
headerClassName: 'htCenter',
},
],
width: '100%',
height: 300,
stretchH: 'all',
contextMenu: true,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
autoRowSize: true,
dialog: true,
};
showAlert() {
const dialogPlugin = this.hotTable.hotInstance.getPlugin('dialog');
dialogPlugin.showAlert({
title: 'Alert',
description: 'This is an example of the alert dialog.',
}, () => {
dialogPlugin.hide();
});
}
showConfirm() {
const dialogPlugin = this.hotTable.hotInstance.getPlugin('dialog');
dialogPlugin.showConfirm('Do you want to undo the last action?', () => {
this.hotTable.hotInstance.getPlugin('undoRedo').undo();
dialogPlugin.hide();
}, () => {
dialogPlugin.hide();
});
}
showCustomConfirm() {
const hotInstance = this.hotTable.hotInstance;
const dialogPlugin = hotInstance.getPlugin('dialog');
dialogPlugin.show({
template: {
type: 'confirm',
title: 'Increase the price of the first row by:',
buttons: [
{
text: 'Cancel',
type: 'secondary',
callback: () => {
dialogPlugin.hide();
},
},
{
text: '$100',
type: 'secondary',
callback: () => {
dialogPlugin.hide();
hotInstance.setDataAtCell(0, 1, hotInstance.getDataAtCell(0, 1) + 100);
hotInstance.selectCell(0, 1);
},
},
{
text: '$200',
type: 'secondary',
callback: () => {
dialogPlugin.hide();
hotInstance.setDataAtCell(0, 1, hotInstance.getDataAtCell(0, 1) + 200);
hotInstance.selectCell(0, 1);
},
},
{
text: '$500',
type: 'secondary',
callback: () => {
dialogPlugin.hide();
hotInstance.setDataAtCell(0, 1, hotInstance.getDataAtCell(0, 1) + 500);
hotInstance.selectCell(0, 1);
},
},
],
},
background: 'solid',
contentBackground: false,
closable: true,
});
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { AppComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ AppComponent ],
providers: [...appConfig.providers],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<app-example4></app-example4>
</div>

Background variants

The dialog supports two background variants: solid and semi-transparent.

TypeScript
/* file: app.component.ts */
import { AfterViewInit, Component, ViewChild, ElementRef, OnDestroy } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
@Component({
selector: 'app-example5',
template: `
<div class="example-controls-container">
<div class="controls">
<div class="theme-dropdown" #dropdown>
<button
class="theme-dropdown-trigger"
type="button"
aria-haspopup="listbox"
[attr.aria-expanded]="isOpen"
(click)="toggleDropdown()"
>
<span>{{ selectedLabel }}</span>
<svg class="theme-dropdown-chevron" aria-hidden="true" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6l6 -6"/></svg>
</button>
<ul class="theme-dropdown-menu" role="listbox" *ngIf="isOpen">
<li
*ngFor="let opt of backgroundOptions"
role="option"
[attr.aria-selected]="selected === opt.value"
(click)="selectBackground(opt.value)"
>{{ opt.label }}</li>
</ul>
</div>
</div>
</div>
<hot-table
#hotTable
[settings]="hotSettings!"
[data]="hotData"
>
</hot-table>
`,
standalone: false
})
export class AppComponent implements AfterViewInit, OnDestroy {
@ViewChild('hotTable') hotTable!: HotTableComponent;
@ViewChild('dropdown') dropdownRef!: ElementRef;
isOpen = false;
selected = 'solid';
backgroundOptions = [
{ value: 'solid', label: 'Solid' },
{ value: 'semi-transparent', label: 'Semi-transparent' },
];
private clickListener = (e: MouseEvent) => {
if (this.dropdownRef && !this.dropdownRef.nativeElement.contains(e.target)) {
this.isOpen = false;
}
};
private keydownListener = (e: KeyboardEvent) => {
if (e.key === 'Escape') this.isOpen = false;
};
get selectedLabel(): string {
return this.backgroundOptions.find((o) => o.value === this.selected)?.label || '';
}
toggleDropdown() {
this.isOpen = !this.isOpen;
}
selectBackground(value: string) {
this.selected = value;
this.isOpen = false;
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
const content = value === 'solid'
? 'This dialog uses a solid background (default).'
: 'This dialog uses a semi-transparent background.';
hotInstance.getPlugin('dialog').update({ content, background: value });
}
}
readonly hotData = [
{ model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true },
{ model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false },
{ model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true },
{ model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false },
{ model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true },
{ model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true },
{ model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false },
{ model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false },
{ model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true },
{ model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true },
{ model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false },
{ model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true },
{ model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false },
{ model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false },
{ model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false },
{ model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false },
{ model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true },
{ model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true },
{ model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false },
{ model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false },
];
readonly hotSettings: GridSettings = {
columns: [
{
title: 'Model',
type: 'text',
data: 'model',
width: 150,
headerClassName: 'htLeft',
},
{
title: 'Price',
type: 'numeric',
data: 'price',
width: 80,
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
},
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Date',
type: 'intl-date',
data: 'sellDate',
width: 130,
locale: 'en-US',
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Time',
type: 'intl-time',
data: 'sellTime',
width: 90,
locale: 'en-US',
timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'In stock',
type: 'checkbox',
data: 'inStock',
className: 'htCenter',
headerClassName: 'htCenter',
},
],
width: '100%',
height: 300,
stretchH: 'all',
contextMenu: true,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
autoRowSize: true,
dialog: {
content: 'This dialog uses a solid background (default).',
background: 'solid',
closable: true,
},
};
ngAfterViewInit() {
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
hotInstance.getPlugin('dialog').show();
}
document.addEventListener('click', this.clickListener);
document.addEventListener('keydown', this.keydownListener);
}
ngOnDestroy() {
document.removeEventListener('click', this.clickListener);
document.removeEventListener('keydown', this.keydownListener);
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { AppComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ AppComponent ],
providers: [...appConfig.providers],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<app-example5></app-example5>
</div>

Content background

The dialog content can have a background color using the contentBackground option.

TypeScript
/* file: app.component.ts */
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
@Component({
selector: 'app-example6',
template: `
<hot-table
#hotTable
[settings]="hotSettings!"
[data]="hotData"
>
</hot-table>
`,
standalone: false
})
export class AppComponent implements AfterViewInit {
@ViewChild('hotTable') hotTable!: HotTableComponent;
readonly hotData = [
{ model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true },
{ model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false },
{ model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true },
{ model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false },
{ model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true },
{ model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true },
{ model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false },
{ model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false },
{ model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true },
{ model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true },
{ model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false },
{ model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true },
{ model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false },
{ model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false },
{ model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false },
{ model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false },
{ model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true },
{ model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true },
{ model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false },
{ model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false },
];
readonly hotSettings: GridSettings = {
columns: [
{
title: 'Model',
type: 'text',
data: 'model',
width: 150,
headerClassName: 'htLeft',
},
{
title: 'Price',
type: 'numeric',
data: 'price',
width: 80,
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
},
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Date',
type: 'intl-date',
data: 'sellDate',
width: 130,
locale: 'en-US',
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Time',
type: 'intl-time',
data: 'sellTime',
width: 90,
locale: 'en-US',
timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'In stock',
type: 'checkbox',
data: 'inStock',
className: 'htCenter',
headerClassName: 'htCenter',
},
],
width: '100%',
height: 300,
stretchH: 'all',
contextMenu: true,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
autoRowSize: true,
dialog: {
content: 'This dialog uses a semi-transparent and content background.',
contentBackground: true,
background: 'semi-transparent',
closable: true,
},
};
ngAfterViewInit() {
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
// Show dialog after initialization
const dialogPlugin = hotInstance.getPlugin('dialog');
dialogPlugin.show();
}
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { AppComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ AppComponent ],
providers: [...appConfig.providers],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<app-example6></app-example6>
</div>

Dialog accessibility

The dialog plugin provides accessibility features through ARIA attributes. You can configure the dialog’s accessibility properties using the a11y option, which includes:

  • role - Sets the ARIA role (defaults to “dialog”)
  • ariaLabel - Sets the dialog’s accessible name (defaults to “Dialog”). This is used when there is no visible dialog title that can be referenced by ariaLabelledby. If both ariaLabel and ariaLabelledby are provided, ariaLabelledby takes precedence
  • ariaLabelledby - References an element that labels the dialog
  • ariaDescribedby - References an element that describes the dialog
TypeScript
/* file: app.component.ts */
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
@Component({
selector: 'app-example7',
template: `
<hot-table
#hotTable
[settings]="hotSettings!"
[data]="hotData"
>
</hot-table>
`,
standalone: false
})
export class AppComponent implements AfterViewInit {
@ViewChild('hotTable') hotTable!: HotTableComponent;
readonly hotData = [
{ model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true },
{ model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false },
{ model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true },
{ model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false },
{ model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true },
{ model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true },
{ model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false },
{ model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false },
{ model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true },
{ model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true },
{ model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false },
{ model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true },
{ model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false },
{ model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false },
{ model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false },
{ model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false },
{ model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true },
{ model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true },
{ model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false },
{ model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false },
];
readonly hotSettings: GridSettings = {
columns: [
{
title: 'Model',
type: 'text',
data: 'model',
width: 150,
headerClassName: 'htLeft',
},
{
title: 'Price',
type: 'numeric',
data: 'price',
width: 80,
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
},
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Date',
type: 'intl-date',
data: 'sellDate',
width: 130,
locale: 'en-US',
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Time',
type: 'intl-time',
data: 'sellTime',
width: 90,
locale: 'en-US',
timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'In stock',
type: 'checkbox',
data: 'inStock',
className: 'htCenter',
headerClassName: 'htCenter',
},
],
width: '100%',
height: 300,
stretchH: 'all',
contextMenu: true,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
autoRowSize: true,
dialog: {
content:
'<h2 id="example6-title">Title</h2><p id="example6-description">Description</p>',
a11y: {
role: 'alertdialog',
ariaLabel: 'Title',
ariaLabelledby: 'example6-title',
ariaDescribedby: 'example6-description',
},
closable: true,
},
};
ngAfterViewInit() {
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
// Show dialog after initialization
const dialogPlugin = hotInstance.getPlugin('dialog');
dialogPlugin.show();
}
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { AppComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ AppComponent ],
providers: [...appConfig.providers],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<app-example7></app-example7>
</div>

Programmatic control

You can control the dialog programmatically using the plugin’s methods.

Show and hide dialog

TypeScript
/* file: app.component.ts */
import { Component, ViewChild } from '@angular/core';
import { GridSettings, HotTableComponent } from '@handsontable/angular-wrapper';
@Component({
selector: 'app-example8',
template: `
<div style="margin-bottom: 16px; display: flex; gap: 10px;">
<button (click)="showDialog()">Show Dialog</button>
<button (click)="hideDialog()">Hide Dialog</button>
</div>
<hot-table
#hotTable
[settings]="hotSettings!"
[data]="hotData"
>
</hot-table>
`,
standalone: false
})
export class AppComponent {
@ViewChild('hotTable') hotTable!: HotTableComponent;
readonly hotData = [
{ model: 'Trail Helmet', price: 1298.14, sellDate: '2025-08-31', sellTime: '14:12', inStock: true },
{ model: 'Windbreaker Jacket', price: 178.9, sellDate: '2025-05-10', sellTime: '22:26', inStock: false },
{ model: 'Cycling Cap', price: 288.1, sellDate: '2025-09-15', sellTime: '09:37', inStock: true },
{ model: 'HL Mountain Frame', price: 94.49, sellDate: '2025-01-17', sellTime: '14:19', inStock: false },
{ model: 'Racing Socks', price: 430.38, sellDate: '2025-05-10', sellTime: '13:42', inStock: true },
{ model: 'Racing Socks', price: 138.85, sellDate: '2025-09-20', sellTime: '14:48', inStock: true },
{ model: 'HL Mountain Frame', price: 1909.63, sellDate: '2025-09-05', sellTime: '09:35', inStock: false },
{ model: 'Carbon Handlebar', price: 1080.7, sellDate: '2025-10-24', sellTime: '22:58', inStock: false },
{ model: 'Aero Bottle', price: 1571.13, sellDate: '2025-05-24', sellTime: '00:24', inStock: true },
{ model: 'Windbreaker Jacket', price: 919.09, sellDate: '2025-07-16', sellTime: '19:11', inStock: true },
{ model: 'HL Road Tire', price: 886.22, sellDate: '2025-09-09', sellTime: '00:42', inStock: false },
{ model: 'Speed Gloves', price: 635.13, sellDate: '2025-11-17', sellTime: '12:45', inStock: true },
{ model: 'Trail Helmet', price: 1440.64, sellDate: '2025-01-03', sellTime: '20:16', inStock: false },
{ model: 'Aero Bottle', price: 944.63, sellDate: '2025-11-15', sellTime: '16:14', inStock: false },
{ model: 'Windbreaker Jacket', price: 1161.43, sellDate: '2025-06-24', sellTime: '13:19', inStock: false },
{ model: 'LED Bike Light', price: 1012.5, sellDate: '2025-05-01', sellTime: '17:30', inStock: false },
{ model: 'Windbreaker Jacket', price: 635.37, sellDate: '2025-05-14', sellTime: '09:05', inStock: true },
{ model: 'Road Tire Tube', price: 1421.27, sellDate: '2025-01-31', sellTime: '13:33', inStock: true },
{ model: 'Action Camera', price: 1019.05, sellDate: '2025-12-07', sellTime: '01:26', inStock: false },
{ model: 'Carbon Handlebar', price: 603.96, sellDate: '2025-09-13', sellTime: '04:10', inStock: false },
];
readonly hotSettings: GridSettings = {
columns: [
{
title: 'Model',
type: 'text',
data: 'model',
width: 150,
headerClassName: 'htLeft',
},
{
title: 'Price',
type: 'numeric',
data: 'price',
width: 80,
locale: 'en-US',
numericFormat: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
},
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Date',
type: 'intl-date',
data: 'sellDate',
width: 130,
locale: 'en-US',
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'Time',
type: 'intl-time',
data: 'sellTime',
width: 90,
locale: 'en-US',
timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true },
className: 'htRight',
headerClassName: 'htRight',
},
{
title: 'In stock',
type: 'checkbox',
data: 'inStock',
className: 'htCenter',
headerClassName: 'htCenter',
},
],
width: '100%',
height: 300,
stretchH: 'all',
contextMenu: true,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
autoRowSize: true,
dialog: {
content: 'This dialog can be controlled programmatically.',
closable: true,
},
};
showDialog() {
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
hotInstance.getPlugin('dialog').show();
}
}
hideDialog() {
const hotInstance = this.hotTable.hotInstance;
if (hotInstance) {
hotInstance.getPlugin('dialog').hide();
}
}
}
/* end-file */
/* file: app.module.ts */
import { NgModule, ApplicationConfig } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { registerAllModules } from 'handsontable/registry';
import { HOT_GLOBAL_CONFIG, HotGlobalConfig, HotTableModule } from '@handsontable/angular-wrapper';
import { CommonModule } from '@angular/common';
import { NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
/* start:skip-in-compilation */
import { AppComponent } from './app.component';
/* end:skip-in-compilation */
// register Handsontable's modules
registerAllModules();
export const appConfig: ApplicationConfig = {
providers: [
{
provide: HOT_GLOBAL_CONFIG,
useValue: {
license: NON_COMMERCIAL_LICENSE,
} as HotGlobalConfig
}
],
};
@NgModule({
imports: [ BrowserModule, HotTableModule, CommonModule ],
declarations: [ AppComponent ],
providers: [...appConfig.providers],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/* end-file */
HTML
<div>
<app-example8></app-example8>
</div>

Configuration options

Plugins