0
votes

I want input type=number to accept decimal numbers between 0.1 and 0.9 (only one decimal number after dot, for example: 0.11 is not allowed), and also number 1.
I'm trying to restrict that from a directive. It seems the directive works but then I press the submit button a value of the form control is incorrect.
For example, if I type 0.11, 0.1 is shown in the input but form control has value of 0.11.
If I type a number from 1 to 9, input is empty but form control has value of that number.
Here is a stackblitz link: https://stackblitz.com/edit/angular-ivy-xa5g8v?file=src%2Fapp%2Fapp.component.ts

1

1 Answers

0
votes

This is happening because you are updating DOM but not the form model. One of the easiest and common way would be to emit event from directive and update the form model in event handler as shown below,

**Modified directive

import { Component, Output, EventEmitter } from "@angular/core";
//other import statements

@Directive({
  selector: "[appLimitDecimal]"
})
export class LimitDecimalDirective {
  @Output()
  purgedValue: EventEmitter<any> = new EventEmitter();
  @HostListener("input", ["$event"])
  changes(evt: any) {
    const removeLastChar = evt.target.value.substring(
      0,
      evt.target.value.length - 1
    );
    // if decimal number length is bigger than 3
    if (evt.target.value.length > 3) {
      console.log("fromDirective", removeLastChar);
    }
    // decimal numbers from 0.1 to 0.9 and 1
    // remove last character if does not match regex
    if (!/^(?:0(?:\.[1-9])?|1)$/.test(evt.target.value)) {
      // evt.target.value = removeLastChar;
      this.purgedValue.emit(removeLastChar);
    }
  }
}

**Modified input element

<input
  type="number"
  formControlName="numberInp"
   appLimitDecimal
  (purgedValue)="setValue($event)"
  min="0.1"
  max="1.0"
  step="0.1"
 />

Finally, add following callback method in app.component.ts

  setValue(val) {
    this.f.patchValue({ numberInp: val });
  }

I hope this is helpful to you.