This tutorial provides an in-depth look at little-used HTML5 <datalist> element. It can implement lightweight, easy-to-use, browser-based autocomplete form management that does not require JavaScript.

What is wrong <select>?

HTML5 <select> The controls are ideal when you want the user to choose from a small selection of options. They are less practical when:

  • There are many options such as countries or job titles
  • the user wants to enter their own option that is not listed

The obvious solution is automatic replenishment control. This allows the user to enter a few characters, which limits the options available for faster selection.

<select> jump to the right place when you start typing, but it’s not always obvious. It does not work on all devices (such as touch screens) and is reset in a second or two.

Developers often turn together many JavaScript based solutions, but custom autocomplete management is not always needed. HTML5 <datalist> the element is lightweight, easy to use and has no JavaScript dependencies. You may have heard that it is buggy or missing support. That’s not true in 2021, but there are inconsistencies and warnings in the browser.

<datalist> Quick start

Selecting your country from a list of over 200 options is an ideal candidate for managing autocomplete. Determine a <datalist> with a child <option> elements every country directly on the HTML page:

<datalist id="countrydata">
  <option>Afghanistan</option>
  <option>Åland Islands</option>
  <option>Albania</option>
  <option>Algeria</option>
  <option>American Samoa</option>
  <option>Andorra</option>
  <option>Angola</option>
  <option>Anguilla</option>
  <option>Antarctica</option>
  ...etc...
</datalist>

Datalist id can then be referred to as a list attribute anywhere <input> area:

<label for="country">country</label>

<input type="text"
  list="countrydata"
  id="country" name="country"
  size="50"
  autocomplete="off" />

Confusingly, it’s best to set autocomplete="off". This ensures that the values ​​are displayed to the user <datalist> but not the values ​​they have previously typed into the browser.

Result:

This is the default rendering in Microsoft Edge. Other applications perform similar functions, but the layout varies on platforms and browsers.

<option> Options

Using the tag <option> is common:

<datalist id="mylist">
  <option>label one</option>
  <option>label two</option>
  <option>label three</option>
</datalist>

Use value attribute produces similar results:

<datalist id="mylist">
  <option value="label one" />
  <option value="label two" />
  <option value="label three" />
</datalist>

Note: closing /> a slash is optional in HTML5, although it can help prevent coding errors.

You can also set the value according to the selected label in one of the following formats.

Option 1:

<datalist id="mylist">
  <option value="1">label one</option>
  <option value="2">label two</option>
  <option value="3">label three</option>
</datalist>

Option 2:

<datalist id="mylist">
  <option value="1" label="label one" />
  <option value="2" label="label two" />
  <option value="3" label="label three" />
</datalist>

In both cases, the input field is set to 1, 2 or 3 when a valid option is selected, but the interface varies in browsers:

  • Chrome displays a list of both the value and the tag. Only the value remains when the option is selected.
  • Firefox displays a list with only a sticker. It changes to when the option is selected.
  • Edge only shows the value.

The following CodePen example shows all variations:

Look at the pen
HTML5 examples of autocomplete
by SitePoint (@SitePoint)
on CodePen.

Implementations are evolving, but for now, I recommend that you don’t use value and tag because it is likely to confuse users. (The workaround is discussed below.)

<datalist> Browser support and restores

<datalist> the element is well supported in modern browsers and Internet Explorer 10 and 11:

For information on support for the datalist feature in major browsers, visit caniuse.com

There are several implementation notes, but they do not affect most uses. The worst that can happen is a field that returns to normal text input.

If you absolutely need to support IE9 and older, there is a backup pattern that uses the standard <select> together with text input when <datalist> fails. To customize the country model:

<label for="country">country</label>

<datalist id="countrydata">

  <select name="countryselect">
    <option></option>
    <option>Afghanistan</option>
    <option>Åland Islands</option>
    <option>Albania</option>
    <option>Algeria</option>
    <option>American Samoa</option>
    <option>Andorra</option>
    <option>Angola</option>
    <option>Anguilla</option>
    <option>Antarctica</option>
    ...etc...
  </select>

  <label for="country">or other</label>

</datalist>

<input type="text"
  id="country" name="country"
  size="50"
  list="countrydata"
  autocomplete="off" />

