How to create autocomplete feature in javascript using awesomplete

Autocomplete feature is one of the most exciting features of modern web applications. It can increase the usability of your web application. You can implement the autocomplete feature in your web app using the HTML5 element called datalist. But still, datalist is not able to fulfill your expectation to customize, how your autocomplete feature behaves.

Now we are going to implement the autocomplete feature in JavaScript. There are plenty of libraries available to achieve autocomplete feature in your web application. For this tutorial, I am going to use one such library known as Awesomplete. It is the minimalistic library to implement the autocomplete feature and has many options to customize the behavior. in this tutorial, we are going to build an app where you can enter any country name in the input field, you will get the related suggestions as autocomplete and you will be able to select from the suggested values.

You can download the project files at the end of the tutorial.

Things I am going to use in this tutorial.

CSS Framework – I am gonna use the Bootstrap 4 framework to quickly create the UI for this tutorial. I am gonna copy and paste the basic HTML template for Bootstrap from their website.

JQuery – I am using JQuery to perform DOM manipulation as well as attaching the event to the elements. Yes, I know you are thinking that this is an overkill for this simple tutorial but for the sake of simplicity I am using it if you wish you can use vanilla JavaScript to this things.

Awesomplete – Last and most importantly, the Awesomplete library to actually create the autocomplete feature in our tutorial. You need to download the zip file from its official website.

Setting up the project.

For this tutorial, I am going to create an index.html file as our main file to write the code. Then you need to include the awesomplete.css and awesomplete.js or awesomplete.min.js files in your root directory from the zip file you have downloaded from their website.

Creating the basic UI.

index.html

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
        crossorigin="anonymous">


    <link rel="stylesheet" href="awesomplete.css">
    
    <script src="awesomplete.min.js"></script>
    

    <style>
        
        body{
            background-color: #F1F1F1
        }

       
    </style>

    <title>Javascript Autocomplete Demo</title>

    
</head>

<body>
    
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-8">
                <h1 class="mt-5 text-center">Javascript Autocomplete Demo</h1>
                <div class="card">
                    <div class="card-body shadow">
                        
                            <div class="form-group mt-2">
                                <input type="text" class="form-control form-control-lg" id="country-name" placeholder="Enter Any Country Name">
                            </div>
                    </div>
                </div>
            </div>
        </div>    
    </div>
    

    <!-- jQuery first, then Bootstrap JS -->
    <script src="//code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>
    
</body>


</html>

Now our UI looks like this,

The two ways to use the Awesomplete to achieve the autocomplete feature.

Now there are two ways to use the Awesomplete to create the autocomplete feature. First without writing any extra JavaScript code. When you have static data, you can directly use the datalist element of HTML5 and the Awesomplete library will take care of everything. Second when you want to fetch the data based on user input to show the related list of options. We will look into both the cases one by one.

Using the datalist for the static data.

If you have specific data that is not based on user input then it extremely easy to implement the autocomplete feature using Awesomplete, You just need to add awesomplete class to the input field where you want to use the autocomplete feature. In our web app,  we are going to use autocomplete feature for countries name which we will enter in the input field.

<input type="text" class="form-control form-control-lg awesomplete" id="country-name" placeholder="Enter Any Country Name">

For now, we will keep the countries name fixed and we will add all the countries name in the datalist element which we want our user to select from.

<input type="text" class="form-control form-control-lg awesomplete" list="mylist" id="country-name" placeholder="Enter Any Country Name">
<datalist id="mylist">
   <option>India</option>
   <option>Indonesia</option>
   <option >United States Of America</option>
   <option>United Arab Emirates</option>
   <option>United kingdom</option>
</datalist>

Here we have specified the list attribute and we have passed the id of the datalist element. it binds the datalist element to this input field. Now if type in in the input field it will show all the options which contain the in keyword in it.

It is the simplest way to create autocomplete feature in your web app using Awesomplete. It can come in handy when you have static data which can be directly included in your front-end or can be generated by the server. Then

Using Awesomplete with AJAX.

Now if you have huge data and you don’t want to bloat your frontend code with this data( It’s not the best practice) then you can fetch the data based on user input and show it as suggestions for autocomplete. To achieve this we can use AJAX request to get the data from the server based on user input. For this purpose I am not going to create a REST API to provide us the countries name rather we will be using a free API service provided by //restcountries.eu/. It provides an API to get the details of any country name based on their names,

//restcountries.eu/rest/v2/name/{name}

We need to put the name of the country in the place of {name} parameter. It can take the full name of the country as well as the partial name. For example, if hit the //restcountries.eu/rest/v2/name/united URL then it will fetch all the country’s details which name contains the keyword United. You can copy the above URL and paste it into your browser’s URL bar then you can see the data. Following sample data are taken from that URL.

