Text Component Input Patterns - like phone numbers

This came up when forcing a standard format on a phone number input.

I can force the phone number to look like (123) 456-7890 and make the user enter the parens and dash and space. What would be really nice is if the user could just type the numbers and component does the work of formatting it. I really like it when web site entry forms do this for me.

You can achieve this through the Text Input Change event.
If you go that path, I would also recommend to define it in a module to make it reusable.

formatPhoneNumber function found HERE and astonishingly works well in the Change event

function formatPhoneNumber(value) {
  if (!value) return value;
  const phoneNumber = value.replace(/[^\d]/g, '');
  const phoneNumberLength = phoneNumber.length;
  if (phoneNumberLength < 4) return phoneNumber;
  if (phoneNumberLength < 7) {
    return `(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice(3)}`;
  }
  return `(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice(3,6)}-${phoneNumber.slice(6, 10)}`;
}
textInput1.setValue(formatPhoneNumber(textInput1.value))

A format or mask property on the Text Input would be handy tho..

1 Like

@bradlymathews
If users are going to enter a phone number, you may want to capture the country they're in first so you can then determine the proper standard format. I am sure there are APIs out on the interwebs that provide the standard formats in all countries. It might seem like a lot to go through but at least the data you capture will be following a standard. Just my 2 cents. FWIW

@rferland - that certainly does work beautifully! @ScottR. Valid note, luckily this client only services the US so I'll let someone else figure that out!

For those newer to Retool, here is the exact way to implement this in two steps

  1. Put this script in the App's Javascript library (Three Dot menu on the upper right/Scripts and Styles/Javascript tab:
window.formatPhoneNumber = function(value) {
  if (!value) return value;
  const phoneNumber = value.replace(/[^\d]/g, '');
  const phoneNumberLength = phoneNumber.length;
  if (phoneNumberLength < 4) return phoneNumber;
  if (phoneNumberLength < 7) {
    return `(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice(3)}`;
  }
  return `(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice(3,6)}-${phoneNumber.slice(6, 10)}`;
}

  1. Set up the Text component's onChange handler:

txtPhone.setValue(formatPhoneNumber(self.value))

Replace txtPhone with your component's name.

On a technical side note, you may think that you can use the handler's Control Component Action rather than Run script. But you can't control a component from it's own handlers, so you are stuck with a slightly less elegant solution (IMHO.)

Repeat step 2 with every Phone and Fax field.

Now if you want this on several apps, then put the formatPhoneNumber() function in your organizations's Javascript section in Advanced Settings instead of the app's Scripts and Styles.

1 Like

Hello! Wanted to let those following this thread know that I've created a new phone number input: New Component: Phone Number Input. Let me know if you want it turned on for your org/have any feedback!

1 Like