Format input number in Angular 8 to have thousands separator

4,295 views
Skip to first unread message

Babak Fakhriloo

unread,
Feb 18, 2021, 5:11:13 AM2/18/21
to Angular and AngularJS discussion
I have been trying some packages to add formatting to input values,  but at the end none of them worked for in a way I needed. 

So I created a directive as below : 

import { Directive, forwardRef, OnDestroy, HostListener, Input, ElementRef, Output, EventEmitter, AfterViewInit } from '@angular/core';

import { NG_VALUE_ACCESSOR, ControlValueAccessor, NgModel, NgControl } from '@angular/forms';

import { formatNumber } from '@angular/common';

 

@Directive({

  selector: '[ngModel][appFormatNumber]',

  providers: [NgModel]

 

})

export class FormatNumberDirective {

  decimalMarker: string;

  constructor(private control: NgControl, private element: ElementRef) { }

  ngOnInit() {

    this.control.valueChanges.subscribe((value) => {

      this.formatValue(value);

    });

  }

 

  private formatValue(value: string | null) {

    if (value === null) {

      this.element.nativeElement.value = '';

      return;

    }

 

    if (this.isLastCharacterDecimalSeparator(value)) {

      this.element.nativeElement.value = value;

      return;

    }

 

    // Conclude the decimal and thousand separators from locale

    const [thousandSeparator, decimalMarker] = formatNumber(1000.99, 'en').replace(/\d/g, '');

    this.decimalMarker = decimalMarker;

 

    //Here value should always come with . as decimal marker thus any other behavior is bug

    const [integer, decimal] = value.split('.');

 

    //Group every three elements, and add thousandSeparator after them

    this.element.nativeElement.value = integer.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);

 

    //Add decimals and decimalMarker if any

    if (decimal) {

      this.element.nativeElement.value = this.element.nativeElement.value.concat(decimalMarker, decimal);

    }

  }

 

  isLastCharacterDecimalSeparator(value: any) {

    return isNaN(value[value.length - 1]);

  }

}


And here is how I use the directive : 

<input type="text" [(ngModel)]="z" appFormatNumber/>

It works fine when user enters value and separates number, but when the formcontrol value is read for calculation purposes , it reads the formatted one like "4,561" I want the "4561" read.

Reply all
Reply to author
Forward
0 new messages