1 import {htmlToDom} from "../services/dom";
2 import {debounce} from "../services/util";
3 import {KeyboardNavigationHandler} from "../services/keyboard-navigation";
4 import {Component} from "./component";
7 * Global (header) search box handling.
8 * Mainly to show live results preview.
10 export class GlobalSearch extends Component {
13 this.container = this.$el;
14 this.input = this.$refs.input;
15 this.suggestions = this.$refs.suggestions;
16 this.suggestionResultsWrap = this.$refs.suggestionResults;
17 this.loadingWrap = this.$refs.loading;
18 this.button = this.$refs.button;
20 this.setupListeners();
24 const updateSuggestionsDebounced = debounce(this.updateSuggestions.bind(this), 200, false);
26 // Handle search input changes
27 this.input.addEventListener('input', () => {
28 const value = this.input.value;
29 if (value.length > 0) {
30 this.loadingWrap.style.display = 'block';
31 this.suggestionResultsWrap.style.opacity = '0.5';
32 updateSuggestionsDebounced(value);
34 this.hideSuggestions();
38 // Allow double click to show auto-click suggestions
39 this.input.addEventListener('dblclick', () => {
40 this.input.setAttribute('autocomplete', 'on');
45 new KeyboardNavigationHandler(this.container, () => {
46 this.hideSuggestions();
51 * @param {String} search
53 async updateSuggestions(search) {
54 const {data: results} = await window.$http.get('/search/suggest', {term: search});
55 if (!this.input.value) {
59 const resultDom = htmlToDom(results);
61 this.suggestionResultsWrap.innerHTML = '';
62 this.suggestionResultsWrap.style.opacity = '1';
63 this.loadingWrap.style.display = 'none';
64 this.suggestionResultsWrap.append(resultDom);
65 if (!this.container.classList.contains('search-active')) {
66 this.showSuggestions();
71 this.container.classList.add('search-active');
72 window.requestAnimationFrame(() => {
73 this.suggestions.classList.add('search-suggestions-animation');
78 this.container.classList.remove('search-active');
79 this.suggestions.classList.remove('search-suggestions-animation');
80 this.suggestionResultsWrap.innerHTML = '';