How to apply mask to a default value in Typescript

2.3k Views Asked by At

I have a mask-phone directive that works perfectly in the input when the user write a value, but I need to set a default value and I don't know how to apply the mask directive in the component method. The value is show it in the input without the mask and only if I modify that value the mask comes.

The problem I have is that in Germany has several possibilities for a telephone number, so I can not set a specific mask in the default value, for example: (49)(170)-1111111 (49)(1514)-1111111 (49)(25679)-1111111

I wrote an example, that you can see in the follow link: https://stackblitz.com/edit/angular5-phone-mask-directive-roeqfk?file=app/app.component.ts

Thanks in advance :)

1

There are 1 best solutions below

3
Tino On BEST ANSWER

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
    });
  }
}