Custom auto-complete view – Vanilla Javascript

Autocomplete, or word completion, is a feature in which an input field predicts the rest of a word a user is typing. In most frequently fields like city names, users can typically enter some words and wait for seeing the suggestions to accept one of several cities.

Autocomplete speeds up human-computer interactions when it correctly predicts the word a user intends to enter after only a few characters have been typed into a text input field. It works best in domains with a limited number of possible words (such as in command-line interpreters), when some words are much more common (such as when addressing an e-mail), or writing structured and predictable text (as in source code editors).

In search engines like Google, autocomplete user interface features provide users with suggested queries or results as they type their query in the search box. This is also commonly called autosuggest or incremental search. This type of search often relies on matching algorithms that forgive entry errors such as phonetic Soundex algorithms or the language-independent Levenshtein algorithm. The challenge remains to search large indices or popular query lists in under a few milliseconds so that the user sees results pop up while typing.

Nothing gives you more control than writing code by yourself.

Unknown

Autocomplete can have an adverse effect on individuals and businesses when negative search terms are suggested when a search takes place. Autocomplete has now become a part of reputation management as companies linked to negative search terms such as scam, complaints and fraud seek to alter the results. Google in particular have listed some of the aspects that affect how their algorithm works, but this is an area that is open to manipulation.

Suppose you have a list of values that you want to populate in an input field as user types. Give users an ability to select an item from that list and store the data. For example, if you have a list of products, you can display product title but once any value is selected, you can send the product ID in database. Although there are many libraries on the internet to do this job, but they are limited in customizations and you have to remember their function names and parameters and options etc.

First we are going to create an input field that will have an ability to call a Javascript function as soon as user types something in it. We are attaching the “onkeyup” attribute on that field which will be called for every key pressed by the user. We are also giving this field an ID and name attribute:

  • ID will be use in Javascript to populate suggestions based on this field value.
  • Name will be use in PHP where form data will be sent. You can handle this as per your project.

Form’s method and action attribute depends on your project, you can adjust them as per your needs. We have also created a hidden field which will set the ID of selected product. So we will be displaying product title in suggestions, when user select one product, it’s ID will be put in this hidden field. Lastly, we have a div where all suggested products will be displayed.

<form method="POST" action="send-data.php">
    <input type="text" id="product" name="product" onkeyup="onKeyUp();">
    <input type="hidden" id="productCode" name="productCode">
    <div id="products-list"></div>
</form>

Send HTTP request

First we will create a function for “onkeyup” event that we attached on previous step. In this function, we are getting value from product’s input field. We will get the suggested products only if the input field has at-least 3 words in it. Because sending HTTP request on each word would be very costly and it does not make sense at all. When you search for some product you already know first 4 or 5 characters of it. Even in case of cities, most people know at-least 3-4 characters of what they want to search. Displaying suggestions on each word would be really annoying for users.

Then in div where we wanted to show the suggested products, we will first show a loading message so that the user knows that it is searching for products and the location where suggested products will be displayed. Then we are sending an AJAX request, the request method is GET so it does not require any headers in the request. Second parameter in open function is the name of file, we will create that file in next step. In same parameter, we are sending user entered words in the URL so we can get them in that PHP file. At the end of this function we are sending the request. But before sending, we are attaching an event which will be called when the response is successfully received from server.

From get-products.php file which we will create in next step, we will receive all the suggested products based on value of input field. The response sent from PHP to Javascript will be in JSON string format, so we have to convert (parse) that string to Javascript objects and arrays. Then we will loop through all the suggested products and display them in paragraph. A separate variable is created which will store all the HTML content of the autocomplete view. Finally, we are setting this HTML variable value to div using its unique ID.

<script>
    function onKeyUp() {
        var product = document.getElementById("product");

        if (product.value.length >= 3) {
            document.getElementById("products-list").innerHTML = "Loading...";

            var ajax = new XMLHttpRequest();
            ajax.open("GET", "get-products.php?product=" + product.value, true);

            ajax.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    var data = JSON.parse(this.responseText);
                    var html = "";

                    for (var a = 0; a < data.length; a++) {
                        html += "<p>" + data[a].productName + "</p>";
                    }

                    document.getElementById("products-list").innerHTML = html;
                }
            };

            ajax.send();
        }
    }
</script>

Get suggested products

So we are sending HTTP request after 3 words entered by the user and sending those 3 words to the server to fetch suggested products that match their title with those 3 words. Now we need to create a file that will match the product’s title with those words and return them all as an array. So we are first connecting with the database, get the user input field from URL. Search that value in the database based on the products table’s title field (it might be different as per your need). Executing that query will return a $result object, it will have all pieces of information about the result which is received from the database. For example, number of rows, columns in each row, each row’s content, etc.

You can use the mysqli_fetch_all function to return all rows at once but this function does not work in some PHP versions. So what we are going to do, is to loop through each record and push them in our created array one-by-one. We will be using while loop to continue loop until all rows are fetched. At the end, we will have a PHP array will all the suggested products. But we need them in Javascript, so we need to convert that array into JSON string format and in Javascript we are already converting that string back to Javascript arrays and objects.

get-products.php

<?php

	$conn = mysqli_connect("localhost", "root", "root", "classicmodels");
	$product = $_GET["product"];

	$sql = "SELECT * FROM products WHERE productName LIKE '%" . $product . "%'";
	$result = mysqli_query($conn, $sql);

	$data = array();
	while ($row = mysqli_fetch_object($result))
	{
		array_push($data, $row);
	}
	echo json_encode($data);

?>

Select product from suggestions

At this point, as the user starts typing the input field, after 3 words a list of suggested products will be displayed. Now we need to give the user an ability to select a product from this suggested list. First, we need to attach on “onclick” listener to the product’s title in a suggestions list that will call a Javascript function whenever the user selects a product from the list. In that function we are going to need a selected product ID, so we are adding a custom attribute data-id whose value will be the product ID that should be set in the hidden input field. In that function, we are getting the selected product ID and setting this in the hidden product code field. Also, we are emptying the div so the suggestions will be removed once an item is selected from the list. Lastly, in input field we are setting product’s title as a value because the user has only entered 3 words, once he selects some item from the list, that value will be set in his input field.

function selectProduct(self) {
	var productCode = self.getAttribute("data-id");
	document.getElementById("productCode").value = productCode;
	document.getElementById("products-list").innerHTML = "";
	document.getElementById("product").value = self.innerHTML;
}

// Inside AJAX response
for (var a = 0; a < data.length; a++) {
	html += "<p onclick='selectProduct(this);' data-id='" + data[a].productCode + "'>" + data[a].productName + "</p>";
}

Applying styles

Although this part has nothing to do with functionality, but it is always good to do some work on the design and make it look good. Add a CSS class to suggested products single paragraph, and create a <style> tag anywhere in your file and use that CSS class to applying styles as per your needs.

// Inside the loop in AJAX response, give CSS class
html += "<p class='product-list-item' onclick='selectProduct(this);' data-id='" + data[a].productCode + "'>" + data[a].productName + "</p>";

<style>
    .product-list-item {
        background: darkgray;
        color: white;
        width: 200px;
        padding: 15px;
        border-radius: 5px;
        cursor: pointer;
    }
</style>

Leave a Reply

Please disable your adblocker or whitelist this site!