From 45c89b984d3f2b3bf97c8c5ee52e62aa6a4af6dc Mon Sep 17 00:00:00 2001 From: Mitja Felicijan Date: Fri, 22 Jul 2022 23:27:00 +0200 Subject: Added front end search --- template/script.js | 145 ++++++++++++++++++++++++++++------------------------- 1 file changed, 77 insertions(+), 68 deletions(-) (limited to 'template/script.js') diff --git a/template/script.js b/template/script.js index 0e1291c..3c58403 100755 --- a/template/script.js +++ b/template/script.js @@ -25,79 +25,88 @@ window.addEventListener('load', async () => { }); } - // comments code - const commentsEndpoint = 'https://mitjafelicijan.com/comments-api'; - const commentsPlaceholder = document.querySelector('.comments'); - - if (commentsPlaceholder) { - const guid = commentsPlaceholder.dataset.guid; - const name = commentsPlaceholder.querySelector('input'); - const comment = commentsPlaceholder.querySelector('textarea'); - const submit = commentsPlaceholder.querySelector('button'); - const comments = commentsPlaceholder.querySelector('ul'); - - if (guid) { - await readAndRenderComments(guid, comments); - - submit.addEventListener('click', async() => { - submit.disabled = true; - await writeComments(guid, name.value, comment.value); - - submit.disabled = false; - name.value = ''; - comment.value = ''; - - await readAndRenderComments(guid, comments); - }); - } + // Search functionality + + window.index = null; + + const response = await fetch('/feed.json'); + const feed = await response.json(); + + window.index = elasticlunr(function () { + this.addField('title'); + this.addField('body'); + this.setRef('id'); + }); + + for (const item of feed.items) { + item.id = item.url; + window.index.addDoc({ + id: item.url, + title: item.title, + body: item.content_html, + url: item.url, + }); } - async function writeComments(guid, name, comment) { - const response = await fetch(commentsEndpoint, { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - action: 'write', - guid, - name, - comment, - }) - }); + const blur = document.querySelector('.blur'); + const searchForm = document.querySelector('.search-form'); + const searchResultsList = document.querySelector('.search-form ul'); + + function showSearchModal() { + blur.classList.remove('hidden'); + searchForm.classList.remove('hidden'); + + // Clear search input. + searchForm.querySelector('input').value = ''; + + // We need to clear the list before opening modal. + searchResultsList.innerHTML = ''; + + // Focus on search input. + searchForm.querySelector('input').focus(); } - async function readAndRenderComments(guid, commentsPlaceholder) { - const response = await fetch(commentsEndpoint, { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - action: 'read', - guid, - }) - }); + document.querySelector('.search-trigger').addEventListener('click', async (evt) => { + showSearchModal(); + }); + + document.onkeydown = function (e) { + // Show search modal on F key. + if (blur.classList.contains('hidden')) { + if (e.key === 'f') { + setTimeout(() => { + showSearchModal(); + }, 100); + } + } - // remove all existing comments from list - commentsPlaceholder.innerHTML = ''; - - const commentList = await response.json(); - for (const comment of commentList.reverse()) { - const date = new Date(comment.date).toLocaleDateString('en-US', { - year: 'numeric', - month: 'long', - day: 'numeric', - hour: 'numeric', - minute: 'numeric' - }); - - const commentElement = document.createElement('li'); - commentElement.innerHTML = `

${comment.name} - ${date}

${comment.comment}


`; - commentsPlaceholder.appendChild(commentElement); + // Hide search modal on escape key. + if (!blur.classList.contains('hidden')) { + if (e.key === 'Escape') { + blur.classList.add('hidden'); + searchForm.classList.add('hidden'); + } } - } + }; + + blur.addEventListener('click', async (evt) => { + evt.target.classList.add('hidden'); + searchForm.classList.add('hidden'); + }); + + document.querySelector('.search-form input').addEventListener('keyup', async (evt) => { + // Perform search. + const searchResults = window.index.search(evt.target.value); + + // We need to clear the list before adding new results. + searchResultsList.innerHTML = ''; + + // Loop through the results and add them to the list. + for (const result of searchResults.slice(0, 9)) { + const listItem = document.createElement('li'); + listItem.innerHTML = `${result.doc.title}`; + searchResultsList.appendChild(listItem); + } + }); }); -- cgit v1.2.3