Look at the pen
HTML5 autocomplete return
by SitePoint (@SitePoint)
on CodePen.

In modern browsers <option> elements become part <datalist> and “Thailand Other” the label is not displayed. It looks identical example above, but a countryselect the value of the form is set to an empty string.

In IE9 and below both (very long) <select> and text input fields are active:

IE9 data backup

Both values ​​can be entered in the old IE. Your application is either:

  • decide which is the most valid, or
  • resets a small JavaScript function when another is changed

Using <datalist> non-text controls

Chrome browsers can also search <datalist> set of values:

  1. Input with type "date". The user can choose from several options that are defined YYYY-MM-DD values, but they are presented in their language.

  2. Input with type "color". The user can select from a number of color options that are defined as six-digit hexadecimal (three-digit values ​​do not work).

  3. Input with type "range". There is a check mark in the slider, but this does not limit the value you can enter.

Look at the pen
HTML5 for other input types
by SitePoint (@SitePoint)
on CodePen.

<datalist> CSS formatting

If you have ever fought for design a <select> box, … you had an easy time!

An <input> can be formatted normally but linked <datalist> and its child <option> elements cannot be formatted in CSS. The rendering of the list is completely determined by the platform and the browser.

I hope the situation improves, but for now MDN proposes a solution which:

  1. overrides the default browser behavior
  2. treats effectively <datalist> like <div> so it can be formatted in CSS
  3. copy all JavaScript autocomplete functions

I have improved it further and the code is available from GitHub. You can use it by uploading the script to any part of your HTML page as an ES6 module. jsDelivr The CDN URL can be used:

<script src="https://cdn.jsdelivr.net/npm/datalist-css/dist/datalist-css.min.js"></script>

Or you can install it npm if you are using a package:

npm install datalist-css

Your <datalist> elements must be used <option>value</option> form. For example:

<datalist id="mylist">
  <option>label one</option>
  <option>label two</option>
  <option>label three</option>
</datalist>

entry: <option value="value" /> cannot be used because it results in an empty element that cannot be formatted!

CSS can then be added to some or all of the style <datalist> and <option> elements. For example:

datalist {
  position: absolute;
  max-height: 20em;
  border: 0 none;
  overflow-x: hidden;
  overflow-y: auto;
}

datalist option {
  font-size: 0.8em;
  padding: 0.3em 1em;
  background-color: #ccc;
  cursor: pointer;
}


datalist option:hover, datalist option:focus {
  color: #fff;
  background-color: #036;
  outline: 0 none;
}

Example:

Look at the pen
HTML5 CSS formatting for autocomplete
by SitePoint (@SitePoint)
on CodePen.

The design works, but is it worth the effort? I doubt that…

  • Deploying a standard browser keyboard, mouse, and touch controls with reasonable ease of use is difficult. MDN example does not support keyboard events, and while I tried to improve it, some devices inevitably have problems.
  • You rely on 200 lines of JavaScript to solve the CSS problem. It shrinks to 1.5 kb, but can cause performance issues if you need many for a long time <datalist> elements on the same page.
  • If JavaScript is a requirement, would it be better to use a beautiful, more consistent, battle-tested JavaScript component?

Control returns to normal HTML5 <datalist> without formatting when JavaScript fails, but that is a small advantage.

Creating an Ajax Enhanced <datalist>

Assuming that the designer is happy to accept browser style differences, it is possible to improve the standard <datalist> functionality using JavaScript. For example:

  1. Enable optional verification that only accepts a known value <datalist>.
  2. Set <option> elements from the data that Ajax calls to search APIs.
  3. Set other field values ​​when the option is selected. For example, selecting “United States” sets “US” to the hidden feed.

The code needs to be redefined in the first place <option> elements, although there are several encodings:

  • The Ajax API request should only occur after the minimum number of characters has been entered.
  • Writing events should be dismantled. In other words, an Ajax call is not triggered until the user has stopped typing for at least half a second.
  • Query results should be cached, so there is no need to repeat or parse similar calls.
  • Unnecessary inquiries should be avoided. For example, entering “a” restore 12 countries. You no longer need to make Ajax calls “Unit” or “Uniform” because all the resulting options are included in the original 12 results.

