318 lines
12 KiB
JavaScript
318 lines
12 KiB
JavaScript
function customSearch() {
|
||
let searchableContent = document.querySelectorAll('tr td:not(:last-of-type)');
|
||
let searchInput = document.querySelector('input[type="search"]');
|
||
let searchResults = document.querySelector('#search_results');
|
||
let isResultOpen = false;
|
||
let resultAmount = 0;
|
||
let resultAmountText = document.querySelector('#result_amount');
|
||
let hilightedWords;
|
||
let typingTimer;
|
||
let currentSelectedWord = 0;
|
||
let downArrow = document.querySelector('#search_results div div img:first-of-type');
|
||
let upArrow = document.querySelector('#search_results div div img:last-of-type');
|
||
|
||
let thereAreResults = false;
|
||
let inputIsActive = false;
|
||
|
||
searchInput.addEventListener('focus', () => { inputIsActive = true; toggleSearchResults(); });
|
||
searchInput.addEventListener('blur', () => { inputIsActive = false; });
|
||
|
||
searchInput.addEventListener('keydown', function(e) {
|
||
if ((e.key === 'Enter' || e.keyCode === 13) && resultAmount > 1) {
|
||
if (+resultAmountText.innerText.split('/')[0] === resultAmount) {
|
||
getToFirstOccurence();
|
||
} else {
|
||
getToNextOccurence(downArrow);
|
||
}
|
||
} else {
|
||
triggerSearch();
|
||
}
|
||
});
|
||
|
||
function triggerSearch() {
|
||
|
||
setTimeout(() => {
|
||
|
||
hilightedWords = [];
|
||
|
||
resultAmount = 0;
|
||
|
||
removeHighlightTags();
|
||
|
||
let input = searchInput.value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
||
|
||
if (searchInput.value.length >= 3) {
|
||
|
||
thereAreResults = true;
|
||
|
||
clearTimeout(typingTimer);
|
||
|
||
typingTimer = setTimeout(function() {
|
||
|
||
searchInContent(input);
|
||
|
||
let currentScroll = window.scrollY;
|
||
|
||
if (hilightedWords.length != 0) {
|
||
|
||
searchResults.querySelector('div p:first-of-type').style.display = "block";
|
||
searchResults.querySelector('div p:last-of-type').style.display = "none";
|
||
|
||
for (let i = 0; i < hilightedWords.length; i++) {
|
||
|
||
let wordBoundingTop = hilightedWords[i].getBoundingClientRect().top;
|
||
|
||
if (hilightedWords.length <= 1) {
|
||
let scrollValue = (wordBoundingTop + currentScroll) - window.innerHeight / 2;
|
||
window.scrollTo({ top: scrollValue, behavior: 'smooth' });
|
||
currentSelectedWord = 1;
|
||
resultAmountText.innerText = currentSelectedWord + "/" + resultAmountText.innerText;
|
||
upArrow.classList.add('disabled');
|
||
downArrow.classList.add('disabled');
|
||
} else {
|
||
if (currentScroll <= wordBoundingTop + currentScroll && i === 0) {
|
||
let scrollValue = (wordBoundingTop + currentScroll) - window.innerHeight / 2;
|
||
window.scrollTo({ top: scrollValue, behavior: 'smooth' });
|
||
currentSelectedWord = 1;
|
||
resultAmountText.innerText = currentSelectedWord + "/" + resultAmountText.innerText;
|
||
upArrow.classList.add('disabled');
|
||
downArrow.classList.remove('disabled');
|
||
break;
|
||
|
||
} else if (
|
||
currentScroll <= wordBoundingTop + currentScroll && currentScroll >= hilightedWords[i - 1]?.getBoundingClientRect().top + currentScroll
|
||
) {
|
||
let scrollValue = (wordBoundingTop + currentScroll) - window.innerHeight / 2;
|
||
window.scrollTo({ top: scrollValue, behavior: 'smooth' });
|
||
currentSelectedWord = i + 1;
|
||
resultAmountText.innerText = currentSelectedWord + "/" + resultAmountText.innerText;
|
||
upArrow.classList.remove('disabled');
|
||
if (i === hilightedWords.length - 1) {
|
||
downArrow.classList.add('disabled');
|
||
} else {
|
||
downArrow.classList.remove('disabled');
|
||
}
|
||
break;
|
||
|
||
} else if (currentScroll >= wordBoundingTop && i === hilightedWords.length - 1) {
|
||
let scrollValue = (wordBoundingTop + currentScroll) - window.innerHeight / 2;
|
||
window.scrollTo({ top: scrollValue, behavior: 'smooth' });
|
||
currentSelectedWord = hilightedWords.length;
|
||
resultAmountText.innerText = currentSelectedWord + "/" + resultAmountText.innerText;
|
||
upArrow.classList.remove('disabled');
|
||
downArrow.classList.add('disabled');
|
||
break;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
} else {
|
||
searchResults.querySelector('div p:first-of-type').style.display = "none";
|
||
searchResults.querySelector('div p:last-of-type').style.display = "block";
|
||
upArrow.classList.add('disabled');
|
||
downArrow.classList.add('disabled');
|
||
}
|
||
|
||
}, 800);
|
||
|
||
} else {
|
||
removeHighlightTags();
|
||
clearTimeout(typingTimer);
|
||
thereAreResults = false;
|
||
|
||
searchResults.querySelector('div p:first-of-type').style.display = "none";
|
||
searchResults.querySelector('div p:last-of-type').style.display = "block";
|
||
upArrow.classList.add('disabled');
|
||
downArrow.classList.add('disabled');
|
||
}
|
||
}, 10);
|
||
}
|
||
|
||
function searchInContent(input) {
|
||
for (let content of searchableContent) {
|
||
if (content.innerText != '') {
|
||
if (content.children.length > 0) {
|
||
for (let textEl of content.children) {
|
||
compareTexts(textEl, input);
|
||
}
|
||
} else {
|
||
compareTexts(content, input);
|
||
}
|
||
|
||
}
|
||
}
|
||
resultAmountText.innerText = resultAmount;
|
||
}
|
||
|
||
function compareTexts(textEl, input) {
|
||
if (textEl.innerText !== '') {
|
||
|
||
if (textEl.parentElement.tagName === "TR") {
|
||
input = input.replace(/'/g, '’');
|
||
}
|
||
|
||
if (textEl.innerHTML.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").includes(input)) {
|
||
|
||
let splitContent = textEl.innerHTML.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").split(input);
|
||
|
||
|
||
let processedText = '';
|
||
|
||
for (let i = 0; i < splitContent.length; i++) {
|
||
|
||
if (splitContent[0] !== '' || splitContent[splitContent.length - 1] !== '') {
|
||
|
||
if (i === 0) {
|
||
processedText += textEl.innerHTML.substring(0, splitContent[i].length);
|
||
|
||
} else {
|
||
let amountOfTextToConcatenate = 0;
|
||
for (let j = 0; j <= i - 1; j ++) {
|
||
amountOfTextToConcatenate += splitContent[j].length + input.length;
|
||
}
|
||
processedText +=
|
||
'<span class="highlight">' +
|
||
textEl.innerHTML.substring(amountOfTextToConcatenate - input.length, amountOfTextToConcatenate) +
|
||
'</span>' +
|
||
textEl.innerHTML.substring(
|
||
amountOfTextToConcatenate, amountOfTextToConcatenate + splitContent[i].length
|
||
);
|
||
|
||
}
|
||
} else if (splitContent[splitContent.length - 1] === '' && splitContent[0] === '') {
|
||
processedText = '<span class="highlight">' + textEl.innerHTML + '</span>';
|
||
|
||
}
|
||
|
||
}
|
||
|
||
textEl.innerHTML = processedText;
|
||
|
||
hilightedWords = document.querySelectorAll('.highlight');
|
||
resultAmount = hilightedWords.length;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
function removeHighlightTags() {
|
||
for (let content of searchableContent) {
|
||
if (content.innerHTML.includes('<span class="highlight">')) {
|
||
content.innerHTML = content.innerHTML.replace(/<span class="highlight">|<\/span>/g, '');
|
||
}
|
||
}
|
||
}
|
||
|
||
function toggleSearchResults() {
|
||
// dans le if thereAreResults || inputIsActive
|
||
// si on veut que les résultats restent ouvert
|
||
// quand il y a des résultats
|
||
if (inputIsActive) {
|
||
searchResults.style.top = `${searchInput.getBoundingClientRect().bottom + 5}px`;
|
||
searchResults.style.display = "block";
|
||
searchResults.style.opacity = 1;
|
||
searchResults.style.maxHeight = "1000px";
|
||
isResultOpen = true;
|
||
} else {
|
||
searchResults.style.opacity = 0;
|
||
searchResults.style.maxHeight = "0px";
|
||
isResultOpen = false;
|
||
setTimeout(() => {
|
||
searchResults.style.display = "none";
|
||
}, 300);
|
||
}
|
||
}
|
||
|
||
upArrow.addEventListener('click', function (el) {
|
||
getToPrevOccurence(el)
|
||
});
|
||
|
||
function getToPrevOccurence(el) {
|
||
if (!el.target.classList.contains('disabled')) {
|
||
let currentScroll = window.scrollY;
|
||
currentSelectedWord--;
|
||
|
||
let wordBoundingTop = hilightedWords[currentSelectedWord - 1].getBoundingClientRect().top;
|
||
|
||
let scrollValue = (wordBoundingTop + currentScroll) - window.innerHeight / 2;
|
||
window.scrollTo({ top: scrollValue, behavior: 'smooth' });
|
||
resultAmountText.innerText = currentSelectedWord + "/" + resultAmountText.innerText.split('/')[1];
|
||
|
||
if (currentSelectedWord === 1) {
|
||
upArrow.classList.add('disabled');
|
||
downArrow.classList.remove('disabled');
|
||
} else {
|
||
upArrow.classList.remove('disabled');
|
||
downArrow.classList.remove('disabled');
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
downArrow.addEventListener('click', function (el) {
|
||
getToNextOccurence(el.target);
|
||
});
|
||
|
||
function getToNextOccurence(el) {
|
||
if (!el.classList.contains('disabled')) {
|
||
let currentScroll = window.scrollY;
|
||
currentSelectedWord++;
|
||
|
||
let wordBoundingTop = hilightedWords[currentSelectedWord - 1].getBoundingClientRect().top;
|
||
|
||
let scrollValue = (wordBoundingTop + currentScroll) - window.innerHeight / 2;
|
||
window.scrollTo({ top: scrollValue, behavior: 'smooth' });
|
||
resultAmountText.innerText = currentSelectedWord + "/" + resultAmountText.innerText.split('/')[1];
|
||
|
||
if (currentSelectedWord === hilightedWords.length) {
|
||
downArrow.classList.add('disabled');
|
||
upArrow.classList.remove('disabled');
|
||
} else {
|
||
downArrow.classList.remove('disabled');
|
||
upArrow.classList.remove('disabled');
|
||
}
|
||
}
|
||
}
|
||
|
||
function getToFirstOccurence() {
|
||
let currentScroll = window.scrollY;
|
||
currentSelectedWord = 1;
|
||
|
||
let wordBoundingTop = hilightedWords[currentSelectedWord - 1].getBoundingClientRect().top;
|
||
|
||
let scrollValue = (wordBoundingTop + currentScroll) - window.innerHeight / 2;
|
||
window.scrollTo({ top: scrollValue, behavior: 'smooth' });
|
||
resultAmountText.innerText = currentSelectedWord + "/" + resultAmountText.innerText.split('/')[1];
|
||
|
||
downArrow.classList.remove('disabled');
|
||
upArrow.classList.add('disabled');
|
||
}
|
||
|
||
let tagsDiv = document.querySelector('#search_results > div:last-of-type');
|
||
|
||
window.addEventListener('click', function (el) {
|
||
if (!searchResults.contains(el.target) && isResultOpen && el.target != searchInput && el.target != tagsDiv) {
|
||
toggleSearchResults();
|
||
}
|
||
});
|
||
|
||
let searchWordList = document.querySelector('#content_search_tag');
|
||
searchWordList = searchWordList.innerText.substring(1, searchWordList.innerText.length - 1).split(', ');
|
||
|
||
for (let tag of searchWordList) {
|
||
let tagWrapper = document.createElement('p');
|
||
tagWrapper.innerText = tag;
|
||
tagWrapper.addEventListener('click', function () {
|
||
searchInput.value = tag;
|
||
triggerSearch();
|
||
});
|
||
tagsDiv.appendChild(tagWrapper);
|
||
}
|
||
}
|
||
|
||
export { customSearch }; |