Make a user input phone number display as (xxx) xxx-xxxx on entry.

Hi,

I have a user input field for users to leave their phone number. When entered into the field a 9 digit phone number (1234567890 for example) will be displayed as 9 consecutive numbers like 1234567890. I want to have it so that after a user types that number into the field, the numbers adjust and display as (123) 456-7890 NOT 1234567890.

Any help would be greatly appreciated!

Thanks,
Anney

Assuming you want the format “(123) 456-7890”:

function formatPhoneNumber(phoneNumberString) {
  var cleaned = ('' + phoneNumberString).replace(/\D/g, '')
  var match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/)
  if (match) {
    return '(' + match[1] + ') ' + match[2] + '-' + match[3]
  }
  return null
}

Here’s a version that allows the optional +1 international code:

function formatPhoneNumber(phoneNumberString) {
  var cleaned = ('' + phoneNumberString).replace(/\D/g, '')
  var match = cleaned.match(/^(1|)?(\d{3})(\d{3})(\d{4})$/)
  if (match) {
    var intlCode = (match[1] ? '+1 ' : '')
    return [intlCode, '(', match[2], ') ', match[3], '-', match[4]].join('')
  }
  return null
}
formatPhoneNumber('+12345678900') // => "+1 (234) 567-8900"
formatPhoneNumber('2345678900')   // => "(234) 567-8900"

Hi,

Thank you for helping me with this. I plugged in the code (the first one) but when I put in a phone number it doesn’t change the number to the format. Anything else I need to put in? Does the code need a trigger?

any help for how to use this code? Still haven’t been able to get it to work.
Thank you!

Hi Anney
What you need to do is call the function that Carlos shared above in an event handler attached to the element that takes in the phone number.

There are a couple of ways to do this.

  1. If you use a button to accept the number then you implement the button’s onClick handler that gets the value from the phone number element, calls the formatPhoneNumber() function then assigns the result back to the phone number element value property.

  2. You can implement an onChange handler to the phone number element. This will fire when you click outside of the phone number input field. When it fires you can do the same thing as in 1. It depends on the effect you would like.

  3. You can also implement an onKeyChange event handler and process the input value as described in 1. if the key pressed is “Enter”.

Check this out

Steve

Thanks for the help Steve, but I still can’t seem to get it to work. How do I call this specific function for onChange? I put the code in the onChange event handler with no success.

Hi Anney
Take a look at this video:

Then select the textInput box that you want to attach the event handler to then right click on it and select properties. This will show the properties associated with the textInput element that you have selected. It should look like the one in the video.

You will see several on properties. Some or all of the ones I mention above will be present. Click the blue add button next to the handler you want to use. Then hit return(enter).

As shown in the video a function will be added for you in the page code section.

This is where you can add the formatPhoneNumber function.

If you are still having problems please share the published url for the page and any forum developer can take a look to try to debug the problem.

Hope that helps
Steve

Hi Steve,

I know how to get the event up, but when I put the function code in, nothing happens. The code I have looks like this right now:

export function input44_change(event) {
//Add your code for this event here:

function formatPhoneNumber(phoneNumberString) {
var cleaned = (‘’ + phoneNumberString).replace(/\D/g, ‘’)
var match = cleaned.match(/^(1|)?(\d{3})(\d{3})(\d{4})$/)
if (match) {
var intlCode = (match[1] ? ‘+1 ’ : ‘’)
return [intlCode, ‘(’, match[2], ‘) ‘, match[3], ‘-’, match[4]].join(’’)
}
return null
}
formatPhoneNumber(’+12345678900’) // => “+1 (234) 567-8900”
formatPhoneNumber(‘2345678900’) // => “(234) 567-8900”
}

Input 44 is the user phone number input.

could it be a code problem perhaps?

Thanks,
Anney

Hi Anney:
It appears that you have muddled up your function definitions.

You need to declare the formatPhoneNumber function before or after the change function. Then you call it in the change function…

export function input44_change(event) {  
    clearError();
    let number = $w('#phoneNumber').value;
    number = formatPhoneNumber(number);
    if (number) {
        $w('#phoneNumber').value = number;
    }
}

function formatPhoneNumber(phoneNumberString) {
    let result = null;
    var cleaned = phoneNumberString.replace(/\D/g, '');
    if (cleaned.length >= 10 && cleaned.length <= 12) {
        var match = intlMatch(cleaned);
        if (match) {  
            var intlCode = (match[1] ? '+'+match[1]+' ' : '');
            if (! match[1] || match[1] === '1') {
                // US Format
                match = usMatch(match[2]);
                result =  [intlCode, '(', match[1], ') ', match[2], '-', match[3]].join('');
            } else if (match[1] === '44') {
                // UK format
                match = ukMatch(match[2]);
                result =  [intlCode, '(', match[1], ') ', match[2], ' ', match[3]].join('');
            } else {
                // Generic format
                match = genericMatch(match[2]);
                result =  [intlCode, ' ', match[1], '  ', match[2], ' ', match[3], '  ', match[4], ' ', match[5]].join('');
            } 
        }
    } else {
        // Error wrong number of digits should be 10, 11 or 12
        console.log("Badly formatted phone number!");
    }
    return result;
} 

function intlMatch (matchString) {
    return matchString.match(/^(\d{0,2})?(\d{10})$/);
}

function usMatch (matchString) {
    return matchString.match(/^(\d{3})(\d{3})(\d{4})$/);
}

function ukMatch (matchString) {
    return matchString.match(/^(\d{4})(\d{3})(\d{3})$/)
}

function genericMatch (matchString) {
    return matchString.match(/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/);
}


The above code should do what you want. Note I have also provided some optional formats for numbers that are not US Format. I have have also added an error console.log for badly formatted phone numbers. This could be written to a text element on screen if you want to. Here is an articvle on formattnig international phone numbers if you are interested.

Cheers
Steve

Thank you so much Steve! This was super helpful!!

Hey Steve,

This code is awesome! It works perfectly for an “onChange” event! I was wondering, however, is there any chance you might know how to make it work for “onKeypress”? I can’t get it so that it replaces the values to the (XXX) XXX-XXXX format as the user types. Any thoughts?

Thanks,
Anney

You have this right now

export function input44_change(event) { 
clearError(); let number = $w('#phoneNumber').value;    
 number = formatPhoneNumber(number); 
 if (number) { $w('#phoneNumber').value = number; 
 }
   }

When you insert your onKep press you’ll see where it says “Enter your code here” just paste this

clearError(); let number = $w('#phoneNumber').value;      number = formatPhoneNumber(number); if (number) { $w('#phoneNumber').value = number; }

And remove what is above

Hi,

Thanks for the tip. This works by the end, but is there any way to adjust the code as you enter the phone number?

@anneynorton7 Hi Anney: That could be pretty complex code. Not impossible but may not deliver a good user experience.

Steve

@stcroppe Thought as much. Thanks Steve!

What if I have a Dynamic Item Page and a text element connected to the Database is getting a “number” value (not a string) and all I want to do is add a coma to emphazise the thousands? I would like to show it as a price, for example number = 10000 and show “10,000” @stcroppe
I figured I could add a _viewportEnter(event) to make the function run and use $w(‘#textElement’).text = “”; to update the value of the text element, but I don’t konw how to convert the number to a string and how to format it to add the coma.

Hi Soltrance
the way you would do this is to loop through the number dividing by 1000. Then building your string by prepending the remainder to the result string inserting the comma if your base number exceeds 1000.

Something like this
let workingValue = 234567890;
let formatString = ‘’;

while (workingValue > 1000) {
let remainder = workingValue % 1000;
let workingValue /= 1000;
formatString = “,”+remainder.toString() + formatString;
}
formatString = workingValue.toString() + formatString;
console.log(formatString);

@stcroppe your code returns “234.56789, 567.890000000014, 890”, but thanks to you I realized how to do it.
This would work for numbers under 1 million:

let fullNumber = 18500 // Example number
let formatString = ‘’;

if (fullNumber > 999) {
let lastNumber = fullNumber % 1000; // Gets the last 3 numbers: 500
let firstNumber = fullNumber / 1000; // 18.5
let firstNumberShort = Math.floor(firstNumber); // Rounds down: 18.5 becomes 18
if (lastNumber === 0) {
formatString = firstNumberShort.toString() + “,000”;
}
else {
formatString = firstNumberShort.toString() + “,” + lastNumber.toString();
}
}
console.log(formatString); // testing result in console = 18,500

@solisaguero
Good catch, yes I should have rounded the division result down - the perils of responding late at night with untested code. The reason I added the caveat “something like this”.

Im glad you figured it out from there.

Steve

It seems like you solved it, yet try this, or to anyone trying to do something similar:

$w.onReady(function () {

 const locale = ("en-US");

$w("#dynamicDataset").onReady(() => {

 let itemObj = $w("#dynamicDataset").getCurrentItem();

   $w("#textElement").text = itemObj.fieldKey.toLocaleString(locale);
  }
 
});
 
});

Basically, this returns the string based on a language. Use your dataset name, text element, and the fieldKey that holds the number. The benefit? You can make it work with dates, time, and it is pretty straight forward.