skip to Main Content

I’m trying to format a phone number as a user types, and I’ve almost got it, but I just can’t seem to bring it home.

Here’s what I’m looking for:

+12345678900 --> +1 (234) 567 89-00
+1234567890  --> +1 (234) 567 89-0
+123456789   --> +1 (234) 567 89-
+12345       --> +1 (234) 5
+123         --> +1 (23

Here’s my approach:

'+12345678900'
    .replace(
        /^(+d{1})?(d{1,3})?(d{1,3})?(d{1,2})?(d{1,2})?$/,
        "$1 ($2) $3 $4-$5"
    ); // +1 (234) 567 89-00 ✔️

It works with a full number, but fails for other cases, here are some of them:

+12345678 // expected '+1 (234) 567 8', received '+1 (234) 567 8-'
+1234567  // expected '+1 (234) 567',   received '+1 (234) 567 -'
+123      // expected '+1 (23',         received '+1 (23)  -'

What am I missing here?

2

Answers


  1. You can use a replacement function in your replace method. With this you can build your string based on your required conditions:

    function numberFormatter(number) {
      return number.replace(
        /^(+d{1})(d{1,3})?(d{1,3})?(d{1,2})?(d{1,2})?$/,
        (match, p1, p2, p3, p4, p5) => p1 + ' ' + (p2 ? '(' + p2 + (p2.length > 2 ? ')' : '') : '') + (p3 ? ' ' + p3 : '') + (p4 ? ' ' + p4 + (p4.length > 1 ? '-' : '') : '') + (p5 ? p5 : '')
      )
    }
    
    // Utils
    
    // Tests which worked from your code
    expect("+12345678900", "+1 (234) 567 89-00")
    expect("+1234567890", "+1 (234) 567 89-0")
    expect("+123456789", "+1 (234) 567 89-")
    expect("+12345", "+1 (234) 5")
    
    // Tests which work now
    expect("+12345678", "+1 (234) 567 8")
    expect("+1234567", "+1 (234) 567")
    expect("+123", "+1 (23")
    
    function expect(input, expectedResult) {
      const formattedNumber = numberFormatter(input)
      if (formattedNumber === expectedResult) {
        console.log(`PASSED: "${input}" -> "${expectedResult}"`);
      } else {
        console.error(`FAILED: "${input}" -> Expected: "${expectedResult}", Received: "${formattedNumber}"`);
      }
    }

    Off-topic: I was a little confused by your requirements. I think the replacements will make more sense:

    +1 (234) 567 89     -> +1 (234) 567 89  instead of +1 (234) 567 89-
    +1 (23)             -> +1 (23)          instead of +1 (23
    
    Login or Signup to reply.
  2. Don’t reinvent the wheel. Look into Google’s LibPhonenumber, which has a javascript implementation and does ‘As you type’ formatting. You can try the demo here.

    Output for your example:

    ****Parsing Result:****
    {"country_code":1,"national_number":2345678900,"raw_input":"+12345678900 ","country_code_source":1}
    
    ****Validation Results:****
    Result from isPossibleNumber(): true
    Result from isValidNumber(): true
    Result from isValidNumberForRegion(): false
    Phone Number region: US
    Result from getNumberType(): FIXED_LINE_OR_MOBILE
    
    ****Formatting Results:**** 
    E164 format: +12345678900
    Original format: +1 234-567-8900
    National format: (234) 567-8900
    International format: +1 234-567-8900
    Out-of-country format from US: 1 (234) 567-8900
    Out-of-country format from Switzerland: 00 1 234-567-8900
    Format for mobile dialing (calling from US): +1 234-567-8900
    Format for national dialing with preferred carrier code and empty fallback carrier code: (234) 567-8900
    
    ****AsYouTypeFormatter Results****
    Char entered: + Output: +
    Char entered: 1 Output: +1
    Char entered: 2 Output: +1 2
    Char entered: 3 Output: +1 23
    Char entered: 4 Output: +1 234
    Char entered: 5 Output: +1 234-5
    Char entered: 6 Output: +1 234-56
    Char entered: 7 Output: +1 234-567
    Char entered: 8 Output: +1 234-567-8
    Char entered: 9 Output: +1 234-567-89
    Char entered: 0 Output: +1 234-567-890
    Char entered: 0 Output: +1 234-567-8900
    Char entered:   Output: +12345678900 
    

    This works for all (most?) countries and ensures you use a formatting that is globally used. If I’m not mistaken it is used in Android phones and most certainly in lots of other projects and I think it can be considered a de facto standard for formatting numbers.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search