Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML5

HTML5 in Action: Changing the Face of Web Forms with New Input Types

5.00/5 (4 votes)
9 Dec 2011CPOL20 min read 42.1K  
A chapter excerpt from HTML5 in Action
image002.jpgHTML5 in Action

By Robert Crowther, Joe Lennon, and Ash Blue

Previous versions of HTML gave you ten different input types to use. The problem with those types? They lack features for inputting data types like numbers, dates, colors, email addresses, and URLs. This article, based on chapter 2 of HTML5 in Action, introduces you to the 13 new types defined by HTML5 to solve this problem—and all without JavaScript.

You may also be interested in…

The <input> element is used in HTML to add fields like text boxes, check boxes, and radio buttons to a form. The type attribute is used to indicate to the browser what type of form control should be displayed to the user. In previous versions of HTML, there were ten different types that could be used, as outlined in table 1.

Table 1 Valid input type values in previous versions of HTML

Button checkbox file hidden Image
password radio reset submit Text

The problem with the types in table 1 is that they don’t offer any features for inputting data types like numbers, dates, colors, email addresses, and URLs. Sure, you could just use a standard text input, but you would then need to use JavaScript to validate the data type on the client side. If JavaScript is turned off, this validation won’t take place. To solve this problem, HTML5 defines thirteen new input types, as shown in table 2.

Table 2 New input type values introduced in HTML5

Color Date datetime datetime-local Email
Month Number range search Tel
Time url week    

In this article, you will learn about each of these new input types, how they look in browsers that have implemented them, and the benefits they provide over using the basic text input type. You will also use them in a sample Registration Form.

email, url, and tel

One of the most common uses of text fields in Web forms is to ask the user to enter their email address. Whether it is used in a registration form, contact form, user login, subscribing to a newsletter, or posting a comment on a blog post, email address input is required in the majority of forms on the Web. Of course, all email addresses must adhere to a certain format in order to be deemed valid, and in most cases developers use some form of JavaScript regular expression testing to check the validity of email address on the client side. The problem with this is that different people have different opinions of what constitutes a valid email address and, as a result, developers use a widely varying range of different patterns in their validation routines. HTML5 eradicates this problem by passing responsibility for validating email addresses to the browser itself.

Warning

You should never rely solely on client-side validation, as a malicious user can very easily bypass it. Your applications should always provide solid server-side validation at the backend, with client-side validation only used to enhance the user experience (and to reduce the load of invalid requests being sent to the server).

Using the email input type is extremely straightforward (as is using most of the new HTML5 input types). It works exactly the same as a regular text input but, instead of using type="text", you use type="email" instead.

<input type="email"
name="email_address">

Easy, right? When you view an email input field in a compatible browser, it doesn’t actually look different from a regular HTML text input. In fact, if you view it in any browser, it will just appear as a standard text box. One of the nice things about the new input types is that, if a browser doesn’t recognize them, it will just display a normal text input field instead, so you can safely add these new fields to your applications today, without worrying about their wreaking havoc in older browsers.

At this point, you might be wondering, "What is the point of this new input type if it just looks like a standard text input?" The real power behind the email type is that, by default, a compatible browser will check that the value of the field is a valid email address when the form is submitted. If the field value is invalid, form submission will be stopped and an error message will be displayed to the user, with zero JavaScript code required to do so. Figure 1 shows this error message in several different Web browsers.

image003.jpg

Figure 1 Native email address validation in Opera 11.50, Google Chrome 12 and Mozilla Firefox 5.01

In addition to the new email input type, there are two similar new types: url and tel. The url type behaves the exact same way as the email type, albeit displaying a different error message to denote that the user has entered an invalid URL. The following code is an example of how you can use the url type in HTML5.

<input type="url"
name="web_site_address">

The tel input type is intended to allow users to enter telephone numbers. Unlike email and url, however, browsers don’t natively validate tel input fields because there is no single valid structure for a telephone number. One website might require the user to enter a full telephone number with an international dialing code and area code; others might just want the area code. On top of this, different locales may present phone numbers in different ways. You can use the tel input type as follows.

