You could provide the default value from inside the directive and set the mask in the OnInit
lifecycle hook. This would additionally have the benefit that the default value is the same each time you use this directive.
Code:
import {Directive, ElementRef, HostListener, OnInit} from '@angular/core';
import {NgControl} from '@angular/forms';
@Directive({
selector: '[formControlName][appPhoneMask]'
})
export class PhoneMaskDirective implements OnInit{
defaultValue: string = '4912345678'
constructor(public ngControl: NgControl, private elementRef: ElementRef) { }
ngOnInit(): void {
this.applyMask(this.defaultValue)
}
@HostListener('ngModelChange', ['$event'])
onModelChange(event): void {
this.onInputChange(event, false);
}
@HostListener('keydown.backspace', ['$event'])
keydownBackspace(event): void {
this.onInputChange(event.target.value, true);
}
onInputChange(event, backspace): void {
let newVal = event.replace(/\D/g, '');
if (backspace && newVal.length <= 6) {
newVal = newVal.substring(0, newVal.length - 1);
}
this.applyMask(newVal)
}
applyMask (value): void {
if (value.length === 0) {
value = '';
} else if (value.length <= 3) {
value = value.replace(/^(\d{0,2})/, '($1)');
} else if (value.length <= 6) {
value = value.replace(/^(\d{0,2})(\d{0,3})/, '($1) ($2)');
} else if (value.length <= 12) {
value = value.replace(/^(\d{0,2})(\d{0,3})(\d{0,7})/, '($1) ($2)-$3');
} else if (value.length <= 13) {
value = value.replace(/^(\d{0,2})(\d{0,4})(\d{0,7})/, '($1) ($2)-$3');
} else if (value.length <= 14) {
value = value.replace(/^(\d{0,2})(\d{0,5})(\d{0,7})/, '($1) ($2)-$3');
} else {
value = value.substring(0, 14);
value = value.replace(/^(\d{0,2})(\d{0,5})(\d{0,7})/, '($1) ($2)-$3');
}
this.ngControl.valueAccessor.writeValue(value);
}
/** This method allows to keep the formControl value without the mask, in order to use it in backend queries */
@HostListener('input') onChange(): void {
const newVal = this.elementRef.nativeElement.value.replace(/\D/g, '');
this.ngControl.control.setValue(newVal, {
emitEvent: false,
emitModelToViewChange: false,
emitViewToModelChange: false
});
}
}