Form Field Phone Number Validation

TL;DR
I'm trying to add a "telephone number" field into a form, is there a component for that, similar to the Email Address? Or is there a dropdown somewhere I'm missing/something easy? If not, how would I do that?


So, this may be a newbie question... Is there any easy way to put a "phone number" field in, that I'm maybe missing? Similar to the component for Email Address, that is formatted correctly/with options.

If not, I'm assuming I would need to do something, so that users could enter their telephone number, and it would validate / format on screen correctly?

Does this make sense?

Hello @strdotmatt,

At this time, Retool doesn’t have a phone # input, but there’s a general regex validation field you can use for phone number validation.

Me and my team would love a phone input component as well!

In the meantime, you can build this out in a custom component!

It uses this library in the app settings (three dots) > Scripts and Styles > Libraries

And here's the iFrame code for the custom component:

<html>
  <body>
    <script src="https://unpkg.com/libphonenumber-js@1.9.11/bundle/libphonenumber-min.js" crossorigin></script>
     		<link rel="stylesheet" type="text/css" href="https://lemontreefoods.org/fonts.css">
    <style type='text/css'>
      body {
        margin:0;
        font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
      }
      #label {
        flex: 1;
        font-weight:500;
        display: flex;
        align-items: center;
        margin-right: 8px;
        max-height: 34px;
        font-size: 12px;
        padding-bottom: 3px;
   			margin-top: 2px;
        text-align: right;
        color:#262626;
      }
        #phone-input{
          user-select: text;
          pointer-events: auto;
          font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
          overflow: visible;
          box-sizing: border-box;
          margin: 0;
          font-variant: tabular-nums;
          list-style: none;
          font-feature-settings: "tnum";
          position: relative;
          display: inline-block;
          padding: 4px 11px;
          font-size: 12px;
          line-height: 1.5;
          background-color: #fff;
          background-image: none;
          border: 1px solid #d9d9d9;
          transition: all .3s;
          min-width: 0;
          flex: 1 0 0;
          touch-action: manipulation;
          height: 30px;
          background: #ffffffff;
          border-radius:4px;
          color: #262626ff;
          border-color: #dededeff;
        }
    </style>
    <script>

			let isFormattable = (p) =>{
        const digits = p.replace(/\D/g,'');
        return (p[0] == "1" && digits.length > 4) || (p[0] != "1" && digits.length > 3)
      }
      
      let parseAndReturn = (p) => {
        let parsedNumber = new libphonenumber.parsePhoneNumber(`phone:${p}`,'US')
        window.Retool.modelUpdate({
          raw: p.replaceAll(/[() -]/g, ""),
          is_valid: parsedNumber.isValid(),
          e164: parsedNumber.format('E.164'),
          national: parsedNumber.formatNational(),
          international: parsedNumber.formatInternational()
        })
      }

      function formatInput(e) {
        let phone = e.target.value
        
        if(isFormattable(phone)){ //prevent weird deletion bug
          phone = new libphonenumber.AsYouType('US').input(phone)
          e.target.value = phone
        }
        
        parseAndReturn(phone)
        
      }

      window.Retool.subscribe(function(model) {
        if(!('e164' in model)){
          formattedDefaultPhone = new libphonenumber.parsePhoneNumber(`phone:${model.default_phone}`,'US').formatNational()
        document.getElementById("phone-input").value = formattedDefaultPhone || '';
          parseAndReturn(model.default_phone)
        }
      })

    </script>
    <div style="display:flex;align-items: center;
  justify-content: center;">
    <label id="label"for="phone-input" style="display:inline-block; padding-right:8px">Phone</label>
    <input type="text" inputmode="tel" id="phone-input" placeholder="(555)-123-4566" onKeyUp="formatInput(event)" onBlur="formatInput(event)"></input>
<div>
  </body>
</html>

See attached app JSON if you want to poke around with my setup! You can import this JSON file by clicking Create new (home page) > From JSON. Quick docs on exporting/importing apps here.
Autoformat-20Phone-20Number-20Example.json

Here's another solution.

1 Like

Hello! Wanted to let those following 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!

2 Likes