I have created a standard Network component for this purpose and the code is available on GitHub. Use the CodePen example below to select a valid country after entering at least two characters. Music Artist AutoComplete then returns artists from that country with names that match the search string:

Look at the pen
HTML5 and Ajax autocomplete
by SitePoint (@SitePoint)
on CodePen.

You can use it in your own application by downloading the script anywhere on your HTML page as an ES6 module. jsDelivr The CDN URL can be used:

<script src="https://cdn.jsdelivr.net/npm/datalist-ajax/dist/datalist-ajax.min.js"></script>

Or you can install it npm if you are using a package:

npm install datalist-ajax

Round <auto-complete> element with a child <input> used as a data entry field. For example, country search uses this:

<label for="country">country lookup:</label>

<auto-complete
  api="https://restcountries.eu/rest/v2/name/${country}?fields=name;alpha2Code;region"
  resultname="name"
  querymin="2"
  optionmax="50"
  valid="please select a valid country"
>
  <input type="text" id="country" name="country" size="50" required />
</auto-complete>

<auto-complete> element attributes:

attribute description
api REST API URL (required)
resultdata the name of the property containing the result set of the returned API JSON object (not required if only the results are returned)
resultname the name of the property in each result object that corresponds to the search input and is used in the data list <option> elements (required)
querymin minimum number of characters to enter before starting search (default: 1)
inputdelay minimum time waits in milliseconds between keystrokes before searching (default: 300)
optionmax Maximum number of autocomplete options to display (default: 20)
valid if set, this error message is displayed when an incorrect value is selected

REST URL must contain at least one ${id} the identifier to be replaced <input> with that id. In the example above ${country} that api The URL refers to the value of the child <input>, who has id / "country". The URL usually uses a sub-level feed, but all other fields on the page can be referenced.

restcountries.eu The API returns a single object or group of objects that contains country-specific information. For example:

[
  {
    "name": "Cyprus",
    "alpha2Code": "CY",
    "region": "Europe"
  },
  {
    "name": "Sao Tome and Principe",
    "alpha2Code": "ST",
    "region": "Africa"
  },
  {
    "name": "Andorra",
    "alpha2Code": "AD",
    "region": "Europe"
  }
]

resultdata the attribute does not need to be set because this is the only data returned (no wrapper object exists). resultname the attribute must be specified "name" because this feature is used to populate data listers <option> elements.

Other fields can be filled in automatically when the option is selected. The following incomes are received "alpha2Code" and "region" property information because a data-autofill the attribute is set to:

<input data-autofill="alpha2Code" type="text" id="countrycode" name="countrycode" readonly />

<input data-autofill="region" type="text" id="region" name="region" readonly />

How datalist-ajax works

You can skip this section if you don’t want to read 230 lines of code and keep the magic alive!

The code first creates a new one <datalist> indoors <auto-complete>, which it attaches to the child <input> use list attribute. An input the event handler follows <input> and call a runQuery() function when the minimum number of characters has been entered and the user is not yet typing.

runQuery() builds an API URL from the form data and makes an Ajax call Get the API. The returned JSON is a reusable DOM fragment that is structured and then contains <option> elements are built and cached.

A datalistUpdate() called that upgrade <datalist> with a suitable cached DOM fragment. Additional calls to the number runQuery() Avoid Ajax calls if the query is already cached or the previous query can be used.

A change the event handler also monitors <input>, which is triggered when the focus is moved from the field and the value is changed. The function checks that the value corresponds to a known option and uses it if necessary Constraint validation interface displays the error message that was given valid attribute.

Assuming that a valid option is selected, the change handler function fills all fields with the corresponding ones data-autofill attributes. The reference to the AutoFill fields is retained so that they can be reset if an incorrect option is entered later.

Note that the shadow DOM is No used. This ensures auto-completion <input> (and <datalist>) elements can be formatted with CSS and other scripts can be used as needed.

Dunkin ‘ <datalist>

HTML5 <datalist> has limitations, but is ideal if you need a simple frame-agnostic autocomplete field. The lack of CSS support is a shame, but browser vendors may end up interfering with this control.

Any code and examples from this tutorial can be applied to your own projects.

LEAVE A REPLY

Please enter your comment!
Please enter your name here