{
    "name": "United States Minor Outlying Islands",
    "topLevelDomain": [
      ".us"
    ],
    "alpha2Code": "UM",
    "alpha3Code": "UMI",
    "callingCodes": [
      ""
    ],
    "capital": "",
    "altSpellings": [
      "UM"
    ],
    "region": "Americas",
    "subregion": "Northern America",
    "population": 300,
    "latlng": [],
    "demonym": "American",
    "area": null,
    "gini": null,
    "timezones": [
      "UTC-11:00",
      "UTC-10:00",
      "UTC+12:00"
    ],
    "borders": [],
    "nativeName": "United States Minor Outlying Islands",
    "numericCode": "581",
    "currencies": [
      {
        "code": "USD",
        "name": "United States Dollar",
        "symbol": "$"
      }
    ],
    "languages": [
      {
        "iso639_1": "en",
        "iso639_2": "eng",
        "name": "English",
        "nativeName": "English"
      }
    ],
    "translations": {
      "de": "Kleinere Inselbesitzungen der Vereinigten Staaten",
      "es": "Islas Ultramarinas Menores de Estados Unidos",
      "fr": "Îles mineures éloignées des États-Unis",
      "ja": "合衆国領有小離島",
      "it": "Isole minori esterne degli Stati Uniti d'America",
      "br": "Ilhas Menores Distantes dos Estados Unidos",
      "pt": "Ilhas Menores Distantes dos Estados Unidos",
      "nl": "Kleine afgelegen eilanden van de Verenigde Staten",
      "hr": "Mali udaljeni otoci SAD-a",
      "fa": "جزایر کوچک حاشیه‌ای ایالات متحده آمریکا"
    },
    "flag": "//restcountries.eu/data/umi.svg",
    "regionalBlocs": [],
    "cioc": ""
  }

For our tutorial, we only require the name value for each JSON object returned by the API. Let’s quickly implement this API in our web app to fetch the countries name based on user input.

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
        crossorigin="anonymous">

    <link rel="stylesheet" href="awesomplete.css">
    
    <script src="awesomplete.min.js"></script>
    
    <style>
        .awesomplete{
            display: block;
        }

        body{
            background-color: #F1F1F1
        }
       
    </style>
    <title>Javascript Autocomplete Demo</title>
    
</head>

<body>
    
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-8">
                <h1 class="mt-5 text-center">Javascript Autocomplete Demo</h1>
                <div class="card">
                    <div class="card-body shadow">
                            <div class="form-group mt-2">
                                <input type="text" class="form-control form-control-lg awesomplete" id="country-name" placeholder="Enter Any Country Name">
                            </div>
                    </div>
                </div>
            </div>
        </div>    
    </div>
    

    <!-- jQuery first then Bootstrap JS -->
    <script src="//code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>
    <script src="//stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
        crossorigin="anonymous"></script>
</body>

<script>
    const input = document.getElementById('country-name');
    // Init awesomplete
    const awesomplete = new Awesomplete(input);


    $('#country-name').keypress(function () {
        let country_name = $(this).val();

        // Check if atleast 2 chars are typed
        if(country_name.length >= 2){
            $.ajax({
                url: '//restcountries.eu/rest/v2/name/' + country_name,
                type: 'GET',
                dataType: 'json',
                success: function (response) {
                    prepareList(JSON.parse(JSON.stringify(response)));
                    
                },
                error: function (err) {
                    console.log(err);
                    
                }
            });
        }

    });


    function prepareList(list) {
        let c_list = [];
       
        list.forEach(item => {
            c_list.push(item.name);
        });
        
        // Assigned the c_list to the list property of Awesomplete instance
        awesomplete.list = c_list;
    }

</script>

</html>

Now if you try to type any country name inside the input field it will give you autocomplete suggestions based on your input. Let’s see it in action.

Customize your need with events in Awesomplete.

Now we have seen the power of Awesomplete but it’s time expect more from it. Awesomplete has many great features and it much extensible as I told you in the beginning. Awesomplete emits many events which can be useful if you have many other things to do once the user has selected an option and you want to perform some further calculations or DOM manipulations. Following events are provided by the Awesomplete,

  • awesomplete-select – The user has made a selection (either via pressing enter or clicking on an item), but it has not been applied yet. The callback will be passed an object with text (selected suggestion) and origin (DOM element) properties.
  • awesomplete-selectcomplete – The user has made a selection (either via pressing enter or clicking on an item), and it has been applied. The callback will be passed an object with a text property containing the selected suggestion.
  • awesomplete-close – The popup just closed. The callback will be passed an object with a reason property that indicates why the event was fired. Reasons include “blur”,”esc”, “submit”, “select”, and “nomatches”.
  • awesomplete-highlight – The highlighted item just changed (in response to pressing an arrow key or via an API call). The callback will be passed an object with a text property containing the highlighted suggestion.
  • awesomplete-open – The popup just appeared.

Let’s make use of awesomplete-selectcomplete event. As you might have seen the data fetch by the API, you can see that this API gives much information about any country in this world like it’s capital city, currency code and notation, a URL to view the flag of the country etc. Let’s show the flag of the country above the input field when a user selects any country from the suggestions. To achieve this first we need to add the image element in our code to display a flag.

<img class="card-img-top d-none" id="flag-img" style="object-fit: cover;" height="200px" src="" alt="Country Flag">

