Address Autocomplete Tutorial
Create an Address Input with suggestions by using Geoapify Address Autocomplete API
by Geoapify
HTML
<div class="autocomplete-container" id="autocomplete-container"></div>
CSS
body {
font: 16px;
background: #f3f5f6;
}
.autocomplete-container {
margin-bottom: 20px;
}
.input-container {
display: flex;
position: relative;
}
.input-container input {
flex: 1;
outline: none;
border: 1px solid rgba(0, 0, 0, 0.2);
padding: 10px;
padding-right: 31px;
font-size: 16px;
}
.autocomplete-items {
position: absolute;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.1);
border-top: none;
background-color: #fff;
z-index: 99;
top: calc(100% + 2px);
left: 0;
right: 0;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
}
.autocomplete-items div:hover {
/*when hovering an item:*/
background-color: rgba(0, 0, 0, 0.1);
}
.autocomplete-items .autocomplete-active {
/*when navigating through the items using the arrow keys:*/
background-color: rgba(0, 0, 0, 0.1);
}
.clear-button {
color: rgba(0, 0, 0, 0.4);
cursor: pointer;
position: absolute;
right: 5px;
top: 0;
height: 100%;
display: none;
align-items: center;
}
.clear-button.visible {
display: flex;
}
.clear-button:hover {
color: rgba(0, 0, 0, 0.6);
}
JavaScript
function addressAutocomplete(containerElement, callback, options) {
const MIN_ADDRESS_LENGTH = 3;
const DEBOUNCE_DELAY = 300;
// create container for input element
const inputContainerElement = document.createElement("div");
inputContainerElement.setAttribute("class", "input-container");
containerElement.appendChild(inputContainerElement);
// create input element
const inputElement = document.createElement("input");
inputElement.setAttribute("type", "text");
inputElement.setAttribute("placeholder", options.placeholder);
inputContainerElement.appendChild(inputElement);
// add input field clear button
const clearButton = document.createElement("div");
clearButton.classList.add("clear-button");
addIcon(clearButton);
clearButton.addEventListener("click", (e) => {
e.stopPropagation();
inputElement.value = '';
callback(null);
clearButton.classList.remove("visible");
closeDropDownList();
});
inputContainerElement.appendChild(clearButton);
/* We will call the API with a timeout to prevent unneccessary API activity.*/
let currentTimeout;
/* Save the current request promise reject function. To be able to cancel the promise when a new request comes */
let currentPromiseReject;
/* Focused item in the autocomplete list. This variable is used to navigate with buttons */
let focusedItemIndex;
/* Process a user input: */
inputElement.addEventListener("input", function(e) {
const currentValue = this.value;
/* Close any already open dropdown list */
closeDropDownList();
// Cancel previous timeout
if (currentTimeout) {
clearTimeout(currentTimeout);
}
// Cancel previous request promise
if (currentPromiseReject) {
currentPromiseReject({
canceled: true
});
}
if (!currentValue) {
clearButton.classList.remove("visible");
}
// Show clearButton when there is a text
clearButton.classList.add("visible");
// Skip empty...