Regex for autoformatting a phone field as user is typing

Viewed 88

I've looked at the examples on SO, but none are really what I'm looking for.

My problem is that when a user continues to type, I try to add a space after the area code and next 3 numbers, and then a dash in-between the last 4 characters, but the country prefix disappears and the dashes disappear as well.

I'm looking for a final phone format of: +1 999 999 99-99

  • If the user types 9 (or anything else other than 1) into the empty field, then the result should be +1 9.
  • If the value is +1 999 and the user types in 9, the result should be +1 999 9
  • If value is +1 999 999 99 and the user types in 9, the result should be +1 999 999 99-9
  • If the value is +1 999 999 99-9 and the user clicks backspace, the result should be +1 999 999 99
  • If the value is +1 9 and the user clicks backspace, the result should be ''

Here's my attempt that I've got on JSFiddle.

const onKeyup = (e) => {
    const input = document.getElementById('input');
  const value = input.value;
  
  let _value = value;
  if (_value.length === 1) {
    _value = `+1 (${value}`;
  } else {
    _value.replace(
      /(\d{1,2})(\d{1})?(\d{1,2})?(\d{1,4})?/,
      function(_, p1, p2, p3, p4) {
        let output = ""
        if (p1) output = `${p1}`;
        if (p2) output += `${p2}`;
        if (p3) output += ` ${p3}-`
        if (p4) output += ` ${p4}`
        _value = output;
      }
    );
  }
  input.value = _value
}
2 Answers

I managed to do that without regex, I know that's not what you've asked but I'll post my solution anyways. Consider however that you should try and avoid regex if a native solution is possible since regex is pretty old and slow compared to vanilla code.

const onKeyup = (e) => {
    const input = document.getElementById('input');
  const value = input.value;
  
  let _value = value;
  if(e.keyCode != 8) {
    if(_value.length == 1)
      _value = `+1 ${_value}`;
    else if(_value.length == 6 || value.length == 10)
      _value = _value + ' ';
    else if(_value.length == 13)
      _value = _value + '-'
  }
    
  input.value = _value
}

const input = document.getElementById('input').addEventListener('keyup', onKeyup)
<input id="input" onkeyup="onKeyup()" />

Also if you call the function from HTML the event parameter won't be passed, so you have to add a listener from javascript.

Hope this helps. Obviously this is a barebone script but you might use this as a starting point.

As you're asking for e regex solution, here's a modification of your script that I assume gives you the result that you desire. In case that the user enters unnecessary characters at the end of the string that don't match the phone number pattern, it's removing those too:

const onKeyup = (e) => {
    const input = document.getElementById('input');
    const value = input.value;

    let _value = value;
    if (_value.length === 1 && _value != '1' && _value != '+') {
        _value = `+1 ${value}`;
    } else if (_value.match(/[+]\d\s*$/)) {
        _value = ""
    } else {
        _value = _value.replace(
            /([+]\d)\s*(\d{1,3})?\s*(\d{1,3})?\s*(\d{1,2})?-?(\d{1,2})?.*/,
            function(_, p1, p2, p3, p4, p5) {
                let output = ""
                if (p1) output = `${p1}`;
                if (p2) output += ` ${p2}`;
                if (p3) output += ` ${p3}`;
                if (p4) output += ` ${p4}`;
                if (p5) output += `-${p5}`;
                return output;
            }
        );
    }
    input.value = _value;
}
Related