2018-03-09 20:18:59 +00:00
|
|
|
import $ from 'jquery';
|
2020-04-21 15:21:10 +00:00
|
|
|
import { debounce } from 'lodash';
|
2018-01-26 10:49:05 +00:00
|
|
|
import axios from './lib/utils/axios_utils';
|
2017-08-03 20:31:53 +00:00
|
|
|
|
2017-03-03 10:13:03 +00:00
|
|
|
/**
|
|
|
|
* Makes search request for content when user types a value in the search input.
|
|
|
|
* Updates the html content of the page with the received one.
|
|
|
|
*/
|
2017-03-11 07:30:44 +00:00
|
|
|
|
2017-03-03 10:13:03 +00:00
|
|
|
export default class FilterableList {
|
2017-10-04 14:10:24 +00:00
|
|
|
constructor(form, filter, holder, filterInputField = 'filter_groups') {
|
2017-03-03 10:13:03 +00:00
|
|
|
this.filterForm = form;
|
|
|
|
this.listFilterElement = filter;
|
|
|
|
this.listHolderElement = holder;
|
2017-10-04 14:10:24 +00:00
|
|
|
this.filterInputField = filterInputField;
|
2017-06-06 05:06:08 +00:00
|
|
|
this.isBusy = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
getFilterEndpoint() {
|
2019-07-04 22:30:34 +00:00
|
|
|
return this.getPagePath();
|
2017-06-06 05:06:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getPagePath() {
|
2019-07-04 22:30:34 +00:00
|
|
|
const action = this.filterForm.getAttribute('action');
|
2019-09-19 21:06:29 +00:00
|
|
|
// eslint-disable-next-line no-jquery/no-serialize
|
2019-07-04 22:30:34 +00:00
|
|
|
const params = $(this.filterForm).serialize();
|
|
|
|
return `${action}${action.indexOf('?') > 0 ? '&' : '?'}${params}`;
|
2017-03-03 10:13:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
initSearch() {
|
2017-05-11 01:24:31 +00:00
|
|
|
// Wrap to prevent passing event arguments to .filterResults;
|
2020-04-21 15:21:10 +00:00
|
|
|
this.debounceFilter = debounce(this.onFilterInput.bind(this), 500);
|
2017-03-03 10:13:03 +00:00
|
|
|
|
2017-05-10 18:30:30 +00:00
|
|
|
this.unbindEvents();
|
|
|
|
this.bindEvents();
|
|
|
|
}
|
|
|
|
|
2017-05-31 02:23:03 +00:00
|
|
|
onFilterInput() {
|
2017-06-06 05:06:08 +00:00
|
|
|
const $form = $(this.filterForm);
|
|
|
|
const queryData = {};
|
2017-10-04 14:10:24 +00:00
|
|
|
const filterGroupsParam = $form.find(`[name="${this.filterInputField}"]`).val();
|
2017-06-06 05:06:08 +00:00
|
|
|
|
|
|
|
if (filterGroupsParam) {
|
2017-10-04 14:10:24 +00:00
|
|
|
queryData[this.filterInputField] = filterGroupsParam;
|
2017-06-06 05:06:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this.filterResults(queryData);
|
|
|
|
|
|
|
|
if (this.setDefaultFilterOption) {
|
|
|
|
this.setDefaultFilterOption();
|
|
|
|
}
|
2017-05-31 02:23:03 +00:00
|
|
|
}
|
|
|
|
|
2017-05-10 18:30:30 +00:00
|
|
|
bindEvents() {
|
2017-03-03 10:13:03 +00:00
|
|
|
this.listFilterElement.addEventListener('input', this.debounceFilter);
|
|
|
|
}
|
|
|
|
|
2017-05-10 18:30:30 +00:00
|
|
|
unbindEvents() {
|
|
|
|
this.listFilterElement.removeEventListener('input', this.debounceFilter);
|
|
|
|
}
|
|
|
|
|
2018-01-26 10:49:05 +00:00
|
|
|
filterResults(params) {
|
2017-06-06 05:06:08 +00:00
|
|
|
if (this.isBusy) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-03-03 10:13:03 +00:00
|
|
|
|
2020-12-02 15:09:37 +00:00
|
|
|
$(this.listHolderElement).addClass('gl-opacity-5');
|
2017-03-03 10:13:03 +00:00
|
|
|
|
2018-01-26 10:49:05 +00:00
|
|
|
this.isBusy = true;
|
|
|
|
|
2018-10-24 19:17:03 +00:00
|
|
|
return axios
|
|
|
|
.get(this.getFilterEndpoint(), {
|
|
|
|
params,
|
|
|
|
})
|
2020-12-23 21:10:24 +00:00
|
|
|
.then((res) => {
|
2018-10-24 19:17:03 +00:00
|
|
|
this.onFilterSuccess(res, params);
|
|
|
|
this.onFilterComplete();
|
|
|
|
})
|
|
|
|
.catch(() => this.onFilterComplete());
|
2017-03-03 10:13:03 +00:00
|
|
|
}
|
2017-05-10 18:30:30 +00:00
|
|
|
|
2018-01-26 10:49:05 +00:00
|
|
|
onFilterSuccess(response, queryData) {
|
2018-01-26 11:34:06 +00:00
|
|
|
if (response.data.html) {
|
2018-01-26 10:49:05 +00:00
|
|
|
this.listHolderElement.innerHTML = response.data.html;
|
2017-05-11 01:24:31 +00:00
|
|
|
}
|
|
|
|
|
2017-06-06 05:06:08 +00:00
|
|
|
// Change url so if user reload a page - search results are saved
|
|
|
|
const currentPath = this.getPagePath(queryData);
|
2017-05-10 18:30:30 +00:00
|
|
|
|
2018-10-24 19:17:03 +00:00
|
|
|
return window.history.replaceState(
|
|
|
|
{
|
|
|
|
page: currentPath,
|
|
|
|
},
|
|
|
|
document.title,
|
|
|
|
currentPath,
|
|
|
|
);
|
2017-05-10 18:30:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onFilterComplete() {
|
2017-06-06 05:06:08 +00:00
|
|
|
this.isBusy = false;
|
2020-12-02 15:09:37 +00:00
|
|
|
$(this.listHolderElement).removeClass('gl-opacity-5');
|
2017-05-10 18:30:30 +00:00
|
|
|
}
|
2017-03-03 10:13:03 +00:00
|
|
|
}
|