1

I have this problem where I am trying to implement a smart number input component which can be set to allow or disallow negative numbers. I have an (input) event listener on the <input> element, which runs a function that is supposed to apply a bunch of regex patterns to the value. The function seems to work correcly and the variable's value is being changed, but the value in the input doesn't update (bound to the input via [(ngModel)]).

Here are the code snippets (Angular v13.2.4):

//number-input.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-number-input',
  templateUrl: './number-input.component.html',
  styleUrls: ['./number-input.component.scss']
})
export class NumberInputComponent {
  //basic variables
  @Input() inputValue: string | number | null = null;
  @Input() placeholder: string | number | undefined = undefined;

  //allow negative numbers to be used
  @Input('allow-negative') allowNegative: boolean = false; //this is set to false everywhere possible

  //emit the number from the input on change
  @Output('app-change') change = new EventEmitter<number>();

  constructor() { }

  onInput() {
    let str = String(this.inputValue);
    console.log(this.inputValue, str);

    if (!this.allowNegative && str.match(/\-/g)) {
      str = str.replace(/\-/g, '');
    }
    if (this.allowNegative && str.match(/(.+)-/g)) {
      str = str.replace(/(.+)-/g, '$1');
    }
    if (str.match(/[^0-9,\.\-]/g)) {
      str = str.replace(/[^0-9,\.\-]/g, '');
    }
    if (str.match(/,/g)) {
      str = str.replace(/,/g, '.');
    }
    this.inputValue = Number(str);
    console.log(this.inputValue, str);
  }
  onChange() {
    this.change.emit(Number(this.inputValue));
  }
}
<!-- number-input.component.html -->
<input type="text" [(ngModel)]="inputValue" (input)="onInput()" (change)="onChange()">

Cases I tested

Input value First console.log Second console.log What happens
123 '123' '123' 123 '123' Nothing, as is supposed to
123a '123a' '123a' 123 '123' Value in the input element doesn't update, but this.inputValue clearly does
-123 '-123' '-123' 123 '123' Value in the input element doesn't update, but this.inputValue clearly does
123-4 '123-4' '123-4' 123 '123' Value in the input element doesn't update, but this.inputValue clearly does

Also, in all cases where the value in the input element doesn't update, typing in any number seems to update the input's value, and it displays properly. Typing in any other character does nothing.

Any ideas?

Edit

I came up with a solution, that doesn't involve ngModel:

onInput() method now accepts an event argument, which I use to directly edit the input element's value. Here is the code that ended up working:

onInput(event: Event) {
  let inputEl = event.target as HTMLInputElement;
  let str = String(inputEl.value);

  // some regex matches here

  this.inputValue = Number(str);
  inputEl.value = str;
}
1
  • Implement changeDetectorRef functionality will solve your issues. you can refer official docs from link Commented May 9, 2022 at 18:54

1 Answer 1

0

You could pass your data to $event object:

<input type="text" [(ngModel)]="inputValue" (input)="onInput($event)" >

On ts file:

  onInput(event:any) {
    let str = String(event.target.value);
}
Sign up to request clarification or add additional context in comments.

2 Comments

That wouldn't solve anything. The onInput() function works all fine, it's just that the input's value doesn't update.
Although your suggestion solved nothing, it helped me think of a solution. I edited the original post to include it. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.