Using the Datalist to Provide Guided and Auto-Suggest Values for Form Input Fields
The HTML datalist control pairs with an input to provide simple, semantic solution to provide a currated value list for users to provide a value without typing. This is particularly useful for mobile interfaces because it eliminates an error prone typing experience.
The most common use of the datalist is to create a nice autocomplete experience. Without the datalist you must craft a more complex solution that leans more on slower JavaScript and hacky HTML and CSS. The combination of an Input and datalist controls gives you a slick, native option.
Guided user input is a good data entry user experience. You want to help the user avoid potential mistakes. It also helps que the user about valid values the field is expecting.
With on screen, mobile keyboards you want to reduce the keystrokes required to enter data and at the same time make sure the data entered is at least valid if not absolutely correct.
Ever since Google first introduced a little search phrase suggestion to their home page several years back the notion of an auto-complete has become popular. There are many tutorials around the Internet about how you can implement this simple piece of AJAX magic.
HTML5 added support for many useful form/data entry enhancements. One that does not get much attention is the datalist element. This element acts as a placeholder for a native browser auto-suggest feature.
The recent Apple Safari update finally included support for this native input solution, so now you can safely use this element without needing a clunky polyfil.
Where most AJAX auto-suggest plugins and libraries inject or leverage an absolutely position element containing the list of potential values, the datalist handles this natively.
You can associate most input field types to a datalist element. I have also found it possible to associate multiple inputs to a single datalist.
The association between an input field and a list is made by setting the input's list attribute to the id of the target datalist. This of course means you need to provide a unique id for each datalist.
The list attribute is not supported by the hidden, password, checkbox, radio, file, or any of the button types. Any value that does not match the input element's type is not included in the possible values displayed to the user.
For example a list of emails, like I use in the demos, wont be displayed when the input type if number.
Pre-Populated datalist Options
You can pre-populate the datalist if you want. The datalist should contain a list of Options, similar to the Select element.
Each Option's value will be used to display in the list. When the user selects an item from the auto-suggest list the value is placed in the active INPUT field.
<div class="form-group"> <label for="email">Enter your email</label> <i class="fa fa-user prefix"></i> <input id="email" type="email" multiple name="cc" list="contacts" /> <datalist id="contacts"> <option value="Manuela.Zboncak64@hotmail.com"></option> <option value="Felicia44@hotmail.com"></option> <option value="Denis_Dicki84@yahoo.com"></option> <option value="Julia_Baumbach62@yahoo.com"></option> </datalist> </div>
In this example I have pre-populated the list so the suggested values are available as the page is rendered.
A datalist element can be placed anywhere in the markup, but you associate the target input element by adding a list attribute. The list attribute's value is the 'id' of the related datalist.
Once this relationship is established the user will have access to the suggestion list. In Chrome and the new Edge there is a dropdown arrow in the right-hand side of the input field. FireFox displays nothing, but the user can double-click to display the list.
All browsers will display a list of possible values as the user types. This will be the most common method to trigger the datalist support.
As the user types the list filters to display only values that match the entered phrase.
Dynamically Adding datalist Options Using AJAX
The datalist does not need to be pre-populated. You can dynamically add items at run-time. This means you can wire an AJAX/Fetch based solution to feed data to the option list.
In this example I bind a list of e-mails to the datalist when focus is set to the targeted input.
var dcl = document.getElementById( "dynamic-email" ); dcl.addEventListener( "focus", function () { var dynamicContacts = document.getElementById( "dynamic-contacts" ); // Loop over the JSON array. data.emails.forEach( function ( item ) { // Create a new <option> element. var option = document.createElement( 'option' ); // Set the value using the item in the JSON array. option.value = item; // Add the <option> element to the <datalist>. dynamicContacts.appendChild( option ); } ); } );
I simplified this example to demonstrate how to bind a list of possible options at run-time. The example code has a JSON object with the values for both this e-mail example.
I think the best part of this solution is you can fetch a valid list of values as the user focuses on the field or loads the form. As they type the browser will filter the list to only values matching the entered characters.
This save you, the developer from needing to create a custom filtering solution. It also does not restrict you from doing so either. You can always refresh the datalist values based on your own criteria.
To do so you would need to do a little refactoring to extract the logic to bind the list to the datalist into its own method.
In this code snippet I have extracted the logic to bind the list into its own function (visit the GitHub repo for actual code) and added a 'keyup' event handler to dynamically update the list.
dcl.addEventListener( "focus", bindEmailList ); dcl.addEventListener( "keyup", function ( e ) { e.preventDefault(); if ( e.keyCode !== 13 ) { bindEmailList(); } return false; } );
I did need to make a change to the bindEmailList method to clear the list of child elements before a new set was added.
You should add the following to the code to keep the list from growing exponetially and including duplicate values.
while ( dynamicContacts.firstChild ) { dynamicContacts.removeChild( dynamicContacts.firstChild ); }
I added this code just before the loop starts.
datalist vs Select or Classic Dropdowns
You may be wondering why you would use an Input + datalist solution instead of the Select element?
This is a great question because there are similar, but different and you need to understand when one is more appropriate than the other.
The main difference between the datalist and Select elements is the ability to enter a value not included in the option list. The datalist allows the user to enter any value, assuming it meets validation criteria, and the select element restricts values to those in the option list.
If you think about a typical autocomplete scenario, the suggestions are either based on the user's history or a list of options based on an algorithm. This does not mean the choices are what the user wants to enter.
If you think about using a search engine, each one has a search suggestion list as you type based on related searches others have previously entered. This may not be the search phrase you need, so you are allowed to submit anything.
If search engines used the Select element the range of search phrases would be extremely limited and you most likely would not find an acceptable result for your query.
For the record about 20% of the daily queries submited to search engines have never been submitted before. That means at least 1/5 of the daily search traffic would not exist, well not in its current form at least.
Wrapping It Up
The datalist element is a very helpful tool to guide users to the correct value.
Because it is native to the browser it includes common auto-suggest functionality for pesky data entry tasks. You should always make an effort to make data entry easy and the datalist element is a great tool to make a frustrating form much easier to use, increasing productivity, sales conversions and overall user satisfaction.
I particularly like this option because it is a native control and thus helps us eliminate slower JavaScript options. It is always good when you can remove JavaScript from a web page so you can provide a faster user experience.
The native solution also provides additional advantages as browsers have smart filter/auto-complete logic and filtering that make it easier for us to deliver a better solution faster with less testing required.
I encourage you to start adding the datalist element to your data entry forms. It is a great way to enhance your progressive web applications.
You can find my simple Datalist example inside my Love2Dev Samples Repo on GitHub.