mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-28 17:02:04 +03:00
Added global search input debounce and loading indicator
This commit is contained in:
@ -1,8 +1,9 @@
|
||||
import {htmlToDom} from "../services/dom";
|
||||
import {debounce} from "../services/util";
|
||||
|
||||
/**
|
||||
* @extends {Component}
|
||||
*/
|
||||
import {htmlToDom} from "../services/dom";
|
||||
|
||||
class GlobalSearch {
|
||||
|
||||
setup() {
|
||||
@ -10,23 +11,43 @@ class GlobalSearch {
|
||||
this.input = this.$refs.input;
|
||||
this.suggestions = this.$refs.suggestions;
|
||||
this.suggestionResultsWrap = this.$refs.suggestionResults;
|
||||
this.loadingWrap = this.$refs.loading;
|
||||
|
||||
this.setupListeners();
|
||||
}
|
||||
|
||||
setupListeners() {
|
||||
const updateSuggestionsDebounced = debounce(this.updateSuggestions.bind(this), 200, false);
|
||||
|
||||
// Handle search input changes
|
||||
this.input.addEventListener('input', () => {
|
||||
const value = this.input.value;
|
||||
if (value.length > 0) {
|
||||
this.updateSuggestions(value);
|
||||
this.loadingWrap.style.display = 'block';
|
||||
this.suggestionResultsWrap.style.opacity = '0.5';
|
||||
updateSuggestionsDebounced(value);
|
||||
} else {
|
||||
this.hideSuggestions();
|
||||
}
|
||||
});
|
||||
|
||||
// Allow double click to show auto-click suggestions
|
||||
this.input.addEventListener('dblclick', () => {
|
||||
this.input.setAttribute('autocomplete', 'on');
|
||||
this.input.blur();
|
||||
this.input.focus();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} search
|
||||
*/
|
||||
async updateSuggestions(search) {
|
||||
const {data: results} = await window.$http.get('/ajax/search/entities', {term: search, count: 5});
|
||||
if (!this.input.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resultDom = htmlToDom(results);
|
||||
|
||||
const childrenToTrim = Array.from(resultDom.children).slice(9);
|
||||
@ -35,6 +56,8 @@ class GlobalSearch {
|
||||
}
|
||||
|
||||
this.suggestionResultsWrap.innerHTML = '';
|
||||
this.suggestionResultsWrap.style.opacity = '1';
|
||||
this.loadingWrap.style.display = 'none';
|
||||
this.suggestionResultsWrap.append(resultDom);
|
||||
if (!this.container.classList.contains('search-active')) {
|
||||
this.showSuggestions();
|
||||
|
@ -6,9 +6,9 @@
|
||||
* N milliseconds. If `immediate` is passed, trigger the function on the
|
||||
* leading edge, instead of the trailing.
|
||||
* @attribution https://davidwalsh.name/javascript-debounce-function
|
||||
* @param func
|
||||
* @param wait
|
||||
* @param immediate
|
||||
* @param {Function} func
|
||||
* @param {Number} wait
|
||||
* @param {Boolean} immediate
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function debounce(func, wait, immediate) {
|
||||
|
Reference in New Issue
Block a user