Building a JavaScript Autocomplete Widget with Awesomplete

Share this article

Autocomplete is a feature in web applications which predicts the rest of a word or sentence while the user is still typing. Users usually press the tab key to accept a suggestion, or the down arrow key to accept one of several.

In this tutorial we will look at how to use the Awesomplete JavaScript library to create an autocomplete widget in our websites. Awesomplete is created by Lea Verou, a well-known speaker, author and invited expert in the W3C CSS working group.

Why Not Use the HTML5 datalist Element?

The HTML5 datalist element is possibly the simplest way to implement an autocomplete feature in a website. Unfortunately, browser support for this element is limited and it’s implementation is inconsistent (e.g. Chrome matches only from the start, Firefox anywhere). It’s also not possible to style it according to your website’s design and, although promising, it’s probably not the right choice yet.

Awesomplete, on the other hand, is an ultra lightweight, customizable autocomplete widget, which you can drop into your pages. It has zero dependencies (no jQuery), works across all modern browsers and can be styled according to your website’s theme.

So what are we waiting for? Let’s dive in!

Including Awesomplete in Your Web Page

To use the Awesomplete library we need two files: awesomplete.css and awesomplete.js.

You can get these using bower:

bower install https://github.com/LeaVerou/awesomplete.git#gh-pages

By downloading them from the Awesomplete website directly.

Or, by including them via the RawGit CDN (which serves raw files directly from GitHub with proper Content-Type headers). This is demonstrated below.

To instantiate the basic widget, you need an input element with a class of awesomplete, followed by the assosciated options in a datalist element. The list attribute of the input element must match the id of the datalist element. This is a sensible default configuration, as it offers a fallback to any users with JavaScript disabled.

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="https://cdn.rawgit.com/LeaVerou/awesomplete/gh-pages/awesomplete.css">
  </head>
  <body>
    <input class="awesomplete" list="mylist" />
    <datalist id="mylist">
      <option>One</option>
      <option>Two</option>
      <option>Three</option>
    </datalist>

    <script src="https://cdn.rawgit.com/LeaVerou/awesomplete/gh-pages/awesomplete.min.js"></script>
  </body>
</html>

Basic Functionality

There are many ways to use this versatile library. Let’s start with a basic use case.

Using the data-list Attribute

It is possible to move the options from the aforementioned datalist element into a data-list attribute on the input element itself.

<input class="awesomplete"
       data-minchars="1"
       data-maxitems="5"
       data-list="China, India, Japan, Russia, UK, USA" />

See the Pen Awesomplete (1) by SitePoint (@SitePoint) on CodePen.

Using JavaScript

The above solutions are useful if your autocomplete options are static. However. to create the list dynamically and further customize the behavior of the autocomplete widget, we need a JavaScript method.

<input id="countries" />

var input = document.getElementById("countries");
var awesomplete = new Awesomplete(input, {
  minChars: 1,
  maxItems: 5,
  autoFirst: true
});
awesomplete.list = ["China", "India", "Japan", "Russia", "UK", "USA"];

Here we are creating a Awesomplete object, passing it two parameters: a reference to our input element, and an object literal containing the configuration options.

We then assign the list property of our Awesomplete object to an array holding the list of the autocomplete options. In the demo below, I have expanded the array of country names, using this handy snippet.

Also, note that the minChars, maxItems and autoFirst properties are same as the data-minchars, data-maxitems and data-autofirst attributes in the previous demo.

See the Pen Awesomplete (2) by SitePoint (@SitePoint) on CodePen.

When using JavaScript to instantiate an autocomplete widget we have access to many other properties, APIs and events. Let see what are they are how to use them?

Extended JavaScript Properties

There are four other properties supported by the Awesomplete object. They are: filter, sort, item and replace. These four properties have functions assigned to them.

