1 import {debounce} from "../services/util";
2 import {transitionHeight} from "../services/animations";
3 import {Component} from "./component";
5 export class DropdownSearch extends Component {
9 this.searchInput = this.$refs.searchInput;
10 this.loadingElem = this.$refs.loading;
11 this.listContainerElem = this.$refs.listContainer;
13 this.localSearchSelector = this.$opts.localSearchSelector;
14 this.url = this.$opts.url;
16 this.elem.addEventListener('show', this.onShow.bind(this));
17 this.searchInput.addEventListener('input', this.onSearch.bind(this));
19 this.runAjaxSearch = debounce(this.runAjaxSearch, 300, false);
27 const input = this.searchInput.value.toLowerCase().trim();
28 if (this.localSearchSelector) {
29 this.runLocalSearch(input);
31 this.toggleLoading(true);
32 this.listContainerElem.innerHTML = '';
33 this.runAjaxSearch(input);
37 runAjaxSearch(searchTerm) {
38 this.loadList(searchTerm);
41 runLocalSearch(searchTerm) {
42 const listItems = this.listContainerElem.querySelectorAll(this.localSearchSelector);
43 for (let listItem of listItems) {
44 const match = !searchTerm || listItem.textContent.toLowerCase().includes(searchTerm);
45 listItem.style.display = match ? 'flex' : 'none';
46 listItem.classList.toggle('hidden', !match);
50 async loadList(searchTerm = '') {
51 this.listContainerElem.innerHTML = '';
52 this.toggleLoading(true);
55 const resp = await window.$http.get(this.getAjaxUrl(searchTerm));
56 const animate = transitionHeight(this.listContainerElem, 80);
57 this.listContainerElem.innerHTML = resp.data;
63 this.toggleLoading(false);
64 if (this.localSearchSelector) {
69 getAjaxUrl(searchTerm = null) {
74 const joiner = this.url.includes('?') ? '&' : '?';
75 return `${this.url}${joiner}search=${encodeURIComponent(searchTerm)}`;
78 toggleLoading(show = false) {
79 this.loadingElem.style.display = show ? 'block' : 'none';