X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/4e107b91604e4c110725ff6081a44f10f73cdf81..refs/pull/3908/head:/resources/js/components/auto-suggest.js diff --git a/resources/js/components/auto-suggest.js b/resources/js/components/auto-suggest.js index 7fce09890..b4e6c5957 100644 --- a/resources/js/components/auto-suggest.js +++ b/resources/js/components/auto-suggest.js @@ -1,13 +1,13 @@ import {escapeHtml} from "../services/util"; import {onChildEvent} from "../services/dom"; +import {Component} from "./component"; const ajaxCache = {}; /** * AutoSuggest - * @extends {Component} */ -class AutoSuggest { +export class AutoSuggest extends Component { setup() { this.parent = this.$el.parentElement; this.container = this.$el; @@ -16,6 +16,7 @@ class AutoSuggest { this.input = this.$refs.input; this.list = this.$refs.list; + this.lastPopulated = 0; this.setupListeners(); } @@ -44,7 +45,10 @@ class AutoSuggest { selectSuggestion(value) { this.input.value = value; + this.lastPopulated = Date.now(); this.input.focus(); + this.input.dispatchEvent(new Event('input', {bubbles: true})); + this.input.dispatchEvent(new Event('change', {bubbles: true})); this.hideSuggestions(); } @@ -79,15 +83,17 @@ class AutoSuggest { } async requestSuggestions() { + if (Date.now() - this.lastPopulated < 50) { + return; + } + const nameFilter = this.getNameFilterIfNeeded(); - const search = this.input.value.slice(0, 3); + const search = this.input.value.toLowerCase(); const suggestions = await this.loadSuggestions(search, nameFilter); - let toShow = suggestions.slice(0, 6); - if (search.length > 0) { - toShow = suggestions.filter(val => { - return val.toLowerCase().includes(search); - }).slice(0, 6); - } + + const toShow = suggestions.filter(val => { + return search === '' || val.toLowerCase().startsWith(search); + }).slice(0, 10); this.displaySuggestions(toShow); } @@ -103,6 +109,9 @@ class AutoSuggest { * @returns {Promise} */ async loadSuggestions(search, nameFilter = null) { + // Truncate search to prevent over numerous lookups + search = search.slice(0, 4); + const params = {search, name: nameFilter}; const cacheKey = `${this.url}:${JSON.stringify(params)}`; @@ -123,7 +132,7 @@ class AutoSuggest { return this.hideSuggestions(); } - this.list.innerHTML = suggestions.map(value => `
  • `).join(''); + this.list.innerHTML = suggestions.map(value => `
  • `).join(''); this.list.style.display = 'block'; for (const button of this.list.querySelectorAll('button')) { button.addEventListener('blur', this.hideSuggestionsIfFocusedLost.bind(this)); @@ -139,6 +148,4 @@ class AutoSuggest { this.hideSuggestions(); } } -} - -export default AutoSuggest; \ No newline at end of file +} \ No newline at end of file