Take my advice: Use a single field to represent complex numbers!

When creating data entry applications, it is often tempting to represent complex numbers – such as Social Security numbers and telephone numbers – as multiple text boxes, like this:

image

The thought is that this simplifies data entry by allowing the end-user to focus on the numbers, not the formatting. Sounds good. But, I’m here to tell you that I have been down this road. It is paved with good intentions. But, you do not want to end up where it will take you.

For brevity, let’s just cut to my preferred solution:

  1. Use a single text box to represent the complex number
  2. Use a RequiredFieldValidator to ensure that users don’t skip the field (if necessary)
    • With multiple fields, you’d have to write your own custom validator control.
  3. Use a RegularExpressionValidator to ensure that the data is in an acceptable format
    • You could split the regular expression into three shorter regular expressions, I suppose. But, why would you want to edit the working regex you grabbed off the Intertubes? That would require you to understand the thing!

The advantages of this approach are:

  1. Users can enter raw numbers or formatted text (which helps when the user is trying to copy/paste)
  2. Users can copy/paste in one shot
  3. Users don’t have to tab between extra fields
  4. Users can use Backspace and arrow keys to fix typos (without tabbing/clicking around)
  5. Programmers don’t have to write code to parse/concatenate the fields
  6. Programmers don’t have to write custom validator code

Everybody wins! And, just to prove how simple it is, here’s the code for Social Security Numbers and North American telephone numbers:

Social Security Numbers

<asp:Label ID="SSNLabel" runat="server" Text="SSN:"/>
<asp:TextBox ID="SSNTextBox" runat="server"/>
<asp:RequiredFieldValidator runat="server" Display="Dynamic"
  ID="SSNRequiredFieldValidator" 
  ControlToValidate="SSNTextBox" 
  ErrorMessage="SSN is a required field."/>
<asp:RegularExpressionValidator runat="server" Display="Dynamic"
  ID="SSNRegularExpressionValidator" 
  ControlToValidate="SSNTextBox" 
  ErrorMessage="Please enter a valid SSN." 
  ValidationExpression="^\d{3}[- ]?\d{2}[- ]?\d{4}$"/>

Note: The regular expression above allows formatted SSNs as well as raw numbers. Spaces and hyphens are considered acceptable delimiters, but are not required.

North American Telephone Numbers

<asp:Label ID="PhoneNumberLabel" runat="server" Text="Phone Number:"/>
<asp:TextBox ID="PhoneNumberTextBox" runat="server"/>
<asp:RequiredFieldValidator runat="server" Display="Dynamic"
  ID="PhoneNumberRequiredFieldValidator" 
  ControlToValidate="PhoneNumberTextBox" 
  ErrorMessage="Phone number is a required field."/>
<asp:RegularExpressionValidator runat="server" Display="Dynamic"
  ID="PhoneNumberRegularExpressionValidator" 
  ControlToValidate="PhoneNumberTextBox" 
  ErrorMessage="Please enter a valid phone number, including area code." 
  ValidationExpression="^(?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}[- ]?)[2-9]\d{2}[- ]?\d{4}$"/>

Note: The North American Numbering Plan (NANP) specifies that the area code and prefix must not begin with 0 or 1, for obvious reasons. The regular expression above validates this. It also handles complex formats as well as raw numbers. Spaces and hyphens are considered acceptable delimiters, but are not required. The area code may or may not be wrapped in parentheses, and may or may not include a space (but not a hyphen) after the trailing parenthesis.