I really do like the autocomplete function, but is it possible to change it so it’s blank when I press inside of the textbox, and only displays countries when I start type something in? I’m not sure how I should do this so I would appreciate if someone could tell/show me where to fix that.
When I start typing something, like "Alb", and then remove this and click outside of the textbox, then click inside of it again the previous results is still there
Code Snippet
// Sample list of autocomplete options
var countries = [
"Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Australia", "Austria", "Azerbaijan",
"The Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bhutan", "Bolivia",
"Bosnia and Herzegovina", "Botswana", "Brazil", "Brunei", "Bulgaria", "Burkina Faso", "Burundi"
];
// Get references to the input field and the dropdown list
var input = document.getElementById("country-name");
var autocompleteList = document.getElementById("suggestion-list");
// Function to display the dropdown list
function showAutocompleteList() {
autocompleteList.style.display = 'block';
}
// Function to hide the dropdown list
function hideAutocompleteList() {
autocompleteList.style.display = 'none';
}
// Event listener for input field
input.addEventListener("input", function() {
var inputValue = input.value;
autocompleteList.innerHTML = '';
// Filter and display matching items
countries.forEach(function(country) {
if (country.toLowerCase().startsWith(inputValue.toLowerCase())) {
var item = document.createElement("li");
item.textContent = country;
item.classList.add("autocomplete-item"); // Add the "autocomplete-item" class
item.addEventListener("click", function() {
input.value = country;
autocompleteList.innerHTML = '';
});
item.addEventListener("mouseenter", function() {
item.classList.add("active"); // Add the "active" class on hover
});
item.addEventListener("mouseleave", function() {
item.classList.remove("active"); // Remove the "active" class when not hovering
});
autocompleteList.appendChild(item);
}
});
showAutocompleteList(); // Display the list when input changes
});
// Event listener for "keydown" on the input field
input.addEventListener("keydown", function(e) {
if (e.key === "Tab") {
e.preventDefault(); // Prevent the default tab behavior
// Handle the Tab key behavior for selecting an item
var activeItem = autocompleteList.querySelector(".autocomplete-item.active");
if (activeItem) {
input.value = activeItem.textContent;
autocompleteList.innerHTML = '';
// Redirect to the corresponding HTML page
var countryUrl = 'Countries/' + activeItem.textContent.toLowerCase() + '.html';
window.location.href = countryUrl;
}
}
});
// Event listener for clicking on the list items
autocompleteList.addEventListener("click", function(e) {
if (e.target.classList.contains("autocomplete-item")) {
// If the clicked element has the "autocomplete-item" class
input.value = e.target.textContent;
// Redirect to the corresponding HTML page
var countryUrl = 'Countries/' + e.target.textContent.toLowerCase() + '.html';
window.location.href = countryUrl;
e.preventDefault(); // Prevent the default click behavior
}
});
// Event listener to close the dropdown when clicking outside of the input field
document.addEventListener("click", function(e) {
if (e.target !== autocompleteList && e.target !== input) {
hideAutocompleteList();
}
});
// Event listener for clicking inside the input field to display the dropdown
input.addEventListener("click", showAutocompleteList);
<header>
<h1>Select a country</h1>
</header>
<main>
<div id="content-wrapper">
<div id="get-container">
<input type="text" id="country-name" placeholder="Enter a country" autocomplete="off">
<div id="suggestion-list" class="autocomplete-items"></div>
<div id="error-message"></div>
</div>
<div id="story-container">
<div id="generated-text"></div>
<button id="clear">Clear</button>
</div>
</div>
</main>
2
Answers
Added the
focus
event listener to clear the list when input field is clicked.Updated the
showAutocompleteList()
function to only display the list if the input value is not empty.Updated the input’s
input
event listener to only filter and display the list if the input has at least one character.Modified the input’s
keydown
event listener to check for the length of the input value before displaying the list.Changes from original code:
<div>
for item since it is invalid to append<li>
to a divvalue
– the value on anli
can only be a integer and only onli
in anol
ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li.filter()
for the match to array valuesconst
notvar
on cached valuesCountry/
and put it as a data attribute on the container and not in codepopulateList()
for an updated code for thatfocus
event for the input to show the listmouseenter
andmouseleave
on the list items. Added a border to the actual list just to show what was where (non of this is part of the question answer but illustrates visually what is going on.Suggestion: rather than removing and adding to the DOM for the list, consider generating them all then showing/hiding using the function I created
showElement(element, shouldHide)
instead, called within the filter portion of the code