0

I have the following problem:

I have an phone number input field like this:

phone number input

I want to mask the text like 55-5555-5555 so I have created a directive:

import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
  selector: '[appPhoneNumber]'
})
export class PhoneNumberDirective {

 constructor(public ngControl: NgControl) { }

  ngOnInit() {
    this.windowReady(this.ngControl.model);

  }

  windowReady(value) {
    this.onInputChange(value, false);
  }

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

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

  onInputChange(event, backspace) {
    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 <= 2) {
      newVal = newVal.replace(/^(\d{0,3})/, '$1');
    } else if (newVal.length <= 6) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,4})/, '$1-$2');
    } else if (newVal.length <= 10) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,4})(\d{0,4})/, '$1-$2-$3');
    } else {
      newVal = newVal.substring(0, 10);
      newVal = newVal.replace(/^(\d{0,2})(\d{0,4})(\d{0,4})/, '$1-$2-$3');
    }
    console.log("New value is: " + newVal);
    this.ngControl.valueAccessor.writeValue(newVal);
  }
}

And here is the input field:

<mat-form-field style="width: 75%;">
  <input matInput appPhoneNumber placeholder="Telefono" [(ngModel)]="person.numero_telefono">
</mat-form-field>

As you can see, the input has an ngModel for getting and setting the value, the problem I am facing right now is when the input first appear and the ngModel has a value, the field displays the text like:

5555555555

Instead of:

55-5555-5555

My theory right now is that the directive is setting the value:

this.ngControl.valueAccessor.writeValue(newVal);

Before the input itself:

<input matInput appPhoneNumber placeholder="Telefono" [(ngModel)]="person.numero_telefono">

So when the input set the value, it takes the value without the mask and overrides the text set by the directive.

Does anyone know how to call the directive after the ngModel or something that help me?

Abraham Soto
  • 172
  • 1
  • 9

3 Answers3

1

I believe you want a pipe, not a directive. If you take a look at this post it talks about how to use a pipe with an ngModel Using Pipes within ngModel on INPUT Elements in Angular

Mitch McCutchen
  • 376
  • 2
  • 7
0

ng-mask might be what you are looking for.

<input matInput appPhoneNumber placeholder="Telefono" [(ngModel)]="person.numero_telefono" mask='55-5555-5555'>

Here is the link for further information ng-mask

Jose Ortiz
  • 705
  • 1
  • 9
  • 19
0

The issue is not with [(ngModel)] or Input control. The actual cause of this issue is matInput directive. Just remove matInput and check.

Sunil Singh
  • 11,001
  • 2
  • 27
  • 48