Skip to content

Instantly share code, notes, and snippets.

@moshiurse
Created March 20, 2023 08:09
Show Gist options
  • Save moshiurse/163f1b27f959e6a8c41e45ae43d54e87 to your computer and use it in GitHub Desktop.
Save moshiurse/163f1b27f959e6a8c41e45ae43d54e87 to your computer and use it in GitHub Desktop.
Raw JS Autocomplete
<input type="text" id="autocomplete-input">
<ul id="autocomplete-list"></ul>
<div class="userinfo">
Latitude: <span id="id"></span><br>
Longitude: <span id="name"></span><br>
</div>
const input = document.getElementById('autocomplete-input');
const list = document.getElementById('autocomplete-list');
let activeItem = null;
let timeoutId;
input.addEventListener('input', () => {
if(timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
const value = input.value;
getLocationInput(value);
}, 250);
});
function getLocationInput(location) {
//Clear the previous list items
list.innerHTML = '';
var url = "https://nominatim.openstreetmap.org/search/" + encodeURIComponent(location) + "?format=json&addressdetails=1";
fetch(url)
.then(function(response) {
return response.json();
})
.then(function(data) {
list.innerHTML = '';
data.forEach((element, index) => {
const li = document.createElement('li');
li.textContent = element.display_name;
li.dataset.lat = element.lat;
li.dataset.lon = element.lon;
li.classList.add('autocomplete-item');
// fist one set as active
// if (index === 0) {
// li.classList.add('active');
// activeItem = li;
// }
// APPEND TO LIST
list.appendChild(li);
});
})
.catch(function(error) {
console.log("Error: " + error);
list.innerHTML = '';
});
}
function getCurrentActiveData(elem) {
input.value = elem.textContent;
let latDms = decimalToDegreeMinSec(elem.dataset.lat, false);
let lngDms = decimalToDegreeMinSec(elem.dataset.lon);
$('#id').html(latDms);
$('#name').html(lngDms);
}
input.addEventListener('keydown', (event) => {
if (event.keyCode === 38) { // Up arrow
if (activeItem) {
const previousItem = activeItem.previousElementSibling;
if (previousItem) {
activeItem.classList.remove('active');
previousItem.classList.add('active');
activeItem = previousItem;
// Scroll Manage
if (activeItem.offsetTop < list.scrollTop) {
list.scrollTop = activeItem.offsetTop;
}
}
} else {
activeItem = list.lastElementChild;
activeItem.classList.add('active');
list.scrollTop = list.scrollHeight;
}
} else if (event.keyCode === 40) { // Down arrow
if (activeItem) {
const nextItem = activeItem.nextElementSibling;
console.log(nextItem, activeItem);
if (nextItem) {
activeItem.classList.remove('active');
nextItem.classList.add('active');
activeItem = nextItem;
if (activeItem.offsetTop + activeItem.offsetHeight > list.scrollTop + list.offsetHeight) {
list.scrollTop = activeItem.offsetTop + activeItem.offsetHeight - list.offsetHeight;
}
}
} else {
activeItem = list.firstElementChild;
activeItem.classList.add('active');
list.scrollTop = 0;
}
}else if (event.keyCode === 13) { // Enter key
if (activeItem) {
input.value = activeItem.textContent;
list.innerHTML = '';
}
}
getCurrentActiveData(activeItem);
});
document.addEventListener('click', (event) => {
const isClickInside = input.contains(event.target) || list.contains(event.target);
if (!isClickInside) {
// getCurrentActiveData(activeItem);
list.innerHTML = '';
}
});
list.addEventListener('click', (event) => {
input.value = event.target.textContent;
getCurrentActiveData(event.target);
list.innerHTML = '';
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment