I'm trying to simply format a phone number following this format (123) 456-7890. On React it would be very easy to get the value on an
<input>
with the
onChange()
method and state and format as the user enters the value.
Is it possible to get live values as a user enters it with field hooks or the only solution would be to create a custom component?
Yes a custom component is the way to do it
I have made this plugin here to help with that, use the plugin or copy the code into your own project
https://github.com/NouanceLabs/payload-better-fields-plugin?tab=readme-ov-file#telephone-fieldGreat addition! Thanks!
Or more simply
hooks: {
afterChange: [(value: unknown): string => formatPhoneNumber(value as string)],
},
export function formatPhoneNumber(input: string | number): string {
const digits = input.toString().replace(/\D/g, ''); // Remove non-numeric characters
if (digits.length === 0) return ''; // No input yet
if (digits.length <= 3) return `(${digits}`;
if (digits.length <= 6) return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
}
No, saving phone number is not simple like that. I recommended:
- Use custom mask input component. Give live format when user type the phone number.
- Keep raw value or validate the value following international standard (IIRC, it is E.164) in the database. It'll scaling better when you need to support more countries, or integrate with 3rd party services. Display formatted value should be FE job.
From my experience, phone number or currency should be treated as a type not a string. Those value should have more metadata than just a string. Like: country code, how it should be formatted, how it should be validated, ...
Star
Discord
online
Get dedicated engineering support directly from the Payload team.