You need to place this code above the div with card-body class. You can see that I have also given a d-none class to it. This is Bootstrap 4 build in class to hide the element. Initially, we want our flag image to be hidden and we will display it once the user has selected any country with the help of JQuery. Now our JavaScript code looks like this,

<script>
    const input = document.getElementById('country-name');
    // Init awesomplete
    const awesomplete = new Awesomplete(input);

    // to store the country flags url
    var flags = [];

    $('#country-name').keypress(function () {
        let country_name = $(this).val();

        // Check if atleast 2 chars are typed
        if(country_name.length >= 2){
            $.ajax({
                url: '//restcountries.eu/rest/v2/name/' + country_name,
                type: 'GET',
                dataType: 'json',
                success: function (response) {
                    prepareList(JSON.parse(JSON.stringify(response)));
                    
                },
                error: function (err) {
                    console.log(err);
                    
                }
            });
        }

    });


    function prepareList(list) {
        const dataList = $('datalist');
        let options = '';
        let c_list = [];
        // empty the previous entries
        flags = [];
        list.forEach(item => {
            flags.push({'country': item.name, 'flagUrl': item.flag});
            c_list.push(item.name);
        });
        
        awesomplete.list = c_list;
    }

    window.addEventListener('awesomplete-selectcomplete',function () {
        let country = $('#country-name').val();
        // Get the image element
        const img = $('#flag-img');
        // loop through the flags array to find out selected country flag
        flags.forEach(item => {
            if ( item.country === country ) {
                // Set the country flag
                
                img.attr('src', item.flagUrl);
                // Show the image
                img.removeClass('d-none');
            }
        });
        
    });


</script>

While creating a list of countries fetched by the API, I am creating another array which will hold the JSON objects. We will create JSON objects which will hold the country name with the URL pointing to the country’s flag image.

Next,  as you can see I have attached an event listener to the window and listening for the awesomplete-selectcomplete. This event will be emitted by the Awesomplete once the user has finished selecting a country from the given list. Now let’s capture the country name from the input field and find the flag URL from flags array based on the country name and display it. The final code will be this,

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
        crossorigin="anonymous">


    <link rel="stylesheet" href="awesomplete.css">
    
    <script src="awesomplete.min.js"></script>
    

    <style>
        .awesomplete{
            display: block;
        }

        body{
            background-color: #F1F1F1
        }

       
    </style>

    <title>Javascript Autocomplete Demo</title>

    
</head>

<body>
    
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-8">
                <h1 class="mt-5 text-center">Javascript Autocomplete Demo</h1>
                <div class="card">
                    <img class="card-img-top d-none" id="flag-img" style="object-fit: cover;" height="200px" src="" alt="Country Flag">
                    <div class="card-body shadow">
                        
                            <div class="form-group mt-2">
                                <input type="text" class="form-control form-control-lg awesomplete" id="country-name" placeholder="Enter Any Country Name To See It's Flag">
                                
                            
                            </div>
                    </div>
                </div>
            </div>
        </div>    
    </div>
    

    <!-- jQuery first, then Bootstrap JS -->
    <script src="//code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>
    
</body>

<script>
    const input = document.getElementById('country-name');
    // Init awesomplete
    const awesomplete = new Awesomplete(input);

    // to store the country flags url
    var flags = [];

    $('#country-name').keypress(function () {
        let country_name = $(this).val();

        // Check if atleast 2 chars are typed
        if(country_name.length >= 2){
            $.ajax({
                url: '//restcountries.eu/rest/v2/name/' + country_name,
                type: 'GET',
                dataType: 'json',
                success: function (response) {
                    prepareList(JSON.parse(JSON.stringify(response)));
                    
                },
                error: function (err) {
                    console.log(err);
                    
                }
            });
        }

    });


    function prepareList(list) {
        const dataList = $('datalist');
        let options = '';
        let c_list = [];
        // empty the previous entries
        flags = [];
        list.forEach(item => {
            flags.push({'country': item.name, 'flagUrl': item.flag});
            c_list.push(item.name);
        });
        
        awesomplete.list = c_list;
    }

    window.addEventListener('awesomplete-selectcomplete',function () {
        let country = $('#country-name').val();
        // Get the image element
        const img = $('#flag-img');
        // loop through the flags array to find out selected country flag
        flags.forEach(item => {
            if ( item.country === country ) {
                // Set the country flag
                
                img.attr('src', item.flagUrl);
                // Show the image
                img.removeClass('d-none');
            }
        });
        
    });


</script>

</html>

Download The Complete Project Files

If you face any issue or have any suggestions then write it in the comment box…

Happy Coding……:)

 

Ropali Munshi
Ropali Munshi
Ropali Munshi is fullstack PHP Developer. He is passionate developer who loves to learn and expirement with new programming languages , libraries and frameworks. Nowdays he is more into the JavaScript realm.

1 Comment

  1. Chante says:

    Great article. I will be going through a few of these issues as
    well..

Leave a Reply

Your email address will not be published. Required fields are marked *

You Don't Want To Miss It!

Please subscribe to our newsletter. Every week I share tips, tricks, tutorials, free books & video course directly in your inbox.