fixed and cleaned autocomplete.js
This commit is contained in:
parent
60b4040895
commit
088f80746a
1 changed files with 44 additions and 171 deletions
|
@ -37,7 +37,7 @@ if (resultsSave != null) {
|
||||||
const searchInput = document.getElementById('search-input');
|
const searchInput = document.getElementById('search-input');
|
||||||
const searchWrapper = document.querySelectorAll('.wrapper, .wrapper-results')[0];
|
const searchWrapper = document.querySelectorAll('.wrapper, .wrapper-results')[0];
|
||||||
const resultsWrapper = document.querySelector('.autocomplete');
|
const resultsWrapper = document.querySelector('.autocomplete');
|
||||||
const clearSearch = document.querySelector("#clearSearch");
|
// const clearSearch = document.querySelector("#clearSearch");
|
||||||
|
|
||||||
async function getSuggestions(query) {
|
async function getSuggestions(query) {
|
||||||
try {
|
try {
|
||||||
|
@ -70,15 +70,15 @@ searchInput.addEventListener("focus", async () => {
|
||||||
renderResults(results);
|
renderResults(results);
|
||||||
})
|
})
|
||||||
|
|
||||||
clearSearch.style.visibility = "visible"; // Only show the clear search button for JS users.
|
// clearSearch.style.visibility = "visible"; // Only show the clear search button for JS users.
|
||||||
clearSearch.addEventListener("click", () => {
|
// clearSearch.addEventListener("click", () => {
|
||||||
searchInput.value = "";
|
// searchInput.value = "";
|
||||||
searchInput.focus();
|
// searchInput.focus();
|
||||||
})
|
// })
|
||||||
|
|
||||||
searchInput.addEventListener('keydown', (event) => {
|
searchInput.addEventListener('keydown', (event) => {
|
||||||
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
|
if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'Tab') {
|
||||||
event.preventDefault(); // Prevent the cursor from moving in the search input
|
event.preventDefault(); // Prevent the default behavior, such as moving the cursor
|
||||||
|
|
||||||
// Find the currently selected suggestion element
|
// Find the currently selected suggestion element
|
||||||
const selectedSuggestion = resultsWrapper.querySelector('.selected');
|
const selectedSuggestion = resultsWrapper.querySelector('.selected');
|
||||||
|
@ -86,7 +86,7 @@ searchInput.addEventListener('keydown', (event) => {
|
||||||
selectedSuggestion.classList.remove('selected'); // Deselect the currently selected suggestion
|
selectedSuggestion.classList.remove('selected'); // Deselect the currently selected suggestion
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment or decrement the current index based on the arrow key pressed
|
// Increment current index when ArrowUp is pressed otherwise hen Tab OR ArrowDown decrement
|
||||||
if (event.key === 'ArrowUp') {
|
if (event.key === 'ArrowUp') {
|
||||||
currentIndex--;
|
currentIndex--;
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,9 +107,14 @@ searchInput.addEventListener('keydown', (event) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Default to the currently selected type or fallback to 'text'
|
||||||
|
let selectedType = document.querySelector('.search-active')?.value || 'text';
|
||||||
|
|
||||||
|
// Function to render results
|
||||||
function renderResults(results) {
|
function renderResults(results) {
|
||||||
if (!results || !results.length || !searchInput.value) {
|
if (!results || !results.length || !searchInput.value) {
|
||||||
return searchWrapper.classList.remove('show');
|
searchWrapper.classList.remove('show');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let content = '';
|
let content = '';
|
||||||
|
@ -117,26 +122,38 @@ function renderResults(results) {
|
||||||
content += `<li>${item}</li>`;
|
content += `<li>${item}</li>`;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only show the autocomplete suggestions if the search input has a non-empty value
|
|
||||||
if (searchInput.value) {
|
if (searchInput.value) {
|
||||||
searchWrapper.classList.add('show');
|
searchWrapper.classList.add('show');
|
||||||
}
|
}
|
||||||
resultsWrapper.innerHTML = `<ul>${content}</ul>`;
|
resultsWrapper.innerHTML = `<ul>${content}</ul>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
resultsWrapper.addEventListener('click', (event) => {
|
// Function to handle search input
|
||||||
if (event.target.tagName === 'LI') {
|
searchInput.addEventListener('input', async () => {
|
||||||
// Set the value of the search input to the clicked suggestion
|
let input = searchInput.value;
|
||||||
searchInput.value = event.target.textContent;
|
if (input.length) {
|
||||||
// Reset the current index
|
const results = await getSuggestions(input);
|
||||||
currentIndex = -1;
|
renderResults(results);
|
||||||
// Submit the form
|
|
||||||
searchWrapper.querySelector('input[type="submit"]').click();
|
|
||||||
// Remove the show class from the search wrapper
|
|
||||||
searchWrapper.classList.remove('show');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Handle click events on the type buttons
|
||||||
|
const typeButtons = document.querySelectorAll('[name="t"]');
|
||||||
|
typeButtons.forEach(button => {
|
||||||
|
button.addEventListener('click', function() {
|
||||||
|
selectedType = this.value;
|
||||||
|
typeButtons.forEach(btn => btn.classList.remove('search-active'));
|
||||||
|
this.classList.add('search-active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle clicks on search results
|
||||||
|
resultsWrapper.addEventListener('click', (event) => {
|
||||||
|
if (event.target.tagName === 'LI') {
|
||||||
|
const query = event.target.textContent;
|
||||||
|
window.location.href = `/search?q=${encodeURIComponent(query)}&t=${encodeURIComponent(selectedType)}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener("keypress", (event) => {
|
document.addEventListener("keypress", (event) => {
|
||||||
if (document.activeElement == searchInput) {
|
if (document.activeElement == searchInput) {
|
||||||
|
@ -161,155 +178,11 @@ document.addEventListener('click', (event) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load material icons. If the file cannot be loaded,
|
// Update visual feedback for selected type on page load
|
||||||
// skip them and put a warning in the console.
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const font = new FontFace('Material Icons Round', 'url("/fonts/material-icons-round-v108-latin-regular.woff2") format("woff2")');
|
const activeButton = document.querySelector(`[name="t"][value="${selectedType}"]`);
|
||||||
font.load().then(() => {
|
if (activeButton) {
|
||||||
const icons = document.getElementsByClassName('material-icons-round');
|
typeButtons.forEach(btn => btn.classList.remove('search-active'));
|
||||||
|
activeButton.classList.add('search-active');
|
||||||
// Display all icons.
|
|
||||||
for (let icon of icons) {
|
|
||||||
icon.style.visibility = 'visible';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure icons for the different types of searches are sized correctly.
|
|
||||||
document.querySelectorAll('#sub-search-wrapper-ico').forEach((el) => {
|
|
||||||
el.style.fontSize = '17px';
|
|
||||||
});
|
|
||||||
}).catch(() => {
|
|
||||||
console.warn('Failed to load Material Icons Round. Hiding any icons using said pack.');
|
|
||||||
});
|
|
||||||
|
|
||||||
// load image after server side processing
|
|
||||||
window.addEventListener('DOMContentLoaded', function () {
|
|
||||||
var knoTitleElement = document.getElementById('kno_title');
|
|
||||||
var kno_title = knoTitleElement.dataset.knoTitle;
|
|
||||||
fetch(kno_title)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
const pageId = Object.keys(data.query.pages)[0];
|
|
||||||
const thumbnailSource = data.query.pages[pageId].thumbnail.source;
|
|
||||||
const url = "/img_proxy?url=" + thumbnailSource;
|
|
||||||
|
|
||||||
// update the img tag with url and add kno_wiki_show
|
|
||||||
var imgElement = document.querySelector('.kno_wiki');
|
|
||||||
imgElement.src = url;
|
|
||||||
imgElement.classList.add('kno_wiki_show');
|
|
||||||
|
|
||||||
console.log(url);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log('Error fetching data:', error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
|
|
||||||
if (document.querySelectorAll(".search-active")[1].getAttribute("value") === "image") {
|
|
||||||
|
|
||||||
// image viewer for image search
|
|
||||||
const closeButton = document.querySelector('.image-close');
|
|
||||||
const imageView = document.querySelector('.image_view');
|
|
||||||
const images = document.querySelector('.images');
|
|
||||||
const viewImageImg = document.querySelector('.view-image-img');
|
|
||||||
const imageSource = document.querySelector('.image-source');
|
|
||||||
const imageFull = document.querySelector(".full-size");
|
|
||||||
const imageProxy = document.querySelector('.proxy-size');
|
|
||||||
const imageViewerLink = document.querySelector('.image-viewer-link');
|
|
||||||
const imageSize = document.querySelector('.image-size');
|
|
||||||
const fullImageSize = document.querySelector(".full-image-size");
|
|
||||||
const imageAlt = document.querySelector('.image-alt');
|
|
||||||
const openImageViewer = document.querySelectorAll('.open-image-viewer');
|
|
||||||
const imageBefore = document.querySelector('.image-before');
|
|
||||||
const imageNext = document.querySelector('.image-next');
|
|
||||||
let currentImageIndex = 0;
|
|
||||||
|
|
||||||
closeButton.addEventListener('click', function () {
|
|
||||||
imageView.classList.remove('image_show');
|
|
||||||
imageView.classList.add('image_hide');
|
|
||||||
for (const image of document.querySelectorAll(".image_selected")) {
|
|
||||||
image.classList = ['image'];
|
|
||||||
}
|
|
||||||
images.classList.add('images_viewer_hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
openImageViewer.forEach((image, index) => {
|
|
||||||
image.addEventListener('click', function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
currentImageIndex = index;
|
|
||||||
showImage();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('keydown', function (event) {
|
|
||||||
if (searchInput == document.activeElement)
|
|
||||||
return;
|
|
||||||
if (event.key === 'ArrowLeft') {
|
|
||||||
currentImageIndex = (currentImageIndex - 1 + openImageViewer.length) % openImageViewer.length;
|
|
||||||
showImage();
|
|
||||||
}
|
|
||||||
else if (event.key === 'ArrowRight') {
|
|
||||||
currentImageIndex = (currentImageIndex + 1) % openImageViewer.length;
|
|
||||||
showImage();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
imageBefore.addEventListener('click', function () {
|
|
||||||
currentImageIndex = (currentImageIndex - 1 + openImageViewer.length) % openImageViewer.length;
|
|
||||||
showImage();
|
|
||||||
});
|
|
||||||
|
|
||||||
imageNext.addEventListener('click', function () {
|
|
||||||
currentImageIndex = (currentImageIndex + 1) % openImageViewer.length;
|
|
||||||
showImage();
|
|
||||||
});
|
|
||||||
|
|
||||||
function showImage() {
|
|
||||||
for (const image of document.querySelectorAll(".image_selected")) {
|
|
||||||
image.classList = ['image'];
|
|
||||||
}
|
|
||||||
const current_image = document.querySelectorAll(".image")[currentImageIndex];
|
|
||||||
current_image.classList.add("image_selected");
|
|
||||||
var rect = current_image.getBoundingClientRect();
|
|
||||||
if (!(rect.top >= 0 && rect.left >= 0 &&
|
|
||||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
|
||||||
rect.right <= (window.innerWidth || document.documentElement.clientWidth))) {
|
|
||||||
current_image.scrollIntoView(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
const src = openImageViewer[currentImageIndex].getAttribute('src');
|
|
||||||
const alt = openImageViewer[currentImageIndex].getAttribute('alt');
|
|
||||||
const data = openImageViewer[currentImageIndex].getAttribute('data');
|
|
||||||
const clickableLink = openImageViewer[currentImageIndex].closest('.clickable');
|
|
||||||
const href = clickableLink.getAttribute('href');
|
|
||||||
viewImageImg.src = src;
|
|
||||||
imageProxy.href = src;
|
|
||||||
imageFull.href = data;
|
|
||||||
imageSource.href = href;
|
|
||||||
imageSource.textContent = href;
|
|
||||||
imageViewerLink.href = href;
|
|
||||||
images.classList.remove('images_viewer_hidden');
|
|
||||||
imageView.classList.remove('image_hide');
|
|
||||||
imageView.classList.add('image_show');
|
|
||||||
imageAlt.textContent = alt;
|
|
||||||
fullImageSize.textContent = document.querySelector(".image_selected .resolution").textContent;
|
|
||||||
|
|
||||||
getImageSize(src).then(size => {
|
|
||||||
imageSize.textContent = size;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getImageSize(url) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const img = new Image();
|
|
||||||
img.onload = function () {
|
|
||||||
const size = `${this.width} x ${this.height}`;
|
|
||||||
resolve(size);
|
|
||||||
};
|
|
||||||
img.onerror = function () {
|
|
||||||
reject('Error loading image');
|
|
||||||
};
|
|
||||||
img.src = url;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue