Web UI - How to create an Autocompletion functionality with CSS, Javascript and HTML

About

This article shows you how to create the below input box with an autocompletion feature.

_

Autocompletion is the fact to present to the user possible values that have been chosen from its input.

You will find it in:

This is an advanced subject that requiert a good basic knowledge of:

Overview

The implementation of an autocomplete works with the following component:

and the following actions:

You may add more action such as arrow down to be able to use only the keyboard.

We will implement all this components below.

Steps

The input box

Below we have created the input box with the HTML input element of text type (we may have also use the search input box)

<input 
    id="color-control" 
    type="search" 
    name="color" 
    placeholder="Type a color" 
    autocomplete="off"
>

The HTML autocomplete is on by default and shows the last entered values, we disable it with the autocomplete attribute to off.

The autocompletion list

The popover contains the autocompletion list

It will be created and refreshed for every value change.

  • In html, it will looks like that:
<ul id="color-autocompletion-popover">
    <li>Blue</li>
    <li>Red</a></li>
    <li>Yellow</li>
    <li>...</li>
</ul>
  • The styling (by default a list has a bullet and a margin that we delete)
 
#color-autocompletion-list {
  padding: 0;
  list-style-type: none;
  border: 1px solid rgba(0,0,0,.125);
  border-radius: .25rem;
  width: fit-content;
}
#color-autocompletion-list li {
   padding: 1rem;
}
#color-autocompletion-list li:hover {
    color: #fff;
    background-color: #6c757d;
    border-color: #6c757d;
}
  • In Javascript, we would could create the above completion list with the following function that uses javascript regular expression to filter the data
/* The possible values */
let colors = ["Blue","Red","Yellow"];

/**
  The function that creates the autocompletion list with:
    * a search term as parameter
    * the listElement that receives the list item
    * the inputBox to receive the value when an element is clicked
*/
function addAutoCompletionListItem(searchTerm, listElement, inputBox){
   console.log(`filtering value ${searchTerm}`);
   /* Reset the content */
   listElement.innerHtml=""
   /* No search term */
   if(searchTerm==""){
      return;
   }
   /* Filtering of the data */
   let pattern = new RegExp(`.*${searchTerm}.*`,"i");
   let selectedColors = colors.filter(e=>pattern.test(e));
   if (selectedColors.length==0){
     return;
   }
   /* Creation of the above autocompletion list item */
   for(color of selectedColors){
        let li = document.createElement("li");
        /* To be able to determine that an item was clicked */
        li.classList.add("color-autocompletion-list-item");
        /* We make li focusable to get on the relatedTarget it when we click  */
        li.setAttribute("tabindex","0");
        li.innerText = color;
        /* When the element is clicked, set the value of the search Box */
        li.addEventListener("click", function(){;
             if (inputBox != undefined){
                /* Set the value in the input box */
                inputBox.value = this.innerText;
                /* Remove the list */
                listElement.remove();
             } else {
               console.log(`No input box defined, the selected value was ${this.innerText}`);
             }
        });
        listElement.append(li);
   }
   return listElement;
}
let completionList = document.createElement("ul");
completionList.setAttribute("id","color-autocompletion-list");
completionList = addAutoCompletionListItem(".*", completionList);
document.body.insertAdjacentElement('afterbegin', completionList);
  • Output: Hover over the list and click on an element

You could also encapsulate and create a class (or prototype) for an autocompletion list item.

The display of the autocompletion list

The previous autocompletion list should be:

  • shown when the input element has focus
  • deleted when the input element has lose focus (ie blur

This section shows you how.

  • First, we add some position attribute to the list to make it an overlay
#color-autocompletion-list {
  position: absolute; 
  inset: 0px auto auto 0px;  /*  top, right, bottom, and/or left */
  margin: 0px; 
  transform: translate(10px, 41px);
  background-color: white;
}
  • The below Javascript code shows how we:
    • create the autocompletion list on focus
    • add it with insertAdjacent as a sibling of the input box
    • delete the autocompletion list on blur
/* The input element */
let inputBox = document.getElementById("color-input");

/* The list */
let completionList = document.createElement("ul");
completionList.setAttribute("id","color-autocompletion-list");

/* on focus, create the autocompletion list */
inputBox.addEventListener("focus", function(){
    
    /* on focus, create the list */
    completionList  = setAutoCompletionListItem(".*",completionList ,this);
    inputBox.insertAdjacentElement('afterend',completionList);
    
    /* on blur, delete it */
    inputBox.addEventListener("blur", function(event){
        /* blur can also happen when we click on a list item, we don't remove the list in this case */
        if (event.relatedTarget == null ||
           (event.relatedTarget  !=null && !event.relatedTarget.classList.contains("color-autocompletion-list-item"))){
           completionList.innerHTML = "";
           completionList.remove();
        }
    });
});
  • Result:
    • Click on the input box, you will see the whole list
      • Select an item, the value would go into the input box
      • Or click to the right, the auto-completion list would disappear

The filtering of the autocompletion list

To filter the values of the autocompletion list when a user enters a value into the input box, we need to use the input event.

This event fires each time the input value changes.

/* The input element */
var inputBox = document.getElementById("color-input");

/* The list */
var completionList = document.createElement("ul");
completionList.setAttribute("id","color-autocompletion-list");

/* on the input event, create and filter the autocompletion list with the value */
inputBox.addEventListener("input", function(){
    let searchTerm = this.value;
    if (this.value==""){
       searchTerm = ".*";
    }
    completionList = setAutoCompletionListItem(searchTerm,completionList,this);
});
  • Result:
    • Enter a value in the input box and see the filtering happening
    • Delete the value or take focus to see the whole list again

Final thoughts and Library

This is it, you got all elements of an auto-completion list. You can refactor it:

And if you don't want to develop your own, your can always use a library.


Powered by ComboStrap