The filter property controls how entries get matched. Its callback function takes two parameters: the current suggestion text (so in our example each of the values “China”, “India”, “Japan”, “Russia”, “UK”, “USA” in turn) and a string containing the user’s input. By default, the input can match anywhere within the string and it’s a case insensitive match.

The following example demonstrates how you would make Awesomplete perform a case-sensitive match:

function myFilterFunc(text, input) {
  return text.indexOf(input) > -1;
}

var input = document.getElementById("countries");
var awesomplete = new Awesomplete(input, {
  filter: myFilterFunc
});
awesomplete.list = ["China", "India", "Japan", "Russia", "UK", "USA"];

The sort property controls how list items are ordered. Its callback has the same prototype as the Array.prototype.sort() function.

Here’s how you would use it to sort matches in reverse alphabetical order:

function mySortFunc(text, input) {
  return text < input;
}

var input = document.getElementById("countries");
var awesomplete = new Awesomplete(input, {
  sort: mySortFunc
});
awesomplete.list = ['Albania', 'Brazil', 'Chile', 'Denmark', 'Egypt'];

The item property controls how list items are generated. This callback also has two arguments: the current suggestion text and user’s input. It should return a list item. Here’s how you would use the item property to highlight user input within a suggestion text:

function myItemFunc(text, input){
  return Awesomplete.$.create("li", {
    innerHTML: text.replace(RegExp(input.trim(), "gi"), "<mark>$&amp;</mark>"),
    "aria-selected": "false"
  });
}

var input = document.getElementById("countries");
var awesomplete = new Awesomplete(input, {
  item: myItemFunc
});
awesomplete.list = ["China", "India", "Japan", "Russia", "UK", "USA"];

The fourth and final property is the replace property. The replace property controls how the user’s selection replaces the user’s input. In contrast to the previous three functions, this callback takes one parameter: the text of the selected option. It is fired when the user selects one of the suggested options (e.g. by clicking on it).

Here’s how you would use it to transform a user’s selection to upper case:

function myReplaceFunc(text) {
  input.value = text.toUpperCase();
}

var input = document.getElementById("countries");
var awesomplete = new Awesomplete(input, {
  replace: myReplaceFunc
});
awesomplete.list = ['Albania', 'Brazil', 'Chile', 'Denmark', 'Egypt'];

Tying It All Together

Here is an demo showing how to combine the filter and item functions to only make a suggestion once a user has entered a specified character(s) (in this case a comma followed by a space):

See the Pen Awesomplete (3) by SitePoint (@SitePoint) on CodePen.

Digging Deeper — Events, APIs and Ajax

There are five custom events that are fired by this library. These are: awesomplete-select, awesomplete-selectcomplete, awesomplete-open, awesomplete-close and awesomplete-highlight.

This is how you would hook into each of these events:

window.addEventListener("awesomplete-select", function(e){
  // User made a selection from dropdown. 
  // This is fired before the selection is applied
}, false);

window.addEventListener("awesomplete-selectcomplete", function(e){
  // User made a selection from dropdown. 
  // This is fired after the selection is applied
}, false);

window.addEventListener("awesomplete-open", function(e){
  // The popup just appeared.
}, false);

window.addEventListener("awesomplete-close", function(e){
  // The popup just closed.
}, false);

window.addEventListener("awesomplete-highlight", function(e){
  // The highlighted item just changed 
  // (in response to pressing an arrow key or via an API call).
}, false);

Awesomplete provides various methods on the Awesomplete object that allow you to customize its behavior:

  1. open(): Used to open the popup.
  2. close(): Used to close the popup.
  3. next(): Used to highlight the next item in the popup.
  4. previous(): Used to highlight the previous item in the popup.
  5. goto(i): Used to highlight the item with index i in the popup (-1 to deselect all).
  6. select(): Used to select the currently highlighted item, replace the text field’s value with it and close the popup.
  7. evaluate(): Used to evaluate the current state of the widget and regenerate the list of suggestions. Closes the popup if none are available. This method is particularly useful if you dynamically set the list property while the popup is open.

Note: open() will not currently open the list before an input event has fired, but there is a pull request on the project’s home page which should fix this.

The Finale

By way of a final example, this is how you might use Awesomplete in conjunction with data fetched from a remote API via Ajax. I will be using the REST Countries API, which provides users with a whole host of country data.

The first thing to do is to initialize the widget without setting its list property (I’m using jQuery here for the sake of brevity):

var input = $("#countries");
var awesomplete = new Awesomplete(input, {
  minChars: 1,
  autoFirst: true
});

Then, attach a keyup event listener:

$(input).on("keyup", function(){ ... }

When the user has pressed a key, we need to grab the value of the input element and make our request:

$.ajax({
  url: 'https://restcountries.eu/rest/v1/name/' + this.value,
  type: 'GET',
  dataType: 'json'
})

Within the success callback, we can iterate over the JSON response, grab the names of the respective cities and set the list property of the Awesomplete object on the fly:

.success(function(data) {
  var list = [];
  $.each(data, function(key, value) {
    list.push(value.name);
  });
  awesomplete.list = list;
});

And that’s it!

See the Pen Awesomplete (4) by SitePoint (@SitePoint) on CodePen.

Conclusion

In this tutorial, we have seen how easily we can implement an autocomplete widget in our projects using the lightweight and customizable Awesomplete library. The project is still being actively maintained and I encourage you to check it out.

Frequently Asked Questions (FAQs) about JavaScript Autocomplete Widget – Awesomplete

How do I install and use Awesomplete in my project?

To install Awesomplete, you can use npm or download it directly from the GitHub repository. Once installed, include the awesomplete.css and awesomplete.js files in your HTML file. To use Awesomplete, create an input element in your HTML and initialize Awesomplete with new Awesomplete(input). You can then populate the list with an array of suggestions.

Can I customize the appearance of the Awesomplete dropdown?

Yes, you can customize the appearance of the Awesomplete dropdown by overriding the CSS classes in the awesomplete.css file. You can change the colors, fonts, and other styles to match your website’s design.

How can I use Awesomplete with dynamic data?

Awesomplete can be used with dynamic data by using the list property. You can set the list property to an array of suggestions, and it will automatically update the dropdown as the array changes.

Can I use Awesomplete with a remote data source?

Yes, you can use Awesomplete with a remote data source by using the ajax function. The ajax function takes a URL and a callback function, and it fetches the data from the URL and passes it to the callback function.

How can I handle the selection event in Awesomplete?

You can handle the selection event in Awesomplete by using the ‘awesomplete-select’ event. This event is fired when a suggestion is selected, and you can add an event listener to handle it.

Can I use Awesomplete with multiple input fields?

Yes, you can use Awesomplete with multiple input fields. You just need to create a new instance of Awesomplete for each input field.

How can I filter the suggestions in Awesomplete?

You can filter the suggestions in Awesomplete by using the filter function. The filter function takes a suggestion and a input value, and it returns true if the suggestion matches the input value.

Can I use Awesomplete with other JavaScript libraries?

Yes, you can use Awesomplete with other JavaScript libraries. Awesomplete is a standalone library, so it doesn’t have any dependencies and it doesn’t conflict with other libraries.

How can I sort the suggestions in Awesomplete?

You can sort the suggestions in Awesomplete by using the sort function. The sort function takes two suggestions, and it returns a negative number, zero, or a positive number depending on the order of the suggestions.

Can I use Awesomplete in a form?

Yes, you can use Awesomplete in a form. When a suggestion is selected, the input field’s value is set to the suggestion, so it can be submitted with the form.

Narayan PrustyNarayan Prusty
View Author

Narayan is a web astronaut. He is the founder of QNimate. He loves teaching. He loves to share ideas. When not coding he enjoys playing football. You will often find him at QScutter classes.

ajaxautocompleteawesompletejameshwidget
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week