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); const noResultsBox = document.createElement('div'); noResultsBox.setAttribute('class', 'no-results-box hidden'); noResultsBox.innerText = 'No results 🤷'; resultsBox.appendChild(noResultsBox); 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 = 250; // Milliseconds const MIN_LENGTH = 3; const SEARCH_ENDPOINT = (window.location.host.startsWith('localhost') ? 'http://localhost:3001/api/search' : 'https://api.codigoparallevar.com/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) { if (note.is_todo === "1") { return; } 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} (${note.top_level_title})`; resultContents.appendChild(resultTitle); resultCard.appendChild(resultContents); resultsList.appendChild(resultCard); } if (body.results.notes.length == 0) { noResultsBox.classList.remove('hidden'); } else { noResultsBox.classList.add('hidden'); } }); }; 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()