'How to force ngModel update when value did not change?

I want to limit number input to 0-100 range, but on input, not during validation. I'm using ngModel to bind value and emitt change event:

<input [ngModel]="value" (ngModelChange)="validate($event)" />

And then check if value exceeds given limits:

public validate(value) {
    if (value > 100)
        this.value = 100;
    if (value < 0)
        this.value = 0;
}

And this partialy works. However if I say try to input 150 and value will switch to 100, I can then input anything over 100, because model value remains 100, and so input value is not updated. Is there any way to manually force this update?

EDIT: I missed quite important bit here. This behaviour seems to only occur to input with type=number. Text input wont exceed 100. My workaround is as Faisal suggested using keypress event with preventDefault like so:

public keyPress(event) {
    let inputChar: number = +String.fromCharCode(event.charCode);
    if (this.value + inputChar > 100 || this.value + inputChar < 0) {
        // Exceeded limits, prevent input
        event.preventDefault();
    }
}


Solution 1:[1]

Use a regular expression to limit the user input.

Here is the html code for your input:

<input [(ngModel)]="value" 
       (keypress)="keyPress($event)"
       (ngModelChange)="validate($event)"  
        maxlength=3 />

.. and typescript code:

keyPress(event: any) {
    const pattern = /[0-9]/;
    let inputChar = String.fromCharCode(event.charCode);

    if (!pattern.test(inputChar)) {
        // invalid character, prevent input
        event.preventDefault();
    }
}

validate(value:number) {
    if(value>100) {
        this.value=100;
    }
}

Here is a working plunker: Plunker DEMO

Solution 2:[2]

I had the same problem and found a different solution that I liked more. As you said the problem is that the value in the model is the same before and after your function. What I did was to call Angular's change detection before I change the value so it registers a change. For this use the ChangeDetectorRef class and call its detectChanges method.

Thus, your function becomes :

public validate(value) {
    this.changeDetector.detectChanges();
    if (value > 100)
        this.value = 100;
    if (value < 0)
        this.value = 0;
}

And it works perfectly. Hope it helps.

Solution 3:[3]

I had a similar problem. My input does not update, when the result equals to the previous entry value.

I use @ViewChild like that : In your template :

<input #input [ngModel]="value" (ngModelChange)="validate($event)" />

In your TS file :

@ViewChild('input') input: ElementRef;

public validate(value) {
    if (value > 100)
        this.value = 100;
    if (value < 0)
        this.value = 0;
    this.input.writeValue(this.value); // force to update
}

Solution 4:[4]

another way .. as i Know is to use NgZone (equivalent of AngularJs $scope.$apply()) .. like:

constructor(private _ngZone:NgZone){

}


public validate(value){
    if(value>100)
        this.value=100;
    if(value<0)
        this.value=0;

this._ngzone.run(()=>{
 this.value=(value>100) ? 100  ? (value<0) ? 0 : 0;
});

}

Solution 5:[5]

You can add else part to reflect changes.

public validate(value){
    if(value>100)
        this.value=100;
    else
        this.value = value    
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Faisal
Solution 2 Romain
Solution 3 user1075296
Solution 4 federico scamuzzi
Solution 5 asdf_enel_hak