I am facing an issue with implementing a smart number input component that can toggle between allowing or disallowing negative numbers. I have an event listener for the (input)
on the <input>
element, triggering a function that applies various regex patterns to the value. The function appears to be functioning correctly as the variable's value changes, but the input field value doesn't update (connected to the input via [(ngModel)]
).
Below are the code snippets (Angular version 13.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
@Input('allow-negative') allowNegative: boolean = false;
//emit number onchange
@Output('app-change') change = new EventEmitter<number>();
constructor() { }
onInput() {
let str = String(this.inputValue);
console.log(this.inputValue, str);
// applying regex patterns
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 tested
Input value | First console.log | Second console.log | Outcome |
---|---|---|---|
123 |
'123' '123' |
123 '123' |
No change, as expected |
123a |
'123a' '123a' |
123 '123' |
Input field value doesn't update, but this.inputValue does |
-123 |
'-123' '-123' |
123 '123' |
Input field value doesn't update, but this.inputValue does |
123-4 |
'123-4' '123-4' |
123 '123' |
Input field value doesn't update, but this.inputValue does |
In cases where the input field value doesn't update, typing a number seems to trigger the update and display correctly. Typing any other character has no effect.
Any suggestions?
Edit
I found a solution without using ngModel
:
The updated onInput()
method now takes an event argument to directly modify the input element's value. Here is the working code:
onInput(event: Event) {
let inputEl = event.target as HTMLInputElement;
let str = String(inputEl.value);
// more regex operations
this.inputValue = Number(str);
inputEl.value = str;
}