new-codigoparallevar/static/search-box.js
2022-10-17 00:10:06 +02:00

103 lines
3.4 KiB
JavaScript

function _codigoparallevar_enable_search_box(selector, options) {
const element = document.querySelector(selector);
if ('placeholder' in options) {
element.setAttribute('placeholder', options.placeholder);
}
// Prepare backdrop
const resultsBoxBackdrop = document.createElement('div');
resultsBoxBackdrop.setAttribute('class', 'results-box-container hidden');
const resultsBox = document.createElement('div');
resultsBox.setAttribute('class', 'results-box');
// Results box contents
const innerSearchBox = document.createElement('input');
innerSearchBox.setAttribute('type', 'text');
innerSearchBox.setAttribute('placeholder', element.getAttribute('placeholder'));
resultsBox.appendChild(innerSearchBox);
const resultsList = document.createElement('ul');
resultsBox.appendChild(resultsList);
resultsBoxBackdrop.appendChild(resultsBox);
document.body.appendChild(resultsBoxBackdrop);
// Popup cancellation
resultsBoxBackdrop.onclick = () => {
resultsBoxBackdrop.classList.add('hidden');
};
resultsBox.onclick = (ev) => {
ev.stopPropagation();
};
// Element triggers popup
element.onfocus = () => {
resultsBoxBackdrop.classList.remove('hidden');
innerSearchBox.focus();
const wasKeyDown = document.onkeydown;
document.onkeydown = (ev) => {
if (ev.key === 'Escape') {
resultsBoxBackdrop.classList.add('hidden');
document.onkeydown = wasKeyDown;
ev.stopPropagation();
}
};
};
const DEBOUNCE_TIME = 500; // Milliseconds
const MIN_LENGTH = 3;
const SEARCH_ENDPOINT = 'http://localhost:3001/api/search';
let debounceWaiter = null;
let currentQuery = null;
let lastVal = null;
const doQuery = () => {
const val = innerSearchBox.value.trim();
if ((val.length < MIN_LENGTH) || (val === lastVal)) {
return;
}
lastVal = val;
const uri = SEARCH_ENDPOINT + '?q=' + encodeURIComponent(val);
let query = fetch(uri);
currentQuery = query;
query
.then(res => res.json())
.then((body) => {
if (query !== currentQuery) {
console.log("Query out-raced 🤷");
return;
}
resultsList.innerHTML = '';
for (const note of body.results.notes) {
const resultCard = document.createElement('li');
const resultContents = document.createElement('a');
resultContents.setAttribute('href', './' + note.id + '.node.html');
const resultTitle = document.createElement('h2');
resultTitle.innerText = note.title;
resultContents.appendChild(resultTitle);
resultCard.appendChild(resultContents);
resultsList.appendChild(resultCard);
}
});
};
element.removeAttribute('disabled');
innerSearchBox.onkeyup = (ev) => {
if (debounceWaiter !== null) {
clearTimeout(debounceWaiter);
}
debounceWaiter = setTimeout(doQuery, DEBOUNCE_TIME);
};
}
// // TODO: Remove this when dev is done
// _codigoparallevar_enable_search_box('#searchbox', {placeholder: 'Search...'})
// document.querySelector('#searchbox').focus()