Comments
Add a comment (a note) to a cell, using the context menu, just like in Excel. Edit and delete comments. Make comments read-only.
Enable the plugin
Set the comments configuration option to true to enable the feature and add all the needed context menu items. For example:
data = [ ["A1", "B1", "C1"], ["A2", "B2", "C2"],];settings = { comments: true,};<hot-table [data]="data" [settings]="settings" />Add comments via the context menu
After you’ve enabled the plugin, the Context Menu gains a few new items:
- Add/Edit comment
- Delete comment
- Read-only comment
Set up pre-set comments
You can also pre-define comments for your table. Comments are stored in the table’s/column’s/cell’s metadata object and you can declare as any value of the respective type. For example:
settings = { cell: [{ row: 1, col: 1, comment: { value: "Hello world!" } }],};In this example, the comment “Hello world!” is added to the cell at (1,1).
Basic example
/* file: app.component.ts */import { Component } from '@angular/core';import { GridSettings } from '@handsontable/angular-wrapper';
@Component({ selector: 'example1-comments', standalone: false, template: ` <div> <hot-table [data]="data" [settings]="gridSettings"></hot-table> </div>`,})export class Example1CommentsComponent {
readonly data = [ ['', 'Tesla', 'Nissan', 'Toyota', 'Honda', 'Mazda', 'Ford'], ['2017', 10, 11, 12, 13, 15, 16], ['2018', 10, 11, 12, 13, 15, 16], ['2019', 10, 11, 12, 13, 15, 16], ['2020', 10, 11, 12, 13, 15, 16], ['2021', 10, 11, 12, 13, 15, 16], ];
readonly gridSettings: GridSettings = { rowHeaders: true, colHeaders: true, contextMenu: true, comments: true, cell: [ { row: 1, col: 1, comment: { value: 'Some comment' } }, { row: 2, col: 2, comment: { value: 'More comments' } }, ], height: 'auto', autoWrapRow: true, autoWrapCol: 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 { Example1CommentsComponent } from './app.component';/* end:skip-in-compilation */
// register Handsontable's modulesregisterAllModules();
export const appConfig: ApplicationConfig = { providers: [ { provide: HOT_GLOBAL_CONFIG, useValue: { license: NON_COMMERCIAL_LICENSE, } as HotGlobalConfig } ],};
@NgModule({ imports: [ BrowserModule, HotTableModule, CommonModule ], declarations: [ Example1CommentsComponent ], providers: [...appConfig.providers], bootstrap: [ Example1CommentsComponent ]})
export class AppModule { }/* end-file */<div> <example1-comments></example1-comments></div>Make a comment read-only
By default, all comments are editable. To change this, set the readOnly configuration option to true when adding a comment. This example makes the “Tesla” comment attached to a cell read-only, whereas the “Honda” comment attached to another cell is editable.
/* file: app.component.ts */import { Component } from '@angular/core';import { GridSettings } from '@handsontable/angular-wrapper';
@Component({ selector: 'example2-comments', standalone: false, template: ` <div> <hot-table [data]="data" [settings]="gridSettings"></hot-table> </div>`,})export class Example2CommentsComponent {
readonly data = [ ['', 'Tesla', 'Toyota', 'Honda', 'Ford'], ['2018', 10, 11, 12, 13, 15, 16], ['2019', 10, 11, 12, 13, 15, 16], ['2020', 10, 11, 12, 13, 15, 16], ];
readonly gridSettings: GridSettings = { rowHeaders: true, colHeaders: true, contextMenu: true, comments: true, cell: [ { row: 0, col: 1, comment: { value: 'A read-only comment.', readOnly: true }, }, { row: 0, col: 3, comment: { value: 'You can edit this comment' } }, ], height: 'auto', autoWrapRow: true, autoWrapCol: 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 { Example2CommentsComponent } from './app.component';/* end:skip-in-compilation */
// register Handsontable's modulesregisterAllModules();
export const appConfig: ApplicationConfig = { providers: [ { provide: HOT_GLOBAL_CONFIG, useValue: { license: NON_COMMERCIAL_LICENSE, } as HotGlobalConfig } ],};
@NgModule({ imports: [ BrowserModule, HotTableModule, CommonModule ], declarations: [ Example2CommentsComponent ], providers: [...appConfig.providers], bootstrap: [ Example2CommentsComponent ]})
export class AppModule { }/* end-file */<div> <example2-comments></example2-comments></div>Set a comment box’s size
To set the width and height of a comment box, use the style parameter.
/* file: app.component.ts */import { Component } from '@angular/core';import { GridSettings } from '@handsontable/angular-wrapper';
@Component({ selector: 'example3-comments', standalone: false, template: ` <div> <hot-table [data]="data" [settings]="gridSettings"></hot-table> </div>`,})export class Example3CommentsComponent {
readonly data = [ ['', 'Tesla', 'Nissan', 'Toyota', 'Honda', 'Mazda', 'Ford'], ['2017', 10, 11, 12, 13, 15, 16], ['2018', 10, 11, 12, 13, 15, 16], ['2019', 10, 11, 12, 13, 15, 16], ];
readonly gridSettings: GridSettings = { rowHeaders: true, colHeaders: true, contextMenu: true, comments: true, cell: [ { row: 1, col: 1, comment: { value: 'Some comment' } }, // add the `style` parameter { row: 2, col: 2, comment: { value: 'Comment 200x50 px', style: { width: 200, height: 50 }, }, }, ], height: 'auto', autoWrapRow: true, autoWrapCol: 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 { Example3CommentsComponent } from './app.component';/* end:skip-in-compilation */
// register Handsontable's modulesregisterAllModules();
export const appConfig: ApplicationConfig = { providers: [ { provide: HOT_GLOBAL_CONFIG, useValue: { license: NON_COMMERCIAL_LICENSE, } as HotGlobalConfig } ],};
@NgModule({ imports: [ BrowserModule, HotTableModule, CommonModule ], declarations: [ Example3CommentsComponent ], providers: [...appConfig.providers], bootstrap: [ Example3CommentsComponent ]})
export class AppModule { }/* end-file */<div> <example3-comments></example3-comments></div>Set a delay for displaying comments
To display comments after a pre-configured time delay, use the displayDelay parameter.
/* file: app.component.ts */import { Component } from '@angular/core';import { GridSettings } from '@handsontable/angular-wrapper';
@Component({ selector: 'example4-comments', standalone: false, template: ` <div> <hot-table [data]="data" [settings]="gridSettings"></hot-table> </div>`,})export class Example4CommentsComponent {
readonly data = [ ['', 'Tesla', 'Toyota', 'Honda', 'Ford'], ['2018', 10, 11, 12, 13, 15, 16], ['2019', 10, 11, 12, 13, 15, 16], ['2020', 10, 11, 12, 13, 15, 16], ];
readonly gridSettings: GridSettings = { rowHeaders: true, colHeaders: true, contextMenu: true, comments: { // on mouseover, wait 2 seconds before the comment box displays displayDelay: 2000, }, cell: [{ row: 1, col: 1, comment: { value: 'Some comment' } }], height: 'auto', autoWrapRow: true, autoWrapCol: 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 { Example4CommentsComponent } from './app.component';/* end:skip-in-compilation */
// register Handsontable's modulesregisterAllModules();
export const appConfig: ApplicationConfig = { providers: [ { provide: HOT_GLOBAL_CONFIG, useValue: { license: NON_COMMERCIAL_LICENSE, } as HotGlobalConfig } ],};
@NgModule({ imports: [ BrowserModule, HotTableModule, CommonModule ], declarations: [ Example4CommentsComponent ], providers: [...appConfig.providers], bootstrap: [ Example4CommentsComponent ]})
export class AppModule { }/* end-file */<div> <example4-comments></example4-comments></div>Related keyboard shortcuts
| Windows | macOS | Action | Excel | Sheets |
|---|---|---|---|---|
| Ctrl+Alt+M | Ctrl+Option+M | Add or edit a comment | ✗ | ✓ |
| Ctrl+Enter | Cmd+Enter | Save and exit the current comment | ✗ | ✓ |
| Escape | Escape | Exit the current comment without saving | ✗ | ✗ |
Related API reference
Configuration options