Creating an Autocomplete Search Feature Using Vanilla JavaScript

Autocomplete search is a powerful feature often used in search fields to provide real-time suggestions as users type. We’ll build a simple input field that sends user input via an AJAX request to a server-side page, which returns matching results to be displayed as clickable suggestions.

Requirements

Before we start, ensure you have a server-side script (PHP, for example) that takes a query parameter and returns results based on that query.

HTML Structure

Here’s the basic structure for the autocomplete input field:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Autocomplete Example</title>
    <style>
        * { font-family: Helvetica, sans-serif; }
        body { font-size: 14px; }

        .autosuggest {
            border: 1px solid #333;
            background-color: #fff;
            position: absolute;
            display: none;
            z-index: 999;
        }

        .autosuggest a {
            display: block;
            padding: 3px;
            color: #333;
            text-decoration: none;
        }

        .autosuggest a:hover {
            background-color: #333;
            color: #fff;
        }
    </style>
</head>
<body>

<h2>Search Autocomplete</h2>
<p>
    <input type="search" size="48" name="example" id="color" placeholder="Type your search terms...">
    <label for="color">Search terms</label>
</p>

<script src="autocomplete.js"></script>
</body>
</html>

JavaScript Code for Autocomplete

Now, let’s write the JavaScript code to implement the autocomplete feature. We will use fetch for AJAX requests and native DOM manipulation to display suggestions.

// Minimum number of characters before triggering the search
const autosuggestMinLength = 3;

// Function to handle the autocomplete feature
function autocomplete(inputElement) {
    const id = inputElement.id;
    const offset = inputElement.getBoundingClientRect();
    const left = offset.left;
    const top = offset.top + inputElement.offsetHeight + 5;
    const width = inputElement.offsetWidth + 5;

    // Create the autosuggest dropdown
    const autosuggestContainer = document.createElement('div');
    autosuggestContainer.id = `autosuggest_${id}`;
    autosuggestContainer.classList.add('autosuggest');
    autosuggestContainer.style.left = `${left}px`;
    autosuggestContainer.style.top = `${top}px`;
    autosuggestContainer.style.width = `${width}px`;

    // Append the dropdown to the body
    document.body.appendChild(autosuggestContainer);

    // Listen for keyup events on the input field
    inputElement.addEventListener('keyup', function () {
        const query = inputElement.value;

        if (query.length >= autosuggestMinLength) {
            // Send the query to the server
            fetch(`${inputElement.getAttribute('rel')}?q=${query}`)
                .then(response => response.text())
                .then(data => {
                    if (data.length > 0) {
                        // Split the returned data by pipe delimiter and create links
                        const pairs = data.split('|');
                        let resultHTML = '';
                        pairs.forEach(pair => {
                            resultHTML += `<a href="javascript:void(0);" onclick="selectSuggestion('${pair}', '${id}')">${pair}</a>`;
                        });

                        // Display the suggestions
                        autosuggestContainer.innerHTML = resultHTML;
                        autosuggestContainer.style.display = 'block';
                    } else {
                        // Hide the dropdown if no results
                        autosuggestContainer.style.display = 'none';
                    }
                })
                .catch(error => console.error('Error fetching suggestions:', error));
        } else {
            // Hide the dropdown if input is too short
            autosuggestContainer.style.display = 'none';
        }
    });
}

// Function to select a suggestion and fill the input
function selectSuggestion(value, inputId) {
    const inputElement = document.getElementById(inputId);
    inputElement.value = value;
    document.getElementById(`autosuggest_${inputId}`).style.display = 'none';
}

// Initialize the autocomplete for the input field
document.addEventListener('DOMContentLoaded', function () {
    const inputElement = document.getElementById('color');
    inputElement.setAttribute('rel', 'colors.php'); // Specify the URL for the server-side script
    autocomplete(inputElement);
});

How the JavaScript Code Works

  1. autosuggestMinLength: This sets the minimum number of characters required to trigger the autocomplete feature. In this case, the search will trigger after the user types 3 characters.
  2. autocomplete function: This function handles the core logic of the autocomplete feature. It:
    • Creates a container (<div>) for the suggestions dropdown and positions it near the input field.
    • Listens for keyup events on the input element, and when the input length reaches the specified minimum, it sends an AJAX request (via fetch) to the specified URL (rel attribute).
    • It processes the server’s response, splits it by the pipe (|) delimiter, and creates clickable links for each suggestion.
    • It displays the dropdown container with the suggestions, or hides it if no results are returned.
  3. selectSuggestion function: This function is triggered when a user clicks on a suggestion. It fills the input field with the selected value and hides the suggestion dropdown.
  4. Event Listener: Once the DOM is fully loaded, we initialize the autocomplete functionality by calling autocomplete on the input element with the id="color".

PHP Server-Side Script (Example)

The server-side PHP script (colors.php) handles the query and returns matching results. Here’s an example:

<?php
include '../../../wp-load.php';

global $wpdb;

$q = sanitize_text_field( $_GET['q'] ); // Get the query parameter

$sql = "SELECT * FROM `{$wpdb->prefix}usermeta` WHERE meta_key='rl_location' AND meta_value LIKE '%{$q}%' GROUP BY meta_value";
$result = $wpdb->get_results($sql);

if ($result) {
    foreach ($result as $row) {
        echo $row->meta_value . '|'; // Return results as a pipe-delimited list
    }
}

This script performs a search on a database table and returns results as a pipe-delimited string. You can modify this to fit your own backend logic.

on in AJAX and Fetching Data | Last modified on

Related Posts

Leave a Reply

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