<input type="tel" name="phone_number">

So, if the tel input type doesn’t provide enhanced functionality using validation, then what benefits does it provide over a standard text input? One of the primary reasons for using this input type is that on devices with virtual keyboards such as smartphones, the browser may display a different keyboard to the user depending on the type of input field they are using. This also applies to the email and url input types. For example, when you are entering a value in an email input type on an iOS device, the spacebar on the keyboard is made much smaller, and beside it you will find buttons for the "@" and "." symbols to make it easier to enter email addresses. For url fields, the spacebar is removed altogether and replaced with buttons for ".", "/" and ".com". In the case of tel fields, the standard keyboard is completely replaced with a numeric keypad, with easy access to symbols commonly used in phone numbers like "+", "*" and "#". You can see examples of these changes in figure 2.

image004.jpg

Figure 2 Different virtual keyboards are displayed on an iPhone for different input types—from left to right: "text", "email", "url" and "tel"

Tip

You may have noticed that in the code examples that we are using the <input> element without a terminating slash (like <input />). This syntax was introduced in XHTML and is no longer a requirement in HTML5. Both methods are valid, so if you prefer the XML-style convention, feel free to keep using it in your own applications.

number and range

In HTML 4 and XHTML, when you needed numeric data input, you were forced to use a standard text input element and validate the data using JavaScript. In addition, if you wanted to provide the user with a different user interface for a number field, such as a spinner or a slider, you had to rely on third party UI frameworks. In HTML5, there are two new input types for numeric data entry, number and range. Both of these fields have virtually the same markup and set of accompanying attributes, but they differ in terms of the UI widget that is rendered by the browser. In the case of the number field, you can expect supporting browsers to display a spinner. For example, the following code:

<input type="number" name="mynum">

produces a spinner like the one shown in figure 3.

Note

Mozilla Firefox (up to and including version 6.0.1, at least) does not support the number input type or any of its attributes. To add support for HTML5 form features (such as a spinner widget and numeric validation), you can use a polyfill.

image005.jpg

Figure 3 Spinner widget in Opera on Mac OS X for a number input field

The range input also stores a number value, but it displays a slider widget to the user instead. The following code:

<input type="range" name="mynum">

produces a slider as shown in figure 4.

image006.jpg

Figure 4 Slider widget in Google Chrome on Mac OS X for a range input field

If you use a number or range field as illustrated previously, you won’t get an error message when you enter an invalid number in the field (although Google Chrome will actually convert non-numeric values to numeric on the fly as you tab through the form). However, only a valid number value will be submitted to the server by the form. For example, if you enter the value "3259a" in a number input field and submit the form, the value sent to the server will be "3259". If you enter the value "a3259;" however, the value sent will be an empty string. When you think about why the browser doesn’t validate by default, it makes a lot of sense because there are so many different ways to represent a numeric value. Negative values, zero values, fractions, decimals—how does the browser determine what is valid and what is not? Instead, you need a way of telling the browser what should constitute a valid number. Fortunately, this is very straightforward in HTML5 because both the number and range input types support three new accompanying attributes that allow you to define the properties for checking that a number is valid: min, max and step.

As you might expect, the min attribute is used to specify the lowest acceptable value that should be allowed in the field. Similarly, the max attribute is used to specify the maximum acceptable value allowed. The step attribute allows you to set what values will be deemed acceptable between the min and max attributes. For example, if you have the following number input:

<input type="number" name="mynum"
min="0" max="50" step="10">

The acceptable values will be 0, 10, 20, 30, 40, and 50. The step attribute can also be a decimal number. For example, take the following range input:

<input type="range" name="mynum"
min="0" max="1" step="0.2">

In this case, the acceptable values will be 0, 0.2, 0.4, 0.6, 0.8, and 1. With the range input type, the user won’t be able to enter an invalid value as the user is presented with a slider. But with the number input type, the user can either enter the value as text or can change the value using the spin controls. If the user enters an invalid value in the text box and tries to submit the form, the browser will cancel the submit event and display an error message to the user. Figure 5 illustrates an example of the type of error message you can expect to see.

