Skip to main content

Cracking the Code For a Numeric Keyboard

02-02-12 Rob Tarr

Rob Tarr is on a mission. Destination: proper numeric keyboard.

Recently, I was asked by a client to make modifications to a form in order to make it more mobile-friendly. A simple request really. They wanted the numeric keyboard to display on mobile devices when a user tapped on fields requiring numbers (i.e. phone, date, zip code).

This seems like it should be a simple task, right? With the new HTML5 input types, I can set the input type for phone to “tel,” date to “date,” and zip to... “number?” 

Well, that almost works. <input type=“number”> will display the number keyboard, but it also throws another wrinkle into the situation. Any number entered with more than three digits has a comma added to it (depending on internationalization settings). So when I enter a zip code of 45402, the resulting text in the field is 45,402. At least, this is the case for iOS.

So began my quest. I was out to find an input that made sense and provided a numeric keyboard for mobile devices without inserting a comma into the value.

Check out the test page to see my results so far. Also, please feel free to fork the gist and add your own tests. Final thoughts are below the code example.

<!doctype html>
<html>
<head>
  <title>Number Test</title>
  <style>
    tr {
      background: #ddd;
    }
    tr:nth-child(odd) {
      background: #ccc;
    }
    td {
      border: 1px solid #bbb;
    }</style>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>Input</th>
        <th>Chrome 16 (Mac)</th>
        <th>Firefox 8 (Mac)</th>
        <th colspan="2">iOS 5</th>
        <th colspan="2">Kindle Fire</th>
      </tr>
      <tr>
        <th></th>
        <th>Comma</th>
        <th>Comma</th>
        <th>Comma</th>
        <th>Keyboard</th>
        <th>Comma</th>
        <th>Keyboard</th>
      </tr>
    <tbody>
      <tr>
        <td>
          <input type="number" value="45402">
          <pre>&lt;input type="number" value="45402"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>yes</td><td>number</td>
        <td>no</td><td>keypad</td>
      </tr>
      <tr>
        <td>
          <input type="number" value="45402">
          <pre>&lt;input type="number" value="45402"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>yes</td><td>number</td>
        <td>no</td><td>keypad</td>
      </tr>
      <tr>
        <td>
          <input type="number" value="45402" pattern="[0-9]*">
          <pre>&lt;input type="number" value="45402" pattern="[0-9]*"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>yes</td><td>keypad</td>
        <td>no</td><td>keypad</td>
      </tr>
      <tr>
        <td>
          <input type="number" value="45402" pattern="[0-9]{5}">
          <pre>&lt;input type="number" value="45402" pattern="[0-9]{5}"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>yes</td><td>number</td>
        <td>no</td><td>keypad</td>
      </tr>
      <tr>
        <td>
          <input type="number" value="45402" name="zip">
          <pre>&lt;input type="number" value="45402" name="zip"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>yes</td><td>number</td>
        <td>no</td><td>keypad</td>
      </tr>
      <tr>
        <td>
          <input type="text" value="45402" name="zip">
          <pre>&lt;input type="text" value="45402" name="zip"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>no</td><td>text</td>
        <td>no</td><td>text</td>
      </tr>
      <tr>
        <td>
          <input type="number" value="45402" name="phone">
          <pre>&lt;input type="number" value="45402" name="phone"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>yes</td><td>number</td>
        <td>no</td><td>keypad</td>
      </tr>
      <tr>
        <td>
          <input type="text" value="45402" name="phone">
          <pre>&lt;input type="text" value="45402" name="phone"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>no</td><td>text</td>
        <td>no</td><td>text</td>
      </tr>
      <tr>
        <td>
          <input type="tel" value="45402">
          <pre>&lt;input type="tel" value="45402"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>no</td><td>keypad</td>
        <td>no</td><td>keypad</td>
      </tr>
      <tr>
        <td>
          <input type="text" value="45402">
          <pre>&lt;input type="text" value="45402"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>no</td><td>text</td>
        <td>no</td><td>text</td>
      </tr>
      <tr>
        <td>
          <input type="text" value="45402" pattern="[0-9]*">
          <pre>&lt;input type="text" value="45402" pattern="[0-9]*"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>no</td><td>keypad</td>
        <td>no</td><td>text</td>
      </tr>
      <tr>
        <td>
          <input type="text" value="45402" pattern="[0-9]{5}">
          <pre>&lt;input type="text" value="45402" pattern="[0-9]{5}"></pre>
        </td>
        <td>no</td><td>no</td>
        <td>no</td><td>text</td>
        <td>no</td><td>text</td>
      </tr>
      <tr>
        <td>
          <input type="text" value="45402" pattern="[0-9]{5}(-[0-9]{4})*">
          <pre>&lt;input type="text" value="45402" pattern="[0-9]{5}(-[0-9]{4})*"></pre>
        </td>
        <td>no</td><td></td>
        <td>no</td><td>text</td>
        <td>no</td><td>text</td>
      </tr>
      <tr>
        <td>
          <input type="pc" value="45402">
          <pre>&lt;input type="pc" value="45402"></pre>
        </td>
        <td>no</td><td></td>
        <td>no</td><td>text</td>
        <td>no</td><td>text</td>
      </tr>
      <tr>
        <td>
          <input type="date" value="45402">
          <pre>&lt;input type="date" value="45402"></pre>
        </td>
        <td>no</td><td></td>
        <td>--</td><td>Date dropdown</td>
        <td>no</td><td>text</td>
      </tr>
    </tbody>
  </table>
</body>

The only input type that really gets me what I want is <input type=“tel”>. However, it feels wrong to use this for non-telephone numbers. I just can’t bring myself to do it. This leaves me with <input type=“text” pattern=“[0-9]*“>, which provides zip codes that look right and numeric keyboards in iOS. Sorry, Android users—we’ll hopefully figure out something better that includes you soon.

If you have other suggestions, I’m open. Feel free to add to the gist if you have other input ideas.

Also, check out what Brad Frost wrote on this topic.

Related Content

User-Centered Thinking: 7 Things to Consider and a Free Guide

Want the benefits of UX but not sure where to start? Grab our guide to evaluate your needs, earn buy-in, and get hiring tips.

More Details

See Everything In

Want to talk about how we can work together?

Katie can help

A portrait of Vice President of Business Development, Katie Jennings.

Katie Jennings

Vice President of Business Development