diff --git a/functions.js b/functions.js index 00790128568858c07e4ba539dc88d2be215a2878..5b84a867af3636f7833eeb6a7d5b531533e98ed2 100644 --- a/functions.js +++ b/functions.js @@ -24,14 +24,14 @@ function handleSearchChanged() { } async function onInputChanged(event) { - let searchWord = event.target.value; + const searchWord = event.target.value; - let json = await fetchNews(searchWord); + const json = await fetchNews(searchWord); if (json === undefined) return; - displaySearchResults(json); + displaySearchResults(json, searchWord); } function fetchNews(searchWord) { @@ -48,7 +48,7 @@ function fetchNews(searchWord) { return request; } -function displaySearchResults(json) { +function displaySearchResults(json, searchWord) { const searchResults = document.getElementById('search-results'); searchResults.innerText = ""; @@ -56,28 +56,26 @@ function displaySearchResults(json) { const ul = document.createElement('ul'); json.forEach((news) => { - const li = createNewsChild(news); + const li = createNewsChild(news, searchWord); ul.appendChild(li); }); - console.log(ul); - searchResults.appendChild(ul); const display = json.length === 0 ? "none" : "block";; searchResults.style.display = display; } -function createNewsChild(news) { +function createNewsChild(news, searchWord) { + const title = news['title']; + const id = news['id']; + const li = document.createElement('li'); - const a = document.createElement('a'); - - const textNode = document.createTextNode(news['title']); - a.appendChild(textNode); + const a = createLinkWithHighlightedParts(title, searchWord) const hrefAttr = document.createAttribute('href'); - hrefAttr.value = 'NewsArticle.php?articleId=' + encodeURIComponent(news['id']); + hrefAttr.value = 'NewsArticle.php?articleId=' + encodeURIComponent(id); a.setAttributeNode(hrefAttr); @@ -86,6 +84,50 @@ function createNewsChild(news) { return li; } +function createLinkWithHighlightedParts(title, searchWord) { + const a = document.createElement('a'); + + const indices = [...title.toLowerCase().matchAll(new RegExp(searchWord, 'gi'))].map((a) => a.index).sort((a, b) => b-a); + const length = searchWord.length; + const separator = '*'; + + for (const index of indices) { + title = title.substr(0, index) + separator + title.substr(index, length) + separator + title.substr(index + length); + } + + const separatedBySearchWord = title.split(separator); + const nodes = separatedBySearchWord.map((element) => { + if (element.toLowerCase() === searchWord.toLowerCase()) + return createSpanNode(element); + else + return createTextNode(element); + }) + + a.append(...nodes); + + return a; +} + +function createSpanNode(text) { + const span = document.createElement('span'); + + const textNode = createTextNode(text); + span.appendChild(textNode); + + const classAttribute = document.createAttribute('class'); + classAttribute.value = 'highlight'; + + span.setAttributeNode(classAttribute); + + return span; +} + +function createTextNode(text) { + const textNode = document.createTextNode(text); + + return textNode; +} + function slideImage() { slideNumber = (slideNumber + 1) % 3; diff --git a/styles.css b/styles.css index 7920a803763db7e54f6e78eb33fd798c8005565d..db961a74ea3fe146ec85df4895fcc07fd18257d4 100644 --- a/styles.css +++ b/styles.css @@ -142,6 +142,10 @@ a { white-space: pre-wrap; } +.highlight { + color: yellow; +} + .admin-button a { display: block; padding: 0.5rem;