Skip to content

Commit

Permalink
docs: Refactor search result handling with better event listener clea…
Browse files Browse the repository at this point in the history
…nup (#19252)
  • Loading branch information
amareshsm authored Dec 20, 2024
1 parent c5f3d7d commit f76d05d
Showing 1 changed file with 64 additions and 18 deletions.
82 changes: 64 additions & 18 deletions docs/src/assets/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,36 @@ function fetchSearchResults(query) {
}

/**
* Removes any current search results from the display.
* @returns {void}
* Clears the search results from the display.
* If the removeEventListener flag is true, removes the click event listener from the document.
* @param {boolean} [removeEventListener=false] - Optional flag to indicate if the click event listener should be removed. Default is false.
* @returns {void} - This function doesn't return anything.
*/
function clearSearchResults() {
while (resultsElement.firstChild) {
resultsElement.removeChild(resultsElement.firstChild);
function clearSearchResults(removeEventListener = false) {
resultsElement.innerHTML = "";
if (removeEventListener && document.clickEventAdded) {
document.removeEventListener('click', handleDocumentClick);
document.clickEventAdded = false;
}
}

/**
* Displays a "No results found" message in both the live region and results display area.
* This is typically used when no matching results are found in the search.
* @returns {void} - This function doesn't return anything.
*/
function showNoResults() {
resultsLiveRegion.innerHTML = "No results found.";
resultsElement.innerHTML = "No results found.";
resultsElement.setAttribute('data-results', 'false');
}

/**
* Clears any "No results found" message from the live region and results display area.
* @returns {void} - This function doesn't return anything.
*/
function clearNoResults() {
resultsLiveRegion.innerHTML = "";
resultsElement.innerHTML = "";
}

Expand Down Expand Up @@ -81,9 +104,7 @@ function displaySearchResults(results) {
}

} else {
resultsLiveRegion.innerHTML = "No results found.";
resultsElement.innerHTML = "No results found.";
resultsElement.setAttribute('data-results', 'false');
showNoResults();
}

}
Expand Down Expand Up @@ -125,12 +146,33 @@ function debounce(callback, delay) {
}
}

/**
* Debounced function to fetch search results after 300ms of inactivity.
* Calls `fetchSearchResults` to retrieve data and `displaySearchResults` to show them.
* If an error occurs, clears the search results.
* @param {string} query - The search query.
* @returns {void} - No return value.
* @see debounce - Limits the number of requests during rapid typing.
*/
const debouncedFetchSearchResults = debounce((query) => {
fetchSearchResults(query)
.then(displaySearchResults)
.catch(clearSearchResults);
.catch(() => { clearSearchResults(true) });
}, 300);


/**
* Handles the document click event to clear search results if the user clicks outside of the search input or results element.
* @param {MouseEvent} e - The event object representing the click event.
* @returns {void} - This function does not return any value. It directly interacts with the UI by clearing search results.
*/
const handleDocumentClick = (e) => {
if (e.target !== resultsElement && e.target !== searchInput) {
clearSearchResults(true);
}
}


//-----------------------------------------------------------------------------
// Event Handlers
//-----------------------------------------------------------------------------
Expand All @@ -146,14 +188,13 @@ if (searchInput)
else searchClearBtn.setAttribute('hidden', '');

if (query.length > 2) {

debouncedFetchSearchResults(query);

document.addEventListener('click', function (e) {
if (e.target !== resultsElement) clearSearchResults();
});
if (!document.clickEventAdded) {
document.addEventListener('click', handleDocumentClick);
document.clickEventAdded = true;
}
} else {
clearSearchResults();
clearSearchResults(true);
}

searchQuery = query
Expand All @@ -165,19 +206,24 @@ if (searchClearBtn)
searchClearBtn.addEventListener('click', function (e) {
searchInput.value = '';
searchInput.focus();
clearSearchResults();
clearSearchResults(true);
searchClearBtn.setAttribute('hidden', '');
});

document.addEventListener('keydown', function (e) {

const searchResults = Array.from(document.querySelectorAll('.search-results__item'));

if (e.key === 'Escape') {
if (e.key === "Escape") {
e.preventDefault();
if (searchResults.length) {
clearSearchResults();
clearSearchResults(true);
searchInput.focus();
} else if (
document.activeElement === searchInput
) {
clearNoResults();
searchInput.blur();
}
}

Expand Down

0 comments on commit f76d05d

Please sign in to comment.