Javascript

Create autocomplete using vanilla JavaScript

To create autocomplete feature for input field(s), HTML’s datalist tag can be the easiest solution. But it has limited styling and also some browser support issues. So, let’s create our own stylish autocomplete using vanilla JavaScript and Bootstrap for style.

HTML Part : Create a div and the input field inside of it.

<div class="autocomplete">
    <label class="form-label">Programming Language :</label>
    <input type="text" placeholder="Start typing..." class="form-control" id="myInput">
</div>

 

JavaScript Part : Let’s create our function. The function will accept 2 arguments. The first argument is the input field, and the other argument is the array of suggestions.

var programming_languages = ["Ada", "APL", "Assembly language", "BASIC", "C", "C#", "C++", "Cobol", "Dart", "Delphi", "Forth", "Fortran", "FoxPro", "Golang (Go)", "Groovy", "Haskell", "Java", "JavaScript", "Kotlin", "Lisp", "Lua", "MATLAB", "Objective C", "Pascal", "Perl", "PHP", "PowerShell", "Python", "Qbasic", "R", "Ruby", "Rust", "Scala", "Shell", "Smalltalk", "SQL", "Swift", "TypeScript", "Visual Basic", "Visual Basic .NET"];

function autocomplete(autocomplete_input, suggestions) {
    var currentOption;
    var total_autocomplete = document.getElementsByClassName('autocomplete-input').length

    autocomplete_input.parentNode.style.position = "relative";
    autocomplete_input.classList.add('autocomplete-input');
    autocomplete_input.setAttribute('data-autocomplete-list-id', "autocomplete-list-" + (total_autocomplete + 1));
    autocomplete_input.setAttribute('autocomplete', "off");

    autocomplete_input.addEventListener("input", function(e) {
     var $this = this;
        var string_to_match = $this.value.toLowerCase();
        var autocomplete_list_id = $this.getAttribute('data-autocomplete-list-id');

        removeLists();

        if (string_to_match) {
            currentOption = -1;
            var regex = new RegExp( '(' + string_to_match + ')', 'gi' );

            var autocomplete_list = document.createElement("DIV");
         autocomplete_list.setAttribute("id", autocomplete_list_id);
         autocomplete_list.setAttribute("class", "autocomplete-list shadow border");
         autocomplete_list.style.marginTop = "5px";
         autocomplete_list.style.maxHeight = "300px";
         autocomplete_list.style.overflowY = "auto";

         var autocomplete_items = document.createElement("DIV");
         autocomplete_items.setAttribute("class", "list-group list-group-flush autocomplete-items");

         suggestions.forEach(function(suggestion) {
          if (suggestion.toLowerCase().includes(string_to_match)) {
           var autocomplete_item = document.createElement("DIV");
                 autocomplete_item.setAttribute('class', 'list-group-item list-group-item-action');
           autocomplete_item.setAttribute("data-autocomplete-text", suggestion);
                 autocomplete_item.innerHTML = suggestion.replace(regex, "<b>$1</b>" );

                 autocomplete_item.addEventListener("click", function(e) {
                     autocomplete_input.value = this.getAttribute("data-autocomplete-text");
                     autocomplete_items.remove();
                 });

                 autocomplete_items.appendChild(autocomplete_item);
          }
         });

         autocomplete_list.appendChild(autocomplete_items);
         $this.parentNode.appendChild(autocomplete_list);
        }
    });

    autocomplete_input.addEventListener("keydown", function(e) {
        var autocomplete_list_id = this.getAttribute('data-autocomplete-list-id');
     var autocomplete_list = document.getElementById(autocomplete_list_id);

     if ( autocomplete_list ) {
      var autocomplete_items = autocomplete_list.querySelector('.autocomplete-items').getElementsByTagName("div");
      
      if (e.keyCode == 40) {
             currentOption++;
             selectItem(autocomplete_items);
         } else if (e.keyCode == 38) {
             currentOption--;
             selectItem(autocomplete_items);
         } else if (e.keyCode == 13) {
             e.preventDefault();
             if (currentOption > -1) {
                 if (autocomplete_items) {
                  autocomplete_items[currentOption].click();
                 }
             }
         }
     }
    });

    function selectItem(autocomplete_items) {
        if (autocomplete_items) {
      Array.from(autocomplete_items).forEach(autocomplete_item => {
       autocomplete_item.classList.remove("active");
   });
      
      currentOption = currentOption >= autocomplete_items.length ? 0 : currentOption;
      currentOption = currentOption < 0 ? autocomplete_items.length - 1 : currentOption;

         autocomplete_items[currentOption].classList.add("active");
        }
    }

    function removeLists(element) {
        var autocomplete_lists = document.getElementsByClassName("autocomplete-list");
        Array.from(autocomplete_lists).forEach(autocomplete_list => {
            if (element != autocomplete_list && element != autocomplete_input) {
       autocomplete_list.remove();
            }
  });
    }

    document.addEventListener("click", function(e) {
        removeLists(e.target);
    });
}

autocomplete(document.getElementById("myInput"), programming_languages);

 

You can see it in action here:

S M Zahed Kamal

Recent Posts

PHP to remove unnecessary key and value pairs from any multi-dimensional array

Today I will share a snippet I've used in a project. Using that function, you…

2 years ago

Use vanilla JavaScript to make Ajax request

JavaScript AJAX (Asynchronous JavaScript and XML) is a technique that gives the ability to send…

3 years ago

Add animation to bootstrap carousel elements

By default, Bootstrap carousel has no way to add animations to carousel elements. Here I'm…

3 years ago

Create custom pagination template in Laravel

Laravel comes up with a paginator that generates HTML compatible with the Tailwind CSS framework.…

3 years ago

Add Bootstrap Icons in SASS or SCSS

Bootstrap introduced their icons collection in November 2019 as Bootstrap Icons (v1.0.0-alpha). At that time,…

3 years ago

Use gulp to automate SASS to CSS compilation

Gulp is a toolkit to automate & enhance our workflow. Most of the time, I…

3 years ago