Tomas Lukac
Tomas Lukac

Reputation: 2225

Angular 8 number input min/max

I have an Angular 8 application. What I wanna do is not letting user to set any other value in number input, than from range of 0-100

I was thinking something like this

<input type="number" [ngModel]="value" (ngModelChange)="validateValue($event)">

and

value = 100;

validateValue(event: number) {
    if (event > 100) {
      this.value = 100;
    } else if (event < 0) {
      this.value = 0;
    } else {
      this.value = event;
    }
}

When there is a 100 and I delete last digit and write 5 (so now I should have 105), it will do the magic and change the value to 100.

When I cursor select the whole number and write for example 105, it will do the magic too.

However. when I use the step arrows, or cursor select the last digit and change the last digit, the magic isn't happening.

Why is this not working ?

Upvotes: 2

Views: 19369

Answers (3)

Hersfold
Hersfold

Reputation: 91

I just ran into this problem myself. As you discovered, Angular appears to pay no attention to the max/min attributes set on a number input. Those are only heeded by the spinner buttons (which are actually managed by the browser directly, not Angular). In traditional HTML/JavaScript, a typed value outside the bounds of the field is regarded as 'undefined'; in Angular, it accepts the typed values.

This workaround should achieve what you want; if you (or anyone reading this) want an out-of-range value to be set to 'undefined' instead, remove the setTimeout() calls.

public realValue : number;
public min : number = 0;
public max : number = 100;

get value() : number {
    return this.realValue;
}

set value(newValue : number) {
    this.realValue = newValue;
    if(this.realValue < this.min){
        this.realValue = undefined;
        setTimeout(() => {this.realValue = this.min;});
    }
    else if(this.realValue > this.max){
        this.realValue = undefined;
        setTimeout(() => {this.realValue = this.max;});
    }
}
<input type="number" [(ngModel)]="value" [min]="min" [max]="max" (ngModelChange)="changeCallback()" />

Creating a pseudo-property with the getter and setter routes Angular's ngModel binding through your custom logic, ensuring that the value will always remain within your bounds, no matter how it gets set. Unfortunately, it does appear to be necessary to set the value to 'undefined' briefly; for some reason, Angular wasn't updating the displayed value in the field when I was simply setting realValue to min or max directly. Setting it to undefined, then using setTimeout to set the desired value, seems to force an update, although there is a weird blinky behavior as a result.

Upvotes: 3

Jihoon Kwon
Jihoon Kwon

Reputation: 755

You can try this :

public value;

  validateWhite(event: number) {

    if (event > 100) {
      this.value = 100;
    } else if (event < 0) {
      this.value = 0;
    } else {
      this.value = event;
    }
  }

In template :

<input type="number" [(ngModel)]="value" (ngModelChange)="validateWhite($event)">

It works well to me :)

Upvotes: 2

Try with Min and Max attributes.

   <input type="number" min="1" max="5">

This wont let the step arrows allow exceed the number

Upvotes: 0

Related Questions