2020-12-31 12:25:20 -05:00
|
|
|
import {debounce} from "../services/util";
|
2022-05-14 08:32:25 -04:00
|
|
|
import {transitionHeight} from "../services/animations";
|
2022-11-15 11:04:46 -05:00
|
|
|
import {Component} from "./component";
|
2020-12-31 12:25:20 -05:00
|
|
|
|
2022-11-15 11:04:46 -05:00
|
|
|
export class DropdownSearch extends Component {
|
2020-12-31 12:25:20 -05:00
|
|
|
|
|
|
|
setup() {
|
|
|
|
this.elem = this.$el;
|
|
|
|
this.searchInput = this.$refs.searchInput;
|
|
|
|
this.loadingElem = this.$refs.loading;
|
|
|
|
this.listContainerElem = this.$refs.listContainer;
|
|
|
|
|
|
|
|
this.localSearchSelector = this.$opts.localSearchSelector;
|
|
|
|
this.url = this.$opts.url;
|
|
|
|
|
|
|
|
this.elem.addEventListener('show', this.onShow.bind(this));
|
|
|
|
this.searchInput.addEventListener('input', this.onSearch.bind(this));
|
|
|
|
|
|
|
|
this.runAjaxSearch = debounce(this.runAjaxSearch, 300, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
onShow() {
|
|
|
|
this.loadList();
|
|
|
|
}
|
|
|
|
|
|
|
|
onSearch() {
|
|
|
|
const input = this.searchInput.value.toLowerCase().trim();
|
|
|
|
if (this.localSearchSelector) {
|
|
|
|
this.runLocalSearch(input);
|
|
|
|
} else {
|
|
|
|
this.toggleLoading(true);
|
2021-08-04 15:48:23 -04:00
|
|
|
this.listContainerElem.innerHTML = '';
|
2020-12-31 12:25:20 -05:00
|
|
|
this.runAjaxSearch(input);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
runAjaxSearch(searchTerm) {
|
|
|
|
this.loadList(searchTerm);
|
|
|
|
}
|
|
|
|
|
|
|
|
runLocalSearch(searchTerm) {
|
|
|
|
const listItems = this.listContainerElem.querySelectorAll(this.localSearchSelector);
|
|
|
|
for (let listItem of listItems) {
|
|
|
|
const match = !searchTerm || listItem.textContent.toLowerCase().includes(searchTerm);
|
|
|
|
listItem.style.display = match ? 'flex' : 'none';
|
|
|
|
listItem.classList.toggle('hidden', !match);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async loadList(searchTerm = '') {
|
|
|
|
this.listContainerElem.innerHTML = '';
|
|
|
|
this.toggleLoading(true);
|
|
|
|
|
|
|
|
try {
|
|
|
|
const resp = await window.$http.get(this.getAjaxUrl(searchTerm));
|
2022-05-14 08:32:25 -04:00
|
|
|
const animate = transitionHeight(this.listContainerElem, 80);
|
2020-12-31 12:25:20 -05:00
|
|
|
this.listContainerElem.innerHTML = resp.data;
|
2022-05-14 08:32:25 -04:00
|
|
|
animate();
|
2020-12-31 12:25:20 -05:00
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.toggleLoading(false);
|
|
|
|
if (this.localSearchSelector) {
|
|
|
|
this.onSearch();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getAjaxUrl(searchTerm = null) {
|
|
|
|
if (!searchTerm) {
|
|
|
|
return this.url;
|
|
|
|
}
|
|
|
|
|
|
|
|
const joiner = this.url.includes('?') ? '&' : '?';
|
|
|
|
return `${this.url}${joiner}search=${encodeURIComponent(searchTerm)}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleLoading(show = false) {
|
|
|
|
this.loadingElem.style.display = show ? 'block' : 'none';
|
|
|
|
}
|
|
|
|
|
2022-11-15 11:04:46 -05:00
|
|
|
}
|