Angular Data GridNumeric cell type

Display, format, sort, and filter numbers correctly by using the numeric cell type.

Overview

The default cell type in Handsontable is text. The data of a text cell is processed as a string type that corresponds to the value of the text editor's internal <textarea> element. However, there are many cases where you need cell values to be treated as a number type. The numeric cell type allows you to format displayed numbers nicely and sort them correctly.

Numeric cell type demo

In the following demo, columns Year, Price ($), and Price (€) use the numeric cell type. Click on the column names to sort them.

/* file: app.component.ts */
import { Component } from '@angular/core';
import { GridSettings } from '@handsontable/angular-wrapper';

@Component({
  selector: 'example1-numeric-cell-type',
  standalone: false,
  template: ` <div>
    <hot-table [data]="data" [settings]="gridSettings"></hot-table>
  </div>`,
})
export class Example1NumericCellTypeComponent {

  readonly data = [
    { car: 'Mercedes A 160', year: 2017, price_usd: 7000, price_eur: 7000 },
    {
      car: 'Citroen C4 Coupe',
      year: 2018,
      price_usd: 8330,
      price_eur: 8330,
    },
    {
      car: 'Audi A4 Avant',
      year: 2019,
      price_usd: 33900,
      price_eur: 33900,
    },
    { car: 'Opel Astra', year: 2020, price_usd: 5000, price_eur: 5000 },
    {
      car: 'BMW 320i Coupe',
      year: 2021,
      price_usd: 30500,
      price_eur: 30500,
    },
  ];

  readonly gridSettings: GridSettings = {
    colHeaders: ['Car', 'Year', 'Price ($)', 'Price (€)'],
    columnSorting: true,
    height: 'auto',
    autoWrapRow: true,
    autoWrapCol: true,
    columns: [
      {
        data: 'car',
        // 1st column is simple text, no special options here
      },
      {
        data: 'year',
        type: 'numeric',
      },
      {
        data: 'price_usd',
        type: 'numeric',
        numericFormat: {
          pattern: '$0,0.00',
          culture: 'en-US', // this is the default culture, set up for USD
        },
        allowEmpty: false,
      },
      {
        data: 'price_eur',
        type: 'numeric',
        numericFormat: {
          pattern: '0,0.00 $',
          culture: 'de-DE', // use this for EUR (German),
          // more cultures available on http://numbrojs.com/languages.html
        },
      },
    ]
  };
}



/* 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';
import { Example1NumericCellTypeComponent } from './app.component';

// register Handsontable's modules
registerAllModules();

export const appConfig: ApplicationConfig = {
  providers: [
    {
      provide: HOT_GLOBAL_CONFIG,
      useValue: {
        themeName: 'ht-theme-main',
        license: NON_COMMERCIAL_LICENSE,
      } as HotGlobalConfig
    }
  ],
};

@NgModule({
  imports: [ BrowserModule, HotTableModule, CommonModule ],
  declarations: [ Example1NumericCellTypeComponent ],
  providers: [...appConfig.providers],
  bootstrap: [ Example1NumericCellTypeComponent ]
})

export class AppModule { }

Use the numeric cell type

To use the numeric cell type, set the type option to 'numeric':

// set the numeric cell type for each cell of the entire grid
settings1 = {
  type: "numeric",
};

// set the numeric cell type for each cell of a single column
settings2 = {
  columns: [
    {
      type: "numeric",
    },
  ],
};

// set the numeric cell type for a single cell
settings3 = {
  cell: [
    {
      row: 0,
      col: 0,
      type: "numeric",
    },
  ],
};

Mind that Handsontable doesn't parse strings to numbers. In your data source, make sure to store numeric cell values as numbers, not as strings.

All positive and negative integers whose magnitude is no greater than 253 (+/- 9007199254740991) are representable in the Number type, i.e., as a safe integer. Any calculations that are performed on bigger numbers won't be calculated precisely, due to JavaScript's limitations.

Format numbers

To format the look of numeric values in cell renderers, use the numericFormat option.

In the following demo, columns Price in Japan and Price in Turkey use two different numericFormat configurations.

/* file: app.component.ts */
import { Component } from '@angular/core';
import { GridSettings } from '@handsontable/angular-wrapper';
import numbro from 'numbro';
// @ts-ignore: Missing TypeScript declaration file for "numbro" languages files
import jaJP from 'numbro/languages/ja-JP';
// @ts-ignore: Missing TypeScript declaration file for "numbro" languages files
import trTR from 'numbro/languages/tr-TR';

// register the languages you need
numbro.registerLanguage(jaJP);
numbro.registerLanguage(trTR);

// define formats
const formatJP = {
  pattern: '0,0.00 $',
  culture: 'ja-JP',
};

const formatTR = {
  pattern: '0,0.00 $',
  culture: 'tr-TR',
};

@Component({
  selector: 'example3-numeric-cell-type',
  standalone: false,
  template: ` <div>
    <hot-table [data]="data" [settings]="gridSettings"></hot-table>
  </div>`,
})
export class Example3NumericCellTypeComponent {

  readonly data = [
    {
      productName: 'Product A',
      JP_price: 1450.32,
      TR_price: 202.14,
    },
    {
      productName: 'Product B',
      JP_price: 2430.22,
      TR_price: 338.86,
    },
    {
      productName: 'Product C',
      JP_price: 3120.1,
      TR_price: 435.2,
    },
  ];

  readonly gridSettings: GridSettings = {
    autoRowSize: false,
    autoColumnSize: false,
    columnSorting: true,
    colHeaders: ['Product name', 'Price in Japan', 'Price in Turkey'],
    height: 'auto',
    autoWrapRow: true,
    autoWrapCol: true,
    columns: [
      { data: 'productName', type: 'text', width: '150' },
      {
        data: 'JP_price',
        type: 'numeric',
        numericFormat: formatJP,
        width: '150',
      },
      {
        data: 'TR_price',
        type: 'numeric',
        numericFormat: formatTR,
        width: '150',
      },
    ]
  };
}



/* 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';
import { Example3NumericCellTypeComponent } from './app.component';

// register Handsontable's modules
registerAllModules();

export const appConfig: ApplicationConfig = {
  providers: [
    {
      provide: HOT_GLOBAL_CONFIG,
      useValue: {
        themeName: 'ht-theme-main',
        license: NON_COMMERCIAL_LICENSE,
      } as HotGlobalConfig
    }
  ],
};

@NgModule({
  imports: [ BrowserModule, HotTableModule, CommonModule ],
  declarations: [ Example3NumericCellTypeComponent ],
  providers: [...appConfig.providers],
  bootstrap: [ Example3NumericCellTypeComponent ]
})

export class AppModule { }

Mind that the numericFormat option doesn't change the way numbers are presented or parsed by the cell editor. When you edit a numeric cell:

  • Regardless of the numericFormat configuration, the number that's being edited displays its decimal separator as a period (.), and has no thousands separator or currency symbol.
    For example, during editing $7,000.02, the number displays as 7000.02.
  • You can enter a decimal separator either with a period (.), or with a comma (,).
  • You can't enter a thousands separator. After you finish editing the cell, the thousands separator is added automatically, based on your numericFormat configuration.