HTML Forms - Datalists

Chapter 43 14 mins

Learning outcomes:

  1. What is the <datalist> element
  2. Using the <option> element inside <datalist>
  3. The list attribute
  4. Options with different text and value

Introduction

So far in this unit, we've explored a handful of form controls in HTML. Now, the thing is that most of these controls by themselves don't provide the user with a set of possible values to choose from.

For example, if we have an email input, and know that there are only 5 possible values that could be input into the input field, won't it be convenient if we can somehow provide this set of values to the user for quick entry instead of him having to type one out?

First of all, note that there is absolutely no trivial way to specify the set of possible values of a form control in HTML. We can only provide such a set for convenience sake — the user, if he wants to, can still input anything of his own into the form control.

Coming back to the idea, the way to provide a set of predefined values to be entered into an input field is to use the <datalist> element in HTML.

In this chapter, we shall understand what exactly is the purpose of <datalist>, how to link a <datalist> with a form control element with the help of the list attribute, how to define options within a <datalist>, and so on and so forth.

What is <datalist>?

Let's start by dissecting the purpose of <datalist> via its naming. As per the name, <datalist> represent a list of data. The question is: Data for what?

The answer to this question is basically just the definition of the element itself:

A <datalist> element represents a list of predefined data for a form control.

For instance, borrowing from the example presented at the start of this chapter, suppose we have an email input (i.e. <input type="email"> element).

And also suppose that there are five common emails entered into the input field. The user has the option to enter a separate email as well, but more often than not, these five emails will do the job.

In order to present the user with these five emails the moment he places focus inside the email input (and starts typing), we can leverage the <datalist> element. It can hold these five predefined values for the email input and allow the user to conveniently select any particular email from them.

The <datalist> element is typically rendered by browsers as a dropdown menu (quite similar to a <select> menu) and only when focus goes within a form control for which we have that <datalist>.

The figure below depicts a basic <datalist> as displayed on Chrome (we'll be creating this example shortly below):

The <datalist> element shown (on Chrome)
The <datalist> element displayed (on Chrome)

The interface for a <datalist> differs from browser to browser, but at the very least, we get the suggestions menu rendered either as soon as we focus on the related form control or start typing into it.

A common pattern to support old browsers

For a browser that supports <datalist> (which includes almost all browsers at the time of this writing), any element inside <datalist> except for <option> is NOT rendered in the dropdown suggestions menu.

This is actually used as a benefit to support old browsers. Here's how:

<select> wraps the list of options inside <datalist>. We can even have a <label> containing text to label the <select>. This <select> element, and its <label>, doesn't get rendered on a supporting browser.

But on an unsupporting browser, the <datalist> element isn't recognized it's just ignored itself; its contents are still rendered. And in this case, the <select> element gets rendered, presenting the list of options just as any other <select> would.

Quite a clever and interesting pattern, isn't it?

Technically, <datalist> can be used with any form control in HTML, however, there are only a few with which it makes sense.

For example, there is no point in having a <datalist> for a radio button. Neither is there one for a checkbox.

Good candidates for the association with <datalist>s are free-form text inputs (i.e. for email, URL, search, etc.) and those inputs that don't have pickers tied to them (for e.g. inputs for date, time, color, etc.).

Now that we have a high-level understanding of the purpose behind the <datalist> element, let's see how exactly to use it.

The <option> element

A <datalist>, just like the <ol> and <ul> elements in HTML, only represents a list; the individual items in the list are then to be denoted using separate elements.

In the case of <datalist>, these individual items correspond to none other than the <option> element — yes, the same <option> that we put inside <select> elements.

Each <option> element inside a <datalist> points to a possible value that could be input in the associated form control (we'll shortly see how to associate a <datalist> with a form control).

It's NOT possible to group multiple <option> elements inside a <datalist> using the <optgroup> element.

For example, let's say we want to define a list of 5 email addresses commonly input in an email input field. The following code accomplishes this:

<datalist>
   <option>alice@example.com</option>
   <option>bob@example.com</option>
   <option>tim@example.com</option>
   <option>sara@example.com</option>
   <option>ali@example.com</option>
</datalist>

The entire list is denoted using a <datalist> and each option therein is denoted using an <option>. Pretty simple.

Obviously, creating a <datalist> isn't any useful on its own. We need to associate it with a form control in order to put the options list into action the moment the user activates the control.

The list attribute

We associate a <datalist> element with a form control using the list attribute on the form control and the id attribute on the <datalist>.

As you can probably guess, the list attribute of the form control simply holds the id of the <datalist> that it must be associated with.

The value of list must not include the # symbol, which is otherwise common when referring to the value of the id attribute of a given element.

In the following code, we complete the example presented above by creating an email input and linking it to the <datalist> created:

<label>
   Email
   <input type="email" name="email" list="email-list">
</label>

<datalist id="email-list">
   <option>alice@example.com</option>
   <option>bob@example.com</option>
   <option>tim@example.com</option>
   <option>sara@example.com</option>
   <option>ali@example.com</option>
</datalist>

Live Example

As the email input receives focus, it displays a dropdown showcasing all the applicable options, with regards to the text currently entered into the input field.

Default autocompletion messing up with <datalist>

Keep in mind that browsers by default are configured to cache all previously entered values into an input field and then present them to the user for autocompletion when it is activated again (even on a later date, in a completely new browser session).

This can, unfortunately, mess up with any existing <datalist> options, extending the list of suggestions to include the ones specified in <datalist> and the ones previously entered by the user.

To remedy this issue, we simply need to set autocomplete="off" on the input field. This instructs the browser to disable autocompletion on the input field, i.e. keep from suggesting previously entered values.

In the following code, we do so for our email input:

<label>
   Email
   <input type="email" name="email" list="email-list" autocomplete="off">
</label>

<datalist id="email-list">
   <option>alice@example.com</option>
   <option>bob@example.com</option>
   <option>tim@example.com</option>
   <option>sara@example.com</option>
   <option>ali@example.com</option>
</datalist>

Live Example

Now, as we activate the input, we only see the five email suggestions presented in the <datalist>. Perfect!

Options with different text and value

Just as we can have <option>s inside a <select> whereby the text placed within them is different from the actual underlying value, we can have such <option>s in <datalist> elements as well.

In this case, the value of each <option> in a <datalist> element, given by the value attribute, specifies the value used for the associated form control if that option is selected.

For example, we might have an option reading the text 'United Kingdom' but actually having the value 'GBR', which is the country ISO code for United Kingdom.

More country codes can be explored on countrycode.org.

Consider the example below where we have a text input for obtaining the name of a country. A couple of countries (starting with the letter 'U') have been predefined as part of a <datalist> and linked with this text input:

<label>
   Country
   <input type="text" name="country" list="country-list" autocomplete="off">
</label>

<datalist id="country-list">
   <option value="VI">U.S. Virgin Islands</option>
   <option value="UG">Uganda</option>
   <option value="UA">Ukraine</option>
   <option value="AE">United Arab Emirates</option>
   <option value="GB">United Kingdom</option>
   <option value="US">United States</option>
   <option value="UY">Uruguay</option>
   <option value="UZ">Uzbekistan</option>
</datalist>

Live Example

Most importantly, notice how each country's option in the <datalist> has the country's name mentioned as content of the <option> element and its actual value mentioned in the value attribute.

If we, let's say, click on the option reading 'United Kingdom', we won't get 'United Kingdom' in the text input; rather, we'll get 'GBR', thanks to the value attribute of the <option>.

Also notice how we've kept the autocomplete attribute on the <input> here as well. This is to prevent the browser from presenting us with its own cached suggestions.

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage