I have adapted some autocomplete code to make the products in a dropdown direct the user to a the corresponding product page on click.
If someone types in part of the search query and presses enter it will bring up a search results page, with all results matching 'prod' for example.
I want someone to also go to the corresponding product page if they use the keyboard to cycle through the products and press enter. There is code to handle this, but it is throwing an error and I can't work out why:
Uncaught TypeError: Cannot read properties of undefined (reading 'value')
at HTMLDivElement. (search-results?search=am:1063:65)
at HTMLInputElement. (search-results?search=am:1098:36)
function autocomplete(inp, arr) {
var currentFocus;
inp.addEventListener("input", function(e) {
var a, b, i, val = this.value;
closeAllLists();
if (!val) {
return false;
}
currentFocus = -1;
a = document.createElement("DIV");
a.setAttribute("id", this.id + "autocomplete-list");
a.setAttribute("class", "autocomplete-items");
this.parentNode.appendChild(a);
for (i = 0; i < arr.length; i++) {
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);
if (arr[i].charAt(0) === '-') {
string = arr[i].substring(1);
string2 = string.replace(/[_\W]+/g, "-").toLowerCase();
} else {
string2 = arr[i].replace(/[_\W]+/g, "-").toLowerCase();
}
b.innerHTML += "<a href='/product/" + string2 + "'></a>";
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) { // arrow down
currentFocus++;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 38) { // up
currentFocus--;
addActive(x);
} else if (e.keyCode == 13) { // return
e.preventDefault();
if (x)
x[currentFocus].click();
console.log(x[currentFocus]);
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 products = ["Product name 1", "Product name 2", "Product name 3", "Product name 4", "Product name 5"];
autocomplete(document.getElementById("SearchProductsNav"), products);
On enter key press console.log gives the correct active div I am trying to simulate a click on, but it doesn't actually click through
console.log(x[currentFocus]);