Search code examples
javascriptangularregextypescriptangular-directive

Phone mask directive in Angular 8


I have this phone mask directive which accepts a phone number in US format. However, when i clear the contents in the input by hitting backspace one by one, the value inside the input form is not being emptied. I didn't realize this issue until I logged the input value of the form.

And, when I clear the input form at once, it is being emptied. But, clearing by form value one by one hitting the backspace always leaves one value.

input-form-value

How do I clear the input value when the form value is empty?

I created a working example using StackBlitz. Could anyone please help?

Directive

export class PhoneMaskDirective {
  constructor(public ngControl: NgControl) {}

  @HostListener("ngModelChange", ["$event"])
  onModelChange(event) {
    this.onInputChange(event, false);
  }

  @HostListener("keydown.backspace", ["$event"])
  keydownBackspace(event) {
    this.onInputChange(event.target.value, true);
  }

  onInputChange(event, backspace) {
    if (event == null) {
      return "";
    }
    let newVal = event.replace(/\D/g, "");

    if (backspace && newVal.length <= 6) {
      newVal = newVal.substring(0, newVal.length - 1);
    }
    if (newVal.length === 0) {
      newVal = "";
    } else if (newVal.length <= 3) {
      newVal = newVal.replace(/^(\d{0,3})/, "($1)");
    } else if (newVal.length <= 6) {
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})/, "($1) $2");
    } else if (newVal.length <= 10) {
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(\d{0,4})/, "($1) $2-$3");
    }
    this.ngControl.valueAccessor.writeValue(newVal);
  }
}


Solution

  • Your problem might be set null value when the input value length === 0 with valueAccessor.writevalue which won't work here.

    Can you replace this

    this.ngControl.control.setValue(null);
    

    instead of

    this.ngControl.valueAccessor.writeValue(null);
    

    Ref: https://stackblitz.com/edit/angular6-phone-mask-4rzs1k?file=app%2Fphone-mask.directive.ts