this.input = this.$refs.input;
this.list = this.$refs.list;
+ this.lastPopulated = 0;
this.setupListeners();
}
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();
}
}
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);
}
* @returns {Promise<Object|String|*>}
*/
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)}`;
return this.hideSuggestions();
}
- this.list.innerHTML = suggestions.map(value => `<li><button type="button">${escapeHtml(value)}</button></li>`).join('');
+ this.list.innerHTML = suggestions.map(value => `<li><button type="button" class="text-item">${escapeHtml(value)}</button></li>`).join('');
this.list.style.display = 'block';
for (const button of this.list.querySelectorAll('button')) {
button.addEventListener('blur', this.hideSuggestionsIfFocusedLost.bind(this));