15

I have seen many solutions to formatting a phone number input field in Angularjs, but I cannot find anything on Angular 7. What I essentially want is for the user to type the following in the textfield:

123456789

and for the textfield to format the input as:

(123) 456-789

how can I go about doing this? I have found the following regex to validate it:

^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$

3 Answers 3

21

You can handle this with a Phone Mask Directive as follows,

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) {
    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');
    } else {
      newVal = newVal.substring(0, 10);
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(\d{0,4})/, '($1) $2-$3');
    }
    this.ngControl.valueAccessor.writeValue(newVal);
  }
}

STACKBLITZ DEMO

Sign up to request clarification or add additional context in comments.

2 Comments

I have one issue with this. On chrome, when you let it auto fill out the field, and immediately get the value, it is not formatted, although it looks like it is formatting. However, if you change the value, than it will work Any thoughts?
is there any way so that selection for cursor do not shift at last place while removing any digit from input value ?
16

You can easily install ngx-mask package and then specify your ideal mask like this:

mask="(000) 000-000"

< input type="text" mask="(000) 000-000" />

Comments

0

The best approach would be to format with the libphonenumber-js library.

It provides many useful methods:

const phoneNumber = parsePhoneNumber(' 1 (800) 555-35-35 ', 'US')
const phoneNumber = parsePhoneNumberWithError('+18000000000');
const isPossible = fullFormat.isPossible();
if(!isPossible) {
  // handle error
  return;
}
const valid = fullFormat.isValid();
if(!valid) {
  // handle error
}

It also lets you validate and format partial phone numbers by using the AsYouType class:

const asYouType = new AsYouType({ defaultCountry: 'US' });
const formatted = asYouType.input('3323333333');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.