Updated search suggestion behavior (closes #115)
Arrow key navigation through search suggestions now populates the input field with text content from the active selection. Navigating "down" past the end of the suggestions list returns the active cursor to position 0, while navigating "up" before the list of suggestions restores the original search query and removes the active highlight from element 0.main
parent
f4eca3711b
commit
b2ecd8dc78
|
@ -2,7 +2,7 @@ const handleUserInput = searchBar => {
|
||||||
let xhrRequest = new XMLHttpRequest();
|
let xhrRequest = new XMLHttpRequest();
|
||||||
xhrRequest.open("POST", "/autocomplete");
|
xhrRequest.open("POST", "/autocomplete");
|
||||||
xhrRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
xhrRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||||
xhrRequest.onload = function() {
|
xhrRequest.onload = function () {
|
||||||
if (xhrRequest.readyState === 4 && xhrRequest.status !== 200) {
|
if (xhrRequest.readyState === 4 && xhrRequest.status !== 200) {
|
||||||
// Do nothing if failed to fetch autocomplete results
|
// Do nothing if failed to fetch autocomplete results
|
||||||
return;
|
return;
|
||||||
|
@ -18,6 +18,7 @@ const handleUserInput = searchBar => {
|
||||||
|
|
||||||
const autocomplete = (searchInput, autocompleteResults) => {
|
const autocomplete = (searchInput, autocompleteResults) => {
|
||||||
let currentFocus;
|
let currentFocus;
|
||||||
|
let originalSearch;
|
||||||
|
|
||||||
searchInput.addEventListener("input", function () {
|
searchInput.addEventListener("input", function () {
|
||||||
let autocompleteList, autocompleteItem, i, val = this.value;
|
let autocompleteList, autocompleteItem, i, val = this.value;
|
||||||
|
@ -53,9 +54,11 @@ const autocomplete = (searchInput, autocompleteResults) => {
|
||||||
let suggestion = document.getElementById(this.id + "-autocomplete-list");
|
let suggestion = document.getElementById(this.id + "-autocomplete-list");
|
||||||
if (suggestion) suggestion = suggestion.getElementsByTagName("div");
|
if (suggestion) suggestion = suggestion.getElementsByTagName("div");
|
||||||
if (e.keyCode === 40) { // down
|
if (e.keyCode === 40) { // down
|
||||||
|
e.preventDefault();
|
||||||
currentFocus++;
|
currentFocus++;
|
||||||
addActive(suggestion);
|
addActive(suggestion);
|
||||||
} else if (e.keyCode === 38) { //up
|
} else if (e.keyCode === 38) { //up
|
||||||
|
e.preventDefault();
|
||||||
currentFocus--;
|
currentFocus--;
|
||||||
addActive(suggestion);
|
addActive(suggestion);
|
||||||
} else if (e.keyCode === 13) { // enter
|
} else if (e.keyCode === 13) { // enter
|
||||||
|
@ -63,17 +66,36 @@ const autocomplete = (searchInput, autocompleteResults) => {
|
||||||
if (currentFocus > -1) {
|
if (currentFocus > -1) {
|
||||||
if (suggestion) suggestion[currentFocus].click();
|
if (suggestion) suggestion[currentFocus].click();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
originalSearch = document.getElementById("search-bar").value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const addActive = suggestion => {
|
const addActive = suggestion => {
|
||||||
if (!suggestion || !suggestion[currentFocus]) return false;
|
let searchBar = document.getElementById("search-bar");
|
||||||
|
|
||||||
|
// Handle navigation outside of suggestion list
|
||||||
|
if (!suggestion || !suggestion[currentFocus]) {
|
||||||
|
if (currentFocus >= suggestion.length) {
|
||||||
|
// Move selection back to the beginning
|
||||||
|
currentFocus = 0;
|
||||||
|
} else if (currentFocus < 0) {
|
||||||
|
// Retrieve original search and remove active suggestion selection
|
||||||
|
currentFocus = -1;
|
||||||
|
searchBar.value = originalSearch;
|
||||||
removeActive(suggestion);
|
removeActive(suggestion);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (currentFocus >= suggestion.length) currentFocus = 0;
|
removeActive(suggestion);
|
||||||
if (currentFocus < 0) currentFocus = (suggestion.length - 1);
|
|
||||||
|
|
||||||
suggestion[currentFocus].classList.add("autocomplete-active");
|
suggestion[currentFocus].classList.add("autocomplete-active");
|
||||||
|
|
||||||
|
// Autofill search bar with suggestion content
|
||||||
|
searchBar.value = suggestion[currentFocus].textContent;
|
||||||
|
searchBar.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeActive = suggestion => {
|
const removeActive = suggestion => {
|
||||||
|
|
Loading…
Reference in New Issue