4

I'm using angular 4 for my front end.I want to insert a thousand seperator to a input field. I tried this code but its not working

   <input type="number" class="form-control" id="amount" placeholder="Amount" name="Amount" [ngModel]="Amount | number:'3.2-2'" (keypress)="onlyNumberKey($event)">

here is my component.ts code

export class CustomerDepositApplicationComponent implements OnInit {

Amount: any;

Please help me..

Shyamal
  • 161
  • 1
  • 2
  • 17
  • 1
    thousand seperator means? – Lakshmi Prasanna May 03 '18 at 05:51
  • this might help you https://blog.ngconsultant.io/custom-input-formatting-with-simple-directives-for-angular-2-ec792082976 – Franklin Pious May 03 '18 at 05:52
  • @LakshmiPrasanna when the user type the number it should be automatically break into 3 digits(Ex - 1,000,000) – Shyamal May 03 '18 at 05:59
  • You have taken number pipe completely in wrong way. You have o right your own pipe to get that. you can find code here : https://stackoverflow.com/questions/44672225/how-to-specify-thousand-separator-for-number-pipe-in-angular-4 – Lakshmi Prasanna May 03 '18 at 06:10

5 Answers5

4

You can't add pipes like that. What you have to do is, format your number properly in the ts and bind it.

numeraljs is a really good library for this kind of scenarios.

Let me create a stackblitz using that.

Update

I created simple stackblitz. Please have a look. Any way I couldn't import numeral package into stackblitz due to require issue in stackblitz. But this is way more easy if you use numeral.

In this sample I used .toLocaleString(); functionality where JS automatically detects the browser region and convert your number appropriately. Eg if your browser locale en-US, number will format like 15,000. If it's nb-NO number may looks different way.

Rukshan Dangalla
  • 2,500
  • 2
  • 24
  • 29
0

I had a similar problem. To solve it I have used this article. I have created a slightly modified version to fit my needs.

import { Directive, ElementRef, forwardRef, HostListener, Input, OnDestroy } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { MAT_INPUT_VALUE_ACCESSOR } from '@angular/material';
import { Subscription } from 'rxjs';
import { formatNumber } from '@angular/common';

@Directive({
  selector: 'input[localizedNumericInput]',
  providers: [
    { provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: LocalizedNumericInputDirective },
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => LocalizedNumericInputDirective),
      multi: true
    }
  ]
})
export class LocalizedNumericInputDirective implements ControlValueAccessor, OnDestroy {
  locale = 'en';
  decimalMarker: string;

  constructor(private element: ElementRef<HTMLInputElement>) {
  }

  private _value: string | null;

  get value(): string | null {
    return this._value;
  }

  @Input('value')
  set value(value: string | null) {
    this._value = value;
    this.formatValue(value);
  }

  @HostListener('input', ['$event.target.value'])
  input(value) {
    //Find all numerics, decimal marker(, or .) and -
    //It will delete thousandSeparator cos it's always opposite to decimal marker
    const regExp = new RegExp(`[^\\d${this.decimalMarker}-]`, 'g');
    //Separate value on before and after decimal marker
    const [integer, decimal] = value.replace(regExp, '').split(this.decimalMarker);

    //Send non localized value, with dot as decimalMarker to API
    this._value = decimal ? integer.concat('.', decimal) : integer;

    // If decimal separator is last character don't update
    // because it will delete . || ,
    if (this.isLastCharacterDecimalSeparator(value)) {
      this._value = value;
    }

    // here to notify Angular Validators
    this._onChange(this._value);
  }

  @HostListener('blur')
  _onBlur() {
    /**
     * Adding thousand separators
     */
    this.formatValue(this._value);
  }

  @HostListener('focus')
  onFocus() {
    this.unFormatValue();
  }

  _onChange(value: any): void {}

  /**
   * @param value
   * apply formatting on value assignment
   */
  writeValue(value: any) {
    this._value = value;
    this.formatValue(this._value);
  }

  registerOnChange(fn: (value: any) => void) {
    this._onChange = fn;
  }

  registerOnTouched() {}

  isLastCharacterDecimalSeparator(value: any) {
    return isNaN(value[value.length - 1]);
  }


  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, this.locale).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);
    }
  }

  private unFormatValue() {
    const value = this.element.nativeElement.value;
    if (this.isLastCharacterDecimalSeparator(value)) {
      return;
    }
    const regExp = new RegExp(`[^\\d${this.decimalMarker}-]`, 'g');
    const [integer, decimal] = value.replace(regExp, '').split(this.decimalMarker);

    this._value = integer.concat('.', decimal);
    if (value) {
      this.element.nativeElement.value = this._value;
    } else {
      this.element.nativeElement.value = '';
    }
  }
}

To use this directive your html should look like this:

<mat-form-field>
<mat-label>Value</mat-label>
<input
        type="text"
        localizedNumericInput
        matInput
        autocomplete="off"
        formControlName="value"
      />
</mat-form-field>
Radovan Skendzic
  • 2,923
  • 1
  • 14
  • 22
0

Try like this below:

<input type="text" id="txt" onkeyup = "numberWithCommas(document.getElementById('txt').value)">

<script>
function numberWithCommas(x) {
    if(x != "") {
        var val = parseFloat(x.replace(/,/g, ''))
        document.getElementById('txt').value = parseInt(val).toLocaleString();
    }
}
</script>
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
  • Hi, your answer would be more helpful if you could provide some description or context to go along with it. Good code formatting also goes a long way to improve the readability of your answer. – Burhan Sep 15 '21 at 18:17
-1

You can add ngx-currency module and use it like this:

<input id="valueInput" class="input amount" placeholder="Amount" [(ngModel)]="amount" value="0" currencyMask min="0" (ngModelChange)="amountChanged($event)" >
Amir Ajorloo
  • 85
  • 1
  • 5
-1

A simple and clean solution. Include the code below inside your input.

oninput="this.value=this.value.replace(/\D/g, '').replace(/\B(?=(\d{3})+ (?!\d))/g, ',')"
Cherma Ramalho
  • 373
  • 3
  • 7