javascriptjquerymask

Phone Number Masking (Without Plugin)


I'm trying to do phone masking using the example in this link, but without success.What I want to do is remove the parentheses and reorder.

Rule: the first character is always 5. In the form of 3 3 2 2, example: 532 123 45 67

const $input = document.querySelector('[data-js="input"]')
$input.addEventListener('input', handleInput, false)

function handleInput (e) {
  e.target.value = phoneMask(e.target.value)
}

function phoneMask (phone) {
  return phone.replace(/\D/g, '')
    .replace(/^(\d)/, '($1')
    .replace(/^(\(\d{3})(\d)/, '$1) $2')
    .replace(/(\d{3})(\d)/, "$1-$2")
    .replace(/(-\d{4})\d+?$/, '$1');
}

Sorry for misreporting blocks in the first post. No new character entry should be allowed upon completion.

The blocks will be as follows: 3 3 2 2 / Example : 532 123 45 67


Solution

  • Regex can be tricky but I love how nice is the result :)

    function phoneMask (phone) {
      return phone.replace(/\D/g, '')
        .replace(/(^[^5])/, '')
        .replace(/(\d{3})(\d)/, '$1 $2')
        .replace(/(\d{3}\s\d{3})(\d{1,2})/, '$1 $2')
        .replace(/(\d{3}\s\d{3}\s\d{2})(\d{1,2})/, '$1 $2')
        .replace(/(\d{3}\s\d{3}\s\d{2}\s\d{2})\d+?$/, '$1')
    }
    

    Explained steps:

    1. To only allow numbers, replace non-digits with empty string: .replace(/\D/g, '')
    2. Allow only 5 at the beginning, so replace first digit which isn't 5 by empty string: .replace(/(^[^5])/, '')
    3. Make 2 groups: the first with 3 digits and add a space between them: .replace(/(\d{3})(\d)/, '$1 $2')
    4. After having 3-space-3 digits, add another space between that group and the rest: .replace(/(\d{3}\s\d{3})(\d{1,2})/, '$1 $2')
    5. After having 3-space-3-space-2 digits, add another space between that group and the rest: .replace(/(\d{3}\s\d{3}\s\d{2})(\d{1,2})/, '$1 $2')
    6. Once the sequence 3-space-3-space-2-space-2-digits is completed, end string: .replace(/(\d{3}\s\d{3}\s\d{2}\s\d{2})\d+?$/, '$1')