Home > Software design >  Update the thousand separator commas when the input values are changed in Angular reactive form
Update the thousand separator commas when the input values are changed in Angular reactive form

Time:09-21

The link to the stackblitz https://stackblitz.com/edit/angular-ivy-csqein?file=src/app/hello.component.html

When I copy-paste a value into the INPUT box it returns the correct data

INPUT - 12345678 OUTPUT - 12,345,678

but when I input values one by one it is not able to format it the output looks like this 1,234567

Expected OUTPUT

  1. When the input is first loaded it comes with the comma-separated digits.
  2. I want to make it so that when the users add or delete values in the input box, the commas are updated in the very box.

Things that I have tried

  1. Creating custom Pipe and updating the value in the component using valueChanges

CodePudding user response:

You can't transform input value when you using formControlName, because when you want to transform that value, angular give you a formControl that you can use to change that value.

For example in your code, you can do this:

constructor(private fb: FormBuilder, private currencyPipe: CurrencyPipe) {}
profileForm;
ngOnInit() {
  this.profileForm = this.fb.group({
    name: this.currencyPipe.transform(12345678, '', '','0.0'),
  });

  // this.changes();
}

Note: Don't forget to provide CurrencyPipe in your module.

The code above it's the only way or solution you can do to change the input value when you use the formControlName.

Or another way you can use is remove your formControlName from your input and it will working fine.

<input
    id="number"
    [value]="profileForm.get('name').value | number"
    maxlength="8"
  />

But the problem is you should have to do it manually to patch value from input to your formControl. You can use (input) like what I do in custom input component below.

Custom Input Component

If you like to using custom input component, then code below maybe can help you to resolve your question:

You can create app-input.ts and put this code below:

import { CurrencyPipe } from '@angular/common';
import {
  Component,
  forwardRef,
  HostListener,
  Input,
  OnInit,
} from '@angular/core';
import {
  ControlContainer,
  ControlValueAccessor,
  FormControl,
  FormGroup,
  NG_VALUE_ACCESSOR,
} from '@angular/forms';

@Component({
  selector: 'app-input[type=currency]',
  templateUrl: './currency.component.html',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CurrencyComponent),
      multi: true,
    },
  ],
})
export class CurrencyComponent implements ControlValueAccessor, OnInit {
  @Input() formControlName: string;
  value: any;
  onChange: () => any;
  onTouche: () => any;

  public formGroup: FormGroup;
  public formControl: FormControl;

  constructor(
    private controlContainer: ControlContainer,
    private currencyPipe: CurrencyPipe
  ) {}

  ngOnInit() {
    console.log('Currency Component');
    console.log(this.controlContainer);
    this.setStateInitialization();
  }

  private setStateInitialization(): void {
    this.formGroup = this.controlContainer.control as FormGroup;
    this.formControl = this.formGroup.get(this.formControlName) as FormControl;
  }

  writeValue(value: any): void {
    this.value = value;
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouche = fn;
  }

  @HostListener('input', ['$event'])
  private _onHostListenerInput(event: InputEvent): void {
    const inputElement = event.target as HTMLInputElement;
    let value: string | number = inputElement.value;
    if (value) value =  inputElement.value.replace(/\D/g, '');
    this.formControl.patchValue(value);
    inputElement.value = value
      ? this.currencyPipe.transform(value, '', '', '0.0')
      : '';
  }
}

Now you can add app-input.html and use code below:

<input
  type="text"
  [value]="formControl.value ? (formControl.value | currency: '':'':'0.0') : ''"
/>

After that if you want to use this component, you can call:

<app-input type="currency" formControlName="currency"></app-input>

Or whatever name you want, you can change it.

Update:

Live Preview: https://angular-ivy-aqppd6.stackblitz.io

Live Code: https://stackblitz.com/edit/angular-ivy-aqppd6?file=src/app/app.component.ts

I hope it can help you to imagine what you can do to resolve your question.

  • Related