debian-mirror-gitlab/app/assets/javascripts/filterable_list.js

103 lines
2.4 KiB
JavaScript
Raw Normal View History

2018-05-09 12:01:36 +05:30
import $ from 'jquery';
2017-09-10 17:25:29 +05:30
import _ from 'underscore';
2018-03-17 18:26:18 +05:30
import axios from './lib/utils/axios_utils';
2017-09-10 17:25:29 +05:30
2017-08-17 22:00:37 +05:30
/**
* 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.
*/
export default class FilterableList {
2018-03-17 18:26:18 +05:30
constructor(form, filter, holder, filterInputField = 'filter_groups') {
2017-08-17 22:00:37 +05:30
this.filterForm = form;
this.listFilterElement = filter;
this.listHolderElement = holder;
2018-03-17 18:26:18 +05:30
this.filterInputField = filterInputField;
2017-09-10 17:25:29 +05:30
this.isBusy = false;
}
getFilterEndpoint() {
2019-09-30 21:07:59 +05:30
return this.getPagePath();
2017-09-10 17:25:29 +05:30
}
getPagePath() {
2019-09-30 21:07:59 +05:30
const action = this.filterForm.getAttribute('action');
const params = $(this.filterForm).serialize();
return `${action}${action.indexOf('?') > 0 ? '&' : '?'}${params}`;
2017-08-17 22:00:37 +05:30
}
initSearch() {
2017-09-10 17:25:29 +05:30
// Wrap to prevent passing event arguments to .filterResults;
this.debounceFilter = _.debounce(this.onFilterInput.bind(this), 500);
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
this.unbindEvents();
this.bindEvents();
}
onFilterInput() {
const $form = $(this.filterForm);
const queryData = {};
2018-03-17 18:26:18 +05:30
const filterGroupsParam = $form.find(`[name="${this.filterInputField}"]`).val();
2017-09-10 17:25:29 +05:30
if (filterGroupsParam) {
2018-03-17 18:26:18 +05:30
queryData[this.filterInputField] = filterGroupsParam;
2017-09-10 17:25:29 +05:30
}
this.filterResults(queryData);
if (this.setDefaultFilterOption) {
this.setDefaultFilterOption();
}
}
bindEvents() {
2017-08-17 22:00:37 +05:30
this.listFilterElement.addEventListener('input', this.debounceFilter);
}
2017-09-10 17:25:29 +05:30
unbindEvents() {
this.listFilterElement.removeEventListener('input', this.debounceFilter);
}
2018-03-17 18:26:18 +05:30
filterResults(params) {
2017-09-10 17:25:29 +05:30
if (this.isBusy) {
return false;
}
2017-08-17 22:00:37 +05:30
$(this.listHolderElement).fadeTo(250, 0.5);
2018-03-17 18:26:18 +05:30
this.isBusy = true;
2018-12-13 13:39:08 +05:30
return axios
.get(this.getFilterEndpoint(), {
params,
})
.then(res => {
this.onFilterSuccess(res, params);
this.onFilterComplete();
})
.catch(() => this.onFilterComplete());
2017-08-17 22:00:37 +05:30
}
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
onFilterSuccess(response, queryData) {
if (response.data.html) {
this.listHolderElement.innerHTML = response.data.html;
2017-09-10 17:25:29 +05:30
}
// Change url so if user reload a page - search results are saved
const currentPath = this.getPagePath(queryData);
2018-12-13 13:39:08 +05:30
return window.history.replaceState(
{
page: currentPath,
},
document.title,
currentPath,
);
2017-09-10 17:25:29 +05:30
}
onFilterComplete() {
this.isBusy = false;
$(this.listHolderElement).fadeTo(250, 1);
}
2017-08-17 22:00:37 +05:30
}