image007.jpg

Figure 5 The browser (in this case Opera) will validate the number and display an error message like the one shown if it is not valid.

Warning

Safari 5.1 has partial support for the number input type. It will display the field with a spinner widget, but it will not validate the number against the values in the min, max, and step attributes. These attributes do work correctly in the range input type, however.

In addition to providing a new UI widget and validation attributes for number fields, HTML5 also defines three JavaScript APIs for interacting with number fields—stepUp, stepDown, and valueAsNumber. The stepUp method allows you to increase the value of the field by incrementing it by a defined number of steps. You pass the number of steps as an argument to the method. Say, you have a number field named mynum with the step attribute value set to 10, and the current value of the field is 0. Executing document.forms.myform.mynum.stepUp(2) will increase the value of the field to 20. The stepDown method works the same way, but in reverse.

Warning

You must be careful when using stepUp and stepDown, as trying to step up or down outside the upper and lower bounds set by the min and max attributes will raise an INVALID_STATE_ERR exception. Another gotcha is that if you attempt to execute these methods when the field is empty, you will also raise this exception.

The valueAsNumber method allows you to get the value of the field as a floating-point number (unlike the value property of the element, which is always a string). If you use the valueAsNumber method on a field that contains non-numeric characters, it will return NaN (Not a Number).

date, datetime, time, datetime-local, month, and week

If you have ever booked a flight or made a hotel reservation online, you’ve  come across a date picker widget, which allows you to select the date you want to book on an easy-to-use calendar that allows you to quickly and easily jump between months and years. Nearly every website that uses date pickers seems to use a different variant, be it one that is included with a JavaScript UI library such as ExtJS or YUI, from a server-side development framework like ASP.NET, or just a standalone widget that the site’s developers found on the Web or built themselves. There are a number of issues with this: the first is a lack of consistency. Some pickers will open in new browser windows as popups, others will appear over the page content, and some will even show inline in the form itself (yuck!). Another problem is that almost all of these widgets (at least every one we have come across) require JavaScript in order to function. The site doesn’t necessarily break without it (you can just enter a date in the textbox instead), but you won’t be able to use the date picker unless your browser supports and has JavaScript switched on.

To get around these problems, HTML5 defines a series of new date and time related input types that can be used to enter dates in Web forms. Unfortunately, browser vendors have been slow to add support for these new input types, and the only browser that currently provides a date picker for these elements is Opera (version 9 and later). Google Chrome has partial support for date types, oddly showing a spinner control (like used in the number input type) instead. Chrome will validate that the value is a valid date on submit, however. Apple Safari is one step back, implementing the same spinner control, but not validating the value at all.

Using the date input type is straightforward, as shown in the following snippet:

<input type="date"
name="date_of_birth">

In Opera, this code will produce a drop-down box which, when opened, will display a date picker widget rather than a list of values, as shown in figure 6.

image008.jpg

Figure 6 The native date picker widget in Opera 11 for Mac

In Google Chrome, that same code will produce a spinner widget, which steps up and down through dates rather than numbers. Chrome will also validate that the date entered is a valid date when the user submits the form, as shown in figure 7.

image009.jpg

Figure 7 Date validation in Google Chrome

The format used for the date input type is YYYY-MM-DD. Other date formats are based on local conventions (for example, DD/MM/YYYY is used in the UK and Ireland, while MM/DD/YYYY is used in North America). Trying to account for various local variants would be a nightmare, so the ISO 8601 standard for Gregorian calendars is used instead. In addition to the standard date input type, HTML5 also defines a series of other date/time related types:

  • datetime: The same as date, but also allows you to select a time (with timezone).
  • datetime-local: The same as datetime but without the timezone.
  • time: The same as datetime-local but without the date segment.
  • month: The same as date, but only selects a month/year, not a day; an example of the value of a month input type is 2011-07 (July 2011).
  • week: The same as date, but selects only a week/year, not a day; an example of the value of a week input type is 2011-W28 (Week 28 in 2011).

In addition to the new input types, HTML5 also specifies a new API method, valueAsDate, which allows you to get the value of an input field as a Date object. This method is useful if you want to do more complex validation with your dates. For example, you might allow the user to select a start date and end date in your form. Of course, the end date should be a date on or after the start date. In the past, you would have had to get the value of the form field and construct a Date object from that value. Now, you can use the valueAsDate method to get a Date object straight from the field itself.

search and color

On most dynamic Web sites and applications, you will find some form of search box that allows you to find specific pages or data, typically implemented using a text input field. In HTML5, there is a new search input type which, when implemented further by browsers, should allow native enhanced functionality for your site’s search without requiring additional JavaScript development on your part. Using the search input type is similar to using any other HTML5 form field.

<input type="search" name="mysearch">

In Opera, Chrome, and Safari, you will find that search inputs are styled by default to have rounded corners. In Chrome and Safari, if you enter a value in the field, a small "x" will appear on the right-hand side of the field, which, when pressed, will clear the contents of the field. An example of this can be seen in figure 8.

image010.jpg

Figure 8 Entering a value in the search input field in Google Chrome and Apple Safari results in a small grey "x" showing, allowing you to easily clear the field’s contents

The final new input type introduced in HTML5 is the color type. This field type is designed to allow you to accept a color value in the hexadecimal (hex) notation, such as #000000 (black). The specification specifically states that the color value must:

  1. Start with the # character.
  2. Have six characters in the ranges of 0-9, a-f, and A-F, which follow the # character.

Warning

You should not use color names in a color input field because HTML5 only supports using the hexadecimal notation, and the field won’t work with any other values.

You can use the color input type as follows.

<input type="color" name="mycolor">

In all browsers except Opera, the color input type will appear as a standard text box, and most browsers won’t implement any additional functionality. Google Chrome validates that the value entered in a color field is a valid color value according to the aforementioned rules. Opera has much more mature support for the color input type, however, and implements a native color picker widget, removing the need to implement a third-party JavaScript color picker. An example of the Opera color picker in action can be seen in figure 9.

image011.jpg

Figure 9 Opera color picker widget in action on Mac OS X. Clicking the "Other…" button will launch the native Mac OS X color utility, where you can choose from a much wider range of colors.

Now that you’ve seen the new input types available to you in HTML5, you’re more than ready to get your hands dirty and apply what you’ve learned in a practical example. In the next section, you’ll do just that, building the registration form you see in figure 10.

image012.jpg

Figure 10 A sample HTML5 registration form that includes many new Web form features introduced in HTML5, including new input types, validation, placeholders, meters, and more

Adding form fields to the registration form sample application

As shown in figure 10, the registration form you are building in this chapter has four sections of input—Account Information, Personal Information, Company Information, and Contact Information. Now that you have seen the various new types of form fields you can use in HTML5, let’s start building these sections up with the appropriate types of input field. Listing 1 provides the code you need for the Account Information and Personal Information sections; add it to index.html, just beneath the opening <form> element you added previously.

Listing 1 Adding the Account Information and Personal Information sections to the registration form, using new date and color input types

HTML
<fieldset>
    <legend>Account Information</legend>
    <ul>
        <li>
            <label for="username">Username*</label>
            <input name="username" id="username">
        </li>
        <li>
            <label for="password">Password*</label>
            <input type="password" name="password" id="password">
        </li>
        <li>
            <label for="confirm_password">Confirm Password*</label>
            <input type="password" name="confirm_password" id="confirm_password">
        </li>
        <li>
            <label for="credit_card">Credit Card No*</label>
            <input name="credit_card" id="credit_card">
        </li>
    </ul>
</fieldset>
<fieldset>
    <legend>Personal Information</legend>
    <ul>
        <li>
            <label for="name">Name*</label>
            <input name="name" id="name">
        </li>
        <li>
            <label for="date_of_birth">Date of Birth*</label>
            <input type="date" name="date_of_birth" id="date_of_birth">  #1
        </li>
        <li>
            <label for="color">Favorite Color</label>
            <input type="color" name="color" id="color" value="#0000FF"> #2
        </li>
        <li>
            <label for="photo">Profile Photo(s)</label>
            <input type="file" name="photo" id="photo">
        </li>
        <li>
            <label for="browser">Favorite Browser</label>
            <input name="browser" id="browser">
        </li>
    </ul>
</fieldset>
#1 date input type
#2 color input type

At this point, you are probably thinking, "Where are all the new elements? This is all regular old HTML!" And you’d be right—the majority of the code in listing 1 contains old input types. In the Personal Information section, you ask the user to enter their date of birth, presenting them with a new date input field (#1). The form also includes a field for the user’s favorite color, using a color input type (#2). Every field in the Company Information and Contact Information sections of the form are new HTML5 input types. Let’s add them now—insert the code in listing 2 directly after the code you added previously.

Listing 2 Adding the Company Information and Contact Information sections to the form, using number, range, email, tel, and url HTML5 input types

HTML
<fieldset>
    <legend>Company Information</legend>
    <ul>
        <li>
            <label for="employees">No. of Employees</label>
            <input type="number" name="employees" id="employees" min="0" max="100000" step="100"> #1
        </li>
        <li>
            <label for="revenue">Estimated Revenue</label>
            <input type="range" name="revenue" id="revenue" min="0" max="1000" step="1" value="0"> #2
        </li>
    </ul>
</fieldset>
<fieldset>
    <legend>Contact Information</legend>
    <ul>
        <li>
            <label for="email">Email Address(es)*</label>
            <input type="email" name="email" id="email"> #3
        </li>
        <li>
            <label for="phone_number">Phone Number</label>
            <input type="tel" name="phone_number" id="phone_number"> #4
        </li>
        <li>
            <label for="website">Website URL</label>
            <input type="url" name="website" id="website"> #5
        </li>
    </ul>
</fieldset>
#1 number input type
#2 range input type
#3 email input type
#4 tel input type
#5 url input type

In the Company Information section, there are two fields, both using new HTML5 input types. The first field is for the number of employees in the company, defined as an HTML5 number input field, with a minimum value of 0, a maximum value of 100,000 and which steps up and down in blocks of 100 (#1). The second field asks the user to enter the company’s estimated revenue, with a range input type allowing values of between 0 and 1,000 (million) (#2). You may notice that you cannot see the current value of the field on the slider (as shown in figure 11). You would resolve that issue using the <output> element.

image013.jpg

Figure 11 The HTML5 slider widget does not display the current value of the range input field.

In the final section of the form, Contact Information, you ask the user to enter their email address(es) using an email input field #1, phone number using a tel field #2 and finally the URL of their website using a url input field #3. At this point, the registration form markup will give you a result that looks similar to the screenshot you saw in figure 10.

Summary

Beyond the shadow of a doubt, Web forms are hugely important in modern Web applications. Virtually every Web application ever made relies on Web forms in some respect to provide functionality to users. Whether for data input and retrieval, search queries, or communications and messaging, Web forms are everywhere. The support for Web forms in previous versions of HTML was pretty basic to say the least. If you wanted to provide the user with any sort of feedback or allow them to enter data using a reasonable form of input (think of date pickers for entering dates), you had to rely on third-party JavaScript libraries to facilitate such functionality. If your user used a browser that did not support JavaScript, you could forget about decent widgets and client-side validation.

HTML5 introduces a lot of functionality for improving Web forms. Unfortunately, despite many aspects of these new features and improvements being part of the HTML5 specification for quite some time now, browser vendors have been relatively slow to implement these features in recent versions of the browsers. The only browser vendor to implement widgets for date and color pickers is Opera, and that looks unlikely to change anytime soon. Despite this issue, one thing is for certain—all browsers will offer complete support for these new features at some point, and when that happens, you should be ready to take advantage of it in your applications.

Here are some other Manning titles you might be interested in:

image014.jpg

Hello! HTML5 and CSS3
Rob Crowther

image015.jpg

Sass and Compass in Action
Wynn Netherland, Nathan Weizenbaum, and Chris Eppstein

image016.jpg

Secrets of the JavaScript Ninja
John Resig and Bear Bibeault

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)