Password cell type
Use the password cell type to mask confidential values by rendering entered characters as symbols.
The password cell type masks cell values with asterisks. Use it for PIN codes, access codes, or other values that should not be visible in plain text.
Overview
The password cell type behaves like a text cell, the only difference being that it masks its value using asterisks in the cell renderer. An <input type="password"> field is used for the cell editor. Data is stored in the data source as plain text.
/* file: app.component.ts */import { Component } from '@angular/core';import { GridSettings, HotTableModule} from '@handsontable/angular-wrapper';
@Component({ selector: 'example1-password-cell-type', standalone: true, imports: [HotTableModule], template: ` <div> <hot-table [data]="data" [settings]="gridSettings"></hot-table> </div>`,})export class AppComponent {
readonly data = [ { id: 1, name: { first: 'Chris', last: 'Right' }, password: 'plainTextPassword', }, { id: 2, name: { first: 'John', last: 'Honest' }, password: 'txt' }, { id: 3, name: { first: 'Greg', last: 'Well' }, password: 'longer' }, ];
readonly gridSettings: GridSettings = { colHeaders: ['ID', 'First name', 'Last name', 'Password'], height: 'auto', autoWrapRow: true, autoWrapCol: true, columns: [ { data: 'id' }, { data: 'name.first' }, { data: 'name.last' }, { data: 'password', type: 'password' }, ] };}/* end-file */
/* file: app.config.ts */import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';import { registerAllModules } from 'handsontable/registry';import { HOT_GLOBAL_CONFIG, HotGlobalConfig, NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
// register Handsontable's modulesregisterAllModules();
export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), { provide: HOT_GLOBAL_CONFIG, useValue: { license: NON_COMMERCIAL_LICENSE } as HotGlobalConfig, }, ],};/* end-file */<div> <example1-password-cell-type></example1-password-cell-type></div>Fixed hash length
By default, every hash has a length equal to the length of its corresponding value. Use option hashLength to set a fixed hash length.
/* file: app.component.ts */import { Component } from '@angular/core';import { GridSettings, HotTableModule} from '@handsontable/angular-wrapper';
@Component({ selector: 'example2-password-cell-type', standalone: true, imports: [HotTableModule], template: ` <div> <hot-table [data]="data" [settings]="gridSettings"></hot-table> </div>`,})export class AppComponent {
readonly data = [ { id: 1, name: { first: 'Chris', last: 'Right' }, password: 'plainTextPassword', }, { id: 2, name: { first: 'John', last: 'Honest' }, password: 'txt' }, { id: 3, name: { first: 'Greg', last: 'Well' }, password: 'longer' }, ];
readonly gridSettings: GridSettings = { colHeaders: ['ID', 'First name', 'Last name', 'Password'], height: 'auto', autoWrapRow: true, autoWrapCol: true, columns: [ { data: 'id' }, { data: 'name.first' }, { data: 'name.last' }, { data: 'password', type: 'password', hashLength: 10 }, ] };}/* end-file */
/* file: app.config.ts */import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';import { registerAllModules } from 'handsontable/registry';import { HOT_GLOBAL_CONFIG, HotGlobalConfig, NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
// register Handsontable's modulesregisterAllModules();
export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), { provide: HOT_GLOBAL_CONFIG, useValue: { license: NON_COMMERCIAL_LICENSE } as HotGlobalConfig, }, ],};/* end-file */<div> <example2-password-cell-type></example2-password-cell-type></div>Custom hash symbol
By default, every hash consists of asterisks *. Use the option hashSymbol to set a custom hash symbol. You can use any character, entity, or even HTML. Note that you can’t change the symbol used by the input field due to browser limitations.
/* file: app.component.ts */import { Component } from '@angular/core';import { GridSettings, HotTableModule} from '@handsontable/angular-wrapper';
@Component({ selector: 'example3-password-cell-type', standalone: true, imports: [HotTableModule], template: ` <div> <hot-table [data]="data" [settings]="gridSettings"></hot-table> </div>`,})export class AppComponent {
readonly data = [ { id: 1, name: { first: 'Chris', last: 'Right' }, password: 'plainTextPassword', }, { id: 2, name: { first: 'John', last: 'Honest' }, password: 'txt' }, { id: 3, name: { first: 'Greg', last: 'Well' }, password: 'longer' }, ];
readonly gridSettings: GridSettings = { colHeaders: ['ID', 'First name', 'Last name', 'Password'], height: 'auto', autoWrapRow: true, autoWrapCol: true, columns: [ { data: 'id' }, { data: 'name.first' }, { data: 'name.last' }, { data: 'password', type: 'password', hashSymbol: '■' }, ] };}/* end-file */
/* file: app.config.ts */import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';import { registerAllModules } from 'handsontable/registry';import { HOT_GLOBAL_CONFIG, HotGlobalConfig, NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
// register Handsontable's modulesregisterAllModules();
export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), { provide: HOT_GLOBAL_CONFIG, useValue: { license: NON_COMMERCIAL_LICENSE } as HotGlobalConfig, }, ],};/* end-file */<div> <example3-password-cell-type></example3-password-cell-type></div>Reveal delay
Use the hashRevealDelay option to briefly show each character as you type it. After the delay (in milliseconds) elapses, the character is replaced by the hash symbol. This lets you confirm what you typed without permanently exposing the value.
When hashRevealDelay is set, the editor switches from a native <input type="password"> to a <input type="text"> field with manual masking. Only the most recently typed character stays visible - all preceding characters are already masked.
/* file: app.component.ts */import { Component } from '@angular/core';import { GridSettings, HotTableModule } from '@handsontable/angular-wrapper';
@Component({ selector: 'example4-password-cell-type', standalone: true, imports: [HotTableModule], template: `<div> <hot-table [data]="data" [settings]="gridSettings"></hot-table> </div>`,})export class AppComponent { readonly data = [ { id: 1, name: { first: 'Chris', last: 'Right' }, password: 'plainTextPassword' }, { id: 2, name: { first: 'John', last: 'Honest' }, password: 'txt' }, { id: 3, name: { first: 'Greg', last: 'Well' }, password: 'longer' }, ];
readonly gridSettings: GridSettings = { colHeaders: ['ID', 'First name', 'Last name', 'Password'], height: 'auto', autoWrapRow: true, autoWrapCol: true, columns: [ { data: 'id' }, { data: 'name.first' }, { data: 'name.last' }, { data: 'password', type: 'password', hashRevealDelay: 1000 }, ], };}/* end-file */
/* file: app.config.ts */import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';import { registerAllModules } from 'handsontable/registry';import { HOT_GLOBAL_CONFIG, HotGlobalConfig, NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';
// register Handsontable's modulesregisterAllModules();
export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), { provide: HOT_GLOBAL_CONFIG, useValue: { license: NON_COMMERCIAL_LICENSE } as HotGlobalConfig, }, ],};/* end-file */<div> <example4-password-cell-type></example4-password-cell-type></div>Result
After configuring the password cell type, cells display asterisks instead of the actual value. The editor uses an <input type="password"> field (or <input type="text"> when hashRevealDelay is set). The actual data is stored in plain text in the data source and is not encrypted by Handsontable.
Related articles
Related guides
Configuration options
Core methods
Hooks