What is the best way to design a drop-down suggestion list similar to Google's?

This question is still in the theoretical stage, but it's something I'm definitely considering for the long run. When you visit google.com and type in a search query, the site provides suggestions in a dropdown menu. I'm pretty sure they use AJAX to send the typed text and receive a list of suggestions in return. What I'm curious about is how they format and display that list. It appears to be a simple dropdown menu, similar to an HTML select element, but without the select box at the top. I'm confident that the solution is a straightforward CSS trick that separates the select box from the dropdown list it generates, or possibly using an input type other than select, but I can't seem to figure it out.

Answer №1

Responding a bit late here, but I must say that W3schools has truly excelled in this area.

Only utilizing HTML, CSS, and Pure JavaScript. You should definitely check it out.

Here is the link: W3Schools Auto Complete

In case the link is removed, I'll include the code below for reference.

function autocomplete(inp, arr) {
  // Autocomplete function takes the text field element and an array of possible values
  var currentFocus;
  // Function executes when typing in the text field
  inp.addEventListener("input", function(e) {
      var a, b, i, val = this.value;
      // Close any existing lists of autocompleted values
      closeAllLists();
      if (!val) { return false;}
      currentFocus = -1;
      // Create a DIV element to contain the autocompleted values
      a = document.createElement("DIV");
      a.setAttribute("id", this.id + "autocomplete-list");
      a.setAttribute("class", "autocomplete-items");
      // Append DIV element as a child of the autocomplete container
      this.parentNode.appendChild(a);
      // Loop through array items
      for (i = 0; i < arr.length; i++) {
        // Check if item matches the input value
        if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
          b = document.createElement("DIV");
          b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
          b.innerHTML += arr[i].substr(val.length);
          b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
          b.addEventListener("click", function(e) {
              inp.value = this.getElementsByTagName("input")[0].value;
              closeAllLists();
          });
          a.appendChild(b);
        }
      }
  });
  inp.addEventListener("keydown", function(e) {
      var x = document.getElementById(this.id + "autocomplete-list");
      if (x) x = x.getElementsByTagName("div");
      if (e.keyCode == 40) {
        currentFocus++;
        addActive(x);
      } else if (e.keyCode == 38) {
        currentFocus--;
        addActive(x);
      } else if (e.keyCode == 13) {
        e.preventDefault();
        if (currentFocus > -1) {
          if (x) x[currentFocus].click();
        }
      }
  });
  function addActive(x) {
    if (!x) return false;
    removeActive(x);
    if (currentFocus >= x.length) currentFocus = 0;
    if (currentFocus < 0) currentFocus = (x.length - 1);
    x[currentFocus].classList.add("autocomplete-active");
  }
  function removeActive(x) {
    for (var i = 0; i < x.length; i++) {
      x[i].classList.remove("autocomplete-active");
    }
  }
  function closeAllLists(elmnt) {
    var x = document.getElementsByClassName("autocomplete-items");
    for (var i = 0; i < x.length; i++) {
      if (elmnt != x[i] && elmnt != inp) {
        x[i].parentNode.removeChild(x[i]);
      }
    }
  }
  document.addEventListener("click", function (e) {
      closeAllLists(e.target);
      });
}

var countries = ["Afghanistan","Albania", ... ]; // Array containing country names

autocomplete(document.getElementById("myInput"), countries);
* {
  box-sizing: border-box;
}
body {
  font: 16px Arial;  
}
.autocomplete {
  position: relative;
  display: inline-block;
}
input {
  border: 1px solid transparent;
  background-color: #f1f1f1;
  padding: 10px;
  font-size: 16px;
}
input[type=text] {
  background-color: #f1f1f1;
  width: 100%;
}
input[type=submit] {
  background-color: DodgerBlue;
  color: #fff;
  cursor: pointer;
}
.autocomplete-items {
  position: absolute;
  border: 1px solid #d4d4d4;
  border-bottom: none;
  border-top: none;
  z-index: 99;
  top: 100%;
  left: 0;
  right: 0;
}
.autocomplete-items div {
  padding: 10px;
  cursor: pointer;
  background-color: #fff; 
  border-bottom: 1px solid #d4d4d4; 
}
.autocomplete-items div:hover {
  background-color: #e9e9e9; 
}
.autocomplete-active {
  background-color: DodgerBlue !important; 
  color: #ffffff; 
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>     
<body>

<h2>Autocomplete</h2>

<p>Start typing:</p>

<form autocomplete="off" action="/action_page.php">
  <div class="autocomplete" style="width:300px;">
    <input id="myInput" type="text" name="myCountry" placeholder="Country">
  </div>
  <input type="submit">
</form>
</body>
</html>

Answer №2

There are a few ways you can approach this. You could utilize a select dropdown positioned directly under the input field for typing in keywords, ensuring it is styled with CSS to be absolutely positioned and have a lower z-index than the input text.

Alternatively, you could implement a more intricate solution by creating an unordered list styled to look like a dropdown. With this option, you can even include images (icons) alongside text suggestions. In this case, the ul should be positioned beneath the input field, hover effects should be created for the selected list items, and click events should be set up for each list item to populate the text input with the selected keyword and hide the list.

Hopefully, this clarifies things for you!

Answer №3

Utilize jQuery AutoComplete for enhanced user experience:

By triggering a JavaScript event onKeyUp, an ajax request is sent with the current input value. This request is then processed by PHP to search the database for relevant keywords, returning the results to JavaScript.

JavaScript evaluates the ajax response and populates a select dropdown with the retrieved data in an absolute position.

The select dropdown includes an onClick event that transfers the selected value back to the input field.

Apologies for any language barriers, I am striving to provide a clear explanation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Running JavaScript within Objective-C in a Cordova plugin

I'm working with cordova version 6.5.0 and I'm trying to develop a plugin that can execute some javascript code. I've read on various forums that I can use stringByEvaluatingJavascriptFromString method in my webview, but it seems like it&ap ...

Warning: ComponentMounts has been renamed. Proceed with caution

I'm encountering a persistent warning in my application and I'm struggling to resolve it. Despite running npx react-codemod rename-unsafe-lifecycles as suggested, the error persists and troubleshooting is proving to be challenging. The specific w ...

When using React Final Form, the onBlur event can sometimes hinder the

What is the reason that validation does not work when an onBlur event is added, as shown in the example below? <Field name="firstName" validate={required}> {({ input, meta }) => ( <div> <label>First Name</label& ...

Guide to adjusting the color of Fluent UI icon when hovering with mouse?

I've been implementing Fluent UI in my current project. When initializing my button, I use this straightforward JavaScript code: iconProps: { iconName: 'NewFolder', styles: { root: { color: 'orang ...

Using Rxjs to dynamically map values from an array with forkJoin

Greetings! I have a collection of Boolean observables and would like to apply a logical AND operation. Currently, I am passing static values 'a' and 'b', but I am unsure of the number of elements in the totalKeys array. import { forkJoi ...

How can I add an element to the DOM in React before the render() method is executed?

Currently, I am working with React in conjunction with Rails and incorporating a charting library known as AnyChart. However, the AnyChart code in my render method automatically searches for a <div id="container"></div> element to connect the c ...

Obtain a byte array from an AngularJs controller

In my Angular controller, I am working with a byte array. When the download button is clicked in the view, I want to trigger the browser's download/saveAs dialog with 'report.pdf' as the pre-populated filename and PDF as the file type. After ...

Switch between various chart types in Highcharts for multiple series by utilizing a dropdown menu

Hey there, I'm new to the world of programming and I'm currently working on creating a chart with a drop-down list for chart types. I've tried several solutions suggested here, but unfortunately, none of them seem to work with my code. Any h ...

Obtain JSON data through an HTTP POST call

Here is a function that I have, which was mainly borrowed from the solution to another problem on SO: function sendPostRequest(url, data) { request( { url: url, method: "POST", json: true, body: data }, function(error, response, body) ...

Sort a JSON object in ascending order with JavaScript

I have a JSON object that needs to be sorted in ascending order. [{ d: "delete the text" }, { c: "copy the text" }] The keys d and c are dynamically generated and may change. How can I sort this into? [{ c: "copy the text" }, { d: "delete the text" }] ...

Update a particular class following an AJAX POST request in JavaScript

After conducting extensive research, I have come here seeking your assistance with a particular issue: I am using a comment system with multiple forms on the same page (utilizing FOSCommentBundle in Symfony). My goal is to be able to post comments via Aja ...

submit information using AJAX with jQuery

My goal is to save data in a database when a button is clicked. However, I'm facing an issue where the code works in some browsers but not in Firefox. When I click the button, an empty alert pops up and the data is not saved in the table. $("#Sav ...

Add HTML syntax highlighting to a text area for coding purposes

I am facing a seemingly straightforward issue, but I worry that it may be too complex for me to handle on my own. My goal is to incorporate a textarea into a webpage where users can input HTML code, click a button, and have the interpreted HTML displayed i ...

Issue with jQuery.parseJSON causing empty data structure to return

I am facing a puzzling problem with manipulating data in JavaScript. The code snippet I am using in JavaScript is to fetch data from a PHP/MySQL source. var _response = jQuery.ajax({ url: "../data", async: false, type: "post", data: oPara ...

Tips for tackling challenges with PHP/MySQL and utilizing Ajax, comet, or long polling techniques

My current websites are built on a PHP/MySQL framework and have several features like chat, events, and interval ajax implementations that are causing high server load. With the websites growing larger, I'm looking to switch to long polling/comet tech ...

transfer chosen data from a text box to a dropdown menu

Looking for: I am in need of a feature where users can input a movie title in a textbox and upon clicking the "move to selectedlist" button, the entered movie title should be added to a dropdown list that displays all the movies selected by the user. Addit ...

Discovering the PHP error message that is sent to AJAX through JQuery

This is the code snippet that works: $.ajax({ type: 'POST', url: 'register.php', data: {captcha: captcha }, success: function() { $('#loading').hide() ...

What causes the error "Failed to load SWC binary for win32/x64" when using getStaticProps?

Encountering an issue while using getStaticProps() in a Next.js application, resulting in the following error when running the app: warn - Attempted to load @next/swc-win32-x64-gnu, but it was not installed warn - Attempted to load @next/swc-win32-x64-ms ...

What reasons underlie the existence of various methods for importing Modules in JavaScript?

I'm confused about the distinctions when it comes to importing a JavaScript module in various ways such as: CommonJS ES5 ES6 NodeJS Typescript What is the reason for having multiple methods of importing JavaScript modules? Is the concept of a "modu ...

Customizing Cell Templates in Angular UI-Grid Based on Conditions

I am struggling to display a button in my ui-grid only when the field value is not an empty string. I attempted using the ng-if directive, but it is not functioning as expected. Below is the snippet from my grid options: { field: 'ReleaseStatus&apo ...