2024-10-22 10:46:47 +02:00
|
|
|
/*
|
|
|
|
This script is responsible for fetching search suggestions when the user types in the search bar. It also shows and hides the search suggestions wrapper.
|
|
|
|
*/
|
2024-10-21 07:30:48 +02:00
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
|
|
const searchInput = document.getElementById('search-input');
|
2024-10-22 08:38:50 +02:00
|
|
|
const searchWrapper = document.querySelector('.wrapper, .wrapper-results');
|
2024-10-21 07:30:48 +02:00
|
|
|
const resultsWrapper = document.querySelector('.autocomplete');
|
|
|
|
|
|
|
|
let suggestions = [];
|
|
|
|
let currentIndex = -1; // Keep track of the currently selected suggestion
|
|
|
|
|
|
|
|
// Fetch suggestions from the server
|
|
|
|
async function getSuggestions(query) {
|
|
|
|
try {
|
|
|
|
const response = await fetch(`/suggestions?q=${encodeURIComponent(query)}`);
|
|
|
|
const data = await response.json();
|
|
|
|
return data[1]; // Return only the array of suggestion strings
|
|
|
|
} catch (error) {
|
|
|
|
console.error('Error fetching suggestions:', error);
|
|
|
|
return [];
|
|
|
|
}
|
2024-08-21 22:36:45 +02:00
|
|
|
}
|
|
|
|
|
2024-10-21 07:30:48 +02:00
|
|
|
// Function to render results
|
|
|
|
function renderSuggestions(results) {
|
|
|
|
if (!results || !results.length) {
|
2024-10-21 13:52:56 +02:00
|
|
|
searchWrapper.classList.remove('wrapper-searching');
|
2024-10-21 07:30:48 +02:00
|
|
|
resultsWrapper.innerHTML = '';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let content = '';
|
|
|
|
results.forEach((item, index) => {
|
|
|
|
content += `<li data-index="${index}">${item}</li>`;
|
|
|
|
});
|
|
|
|
|
|
|
|
resultsWrapper.innerHTML = `<ul>${content}</ul>`;
|
2024-10-21 13:52:56 +02:00
|
|
|
searchWrapper.classList.add('wrapper-searching');
|
2024-08-21 22:36:45 +02:00
|
|
|
}
|
|
|
|
|
2024-10-21 07:30:48 +02:00
|
|
|
// Fetch suggestions when input is focused
|
|
|
|
searchInput.addEventListener('focus', async () => {
|
|
|
|
const query = searchInput.value.trim();
|
|
|
|
suggestions = await getSuggestions(query);
|
|
|
|
renderSuggestions(suggestions);
|
|
|
|
currentIndex = -1;
|
|
|
|
});
|
|
|
|
|
|
|
|
// Handle input event
|
|
|
|
searchInput.addEventListener('input', async () => {
|
|
|
|
const query = searchInput.value.trim();
|
|
|
|
if (query.length > 0) {
|
|
|
|
suggestions = await getSuggestions(query);
|
|
|
|
} else {
|
|
|
|
suggestions = [];
|
|
|
|
}
|
|
|
|
currentIndex = -1; // Reset index when new results come in
|
|
|
|
renderSuggestions(suggestions);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Handle keydown events for navigation
|
|
|
|
searchInput.addEventListener('keydown', (event) => {
|
|
|
|
const items = resultsWrapper.querySelectorAll('li');
|
|
|
|
if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'Tab') {
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
// Remove 'selected' class from the current item
|
|
|
|
if (items[currentIndex]) {
|
|
|
|
items[currentIndex].classList.remove('selected');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.key === 'ArrowUp') {
|
|
|
|
currentIndex = (currentIndex > 0) ? currentIndex - 1 : items.length - 1;
|
|
|
|
} else {
|
|
|
|
currentIndex = (currentIndex + 1) % items.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add 'selected' class to the new item and update the input value
|
|
|
|
if (items[currentIndex]) {
|
|
|
|
items[currentIndex].classList.add('selected');
|
|
|
|
searchInput.value = items[currentIndex].textContent;
|
|
|
|
}
|
|
|
|
} else if (event.key === 'Enter') {
|
|
|
|
if (currentIndex > -1 && items[currentIndex]) {
|
|
|
|
event.preventDefault();
|
|
|
|
selectSuggestion(items[currentIndex]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Function to handle suggestion selection
|
|
|
|
function selectSuggestion(item) {
|
|
|
|
const query = item.textContent;
|
|
|
|
searchInput.value = query;
|
|
|
|
resultsWrapper.innerHTML = '';
|
2024-10-21 13:52:56 +02:00
|
|
|
searchWrapper.classList.remove('wrapper-searching');
|
2024-10-21 07:30:48 +02:00
|
|
|
|
|
|
|
// Submit the form or navigate to search results
|
|
|
|
const form = searchInput.closest('form');
|
|
|
|
if (form) {
|
|
|
|
form.submit();
|
|
|
|
} else {
|
|
|
|
window.location.href = `/search?q=${encodeURIComponent(query)}&t=web`;
|
|
|
|
}
|
2024-08-21 22:36:45 +02:00
|
|
|
}
|
|
|
|
|
2024-10-21 07:30:48 +02:00
|
|
|
// Handle clicks on search suggestions
|
|
|
|
resultsWrapper.addEventListener('click', (event) => {
|
|
|
|
if (event.target.tagName === 'LI') {
|
|
|
|
selectSuggestion(event.target);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Close the suggestions when clicking outside
|
|
|
|
document.addEventListener('click', (event) => {
|
|
|
|
if (!searchWrapper.contains(event.target)) {
|
2024-10-21 13:52:56 +02:00
|
|
|
searchWrapper.classList.remove('wrapper-searching');
|
2024-10-21 07:30:48 +02:00
|
|
|
resultsWrapper.innerHTML = '';
|
|
|
|
currentIndex = -1;
|
|
|
|
}
|
|
|
|
});
|
2024-08-21 22:36:45 +02:00
|
|
|
});
|