I have the following problem:
I have an phone number input field like this:
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?
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