Search code examples
angularinputangular-ngmodel

NgModelChange on input number not updating the view


I'm currently trying to create an input number that prevent user to enter a number that is higher than a @Input() maxValue, I implemented it like this :

HTML :

<input
    class="number-selector-input"
    type="number"
    [(ngModel)]="value"
    (ngModelChange)="checkValue($event)"
/>

Typescript :

public checkValue(value) {
  if (value > this.maxValue) { 
    this.value = this.maxValue;
  }
  if (value < this.minValue) { 
    this.value = this.minValue;
  }
}

It is working quite well but there is still a problem that I can't understand. I have a maxValue equals to 100, when I type 150 or 200, it change automatically to 100 but when I type 1000, the input number does not update.

When I tried to show the value in the console or directly in the HTML, the model is correctly equals to 100. Do you have any idea to help me understand this ?


Solution

  • Weird bug to be honest, I tested and it showed the same behavior.

    However, you can circumvent this by adding a directive, which is imo also a lot cleaner because it doesnt clutter your component with a function

    Directive:

    import { Directive, Input, ElementRef, HostListener } from '@angular/core';
    
    @Directive({
      selector: '[minMax]'
    })
    export class MinMaxDirective {
    
      @Input()
      public min: number;
    
      @Input()
      public max: number;
    
      constructor(private ref: ElementRef) { }
    
        @HostListener('input', [ '$event' ])
      public onInput(a_Event: InputEvent): void {
        let val = parseInt(this.ref.nativeElement.value);
        if(this.max !== null && this.max !== undefined  && val >= this.max)
          this.ref.nativeElement.value = this.max.toString();
        else if (this.min !== null && this.min !== undefined  && val <= this.min)
          this.ref.nativeElement.value = this.min.toString();
      }
    
    }
    

    Usage:

    <input
        [(ngModel)]="value"
        [min]="minValue"
        [max]="maxValue"
        minMax
        class="number-selector-input"
        type="number"/>
    

    Demo: https://stackblitz.com/edit/angular-input-min-max-directive