debian-mirror-gitlab/app/assets/javascripts/droplab/drop_down.js

175 lines
4.1 KiB
JavaScript
Raw Normal View History

2017-08-17 22:00:37 +05:30
import utils from './utils';
import { SELECTED_CLASS, IGNORE_CLASS } from './constants';
2017-09-10 17:25:29 +05:30
class DropDown {
2018-12-13 13:39:08 +05:30
constructor(list, config = {}) {
2017-09-10 17:25:29 +05:30
this.currentIndex = 0;
this.hidden = true;
this.list = typeof list === 'string' ? document.querySelector(list) : list;
this.items = [];
this.eventWrapper = {};
2018-03-17 18:26:18 +05:30
this.hideOnClick = config.hideOnClick !== false;
if (config.addActiveClassToDropdownButton) {
this.dropdownToggle = this.list.parentNode.querySelector('.js-dropdown-toggle');
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
this.getItems();
this.initTemplateString();
this.addEvents();
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
this.initialState = list.innerHTML;
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
getItems() {
2017-08-17 22:00:37 +05:30
this.items = [].slice.call(this.list.querySelectorAll('li'));
return this.items;
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
initTemplateString() {
const items = this.items || this.getItems();
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
let templateString = '';
2017-08-17 22:00:37 +05:30
if (items.length > 0) templateString = items[items.length - 1].outerHTML;
this.templateString = templateString;
return this.templateString;
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
clickEvent(e) {
2017-08-17 22:00:37 +05:30
if (e.target.tagName === 'UL') return;
2018-03-17 18:26:18 +05:30
if (e.target.closest(`.${IGNORE_CLASS}`)) return;
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
const selected = e.target.closest('li');
2017-08-17 22:00:37 +05:30
if (!selected) return;
this.addSelectedClass(selected);
e.preventDefault();
2018-03-17 18:26:18 +05:30
if (this.hideOnClick) {
this.hide();
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
const listEvent = new CustomEvent('click.dl', {
2017-08-17 22:00:37 +05:30
detail: {
list: this,
2017-09-10 17:25:29 +05:30
selected,
2017-08-17 22:00:37 +05:30
data: e.target.dataset,
},
});
this.list.dispatchEvent(listEvent);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
addSelectedClass(selected) {
2017-08-17 22:00:37 +05:30
this.removeSelectedClasses();
selected.classList.add(SELECTED_CLASS);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
removeSelectedClasses() {
2017-08-17 22:00:37 +05:30
const items = this.items || this.getItems();
items.forEach(item => item.classList.remove(SELECTED_CLASS));
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
addEvents() {
this.eventWrapper.clickEvent = this.clickEvent.bind(this);
2018-03-17 18:26:18 +05:30
this.eventWrapper.closeDropdown = this.closeDropdown.bind(this);
2017-08-17 22:00:37 +05:30
this.list.addEventListener('click', this.eventWrapper.clickEvent);
2018-03-17 18:26:18 +05:30
this.list.addEventListener('keyup', this.eventWrapper.closeDropdown);
}
closeDropdown(event) {
// `ESC` key closes the dropdown.
if (event.keyCode === 27) {
event.preventDefault();
return this.toggle();
}
return true;
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
setData(data) {
2017-08-17 22:00:37 +05:30
this.data = data;
this.render(data);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
addData(data) {
2017-08-17 22:00:37 +05:30
this.data = (this.data || []).concat(data);
this.render(this.data);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
render(data) {
2017-08-17 22:00:37 +05:30
const children = data ? data.map(this.renderChildren.bind(this)) : [];
2020-03-13 15:44:24 +05:30
if (this.list.querySelector('.filter-dropdown-loading')) {
return;
}
2017-08-17 22:00:37 +05:30
const renderableList = this.list.querySelector('ul[data-dynamic]') || this.list;
renderableList.innerHTML = children.join('');
2018-03-17 18:26:18 +05:30
const listEvent = new CustomEvent('render.dl', {
detail: {
list: this,
},
});
this.list.dispatchEvent(listEvent);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
renderChildren(data) {
const html = utils.template(this.templateString, data);
const template = document.createElement('div');
2017-08-17 22:00:37 +05:30
template.innerHTML = html;
2017-09-10 17:25:29 +05:30
DropDown.setImagesSrc(template);
2017-08-17 22:00:37 +05:30
template.firstChild.style.display = data.droplab_hidden ? 'none' : 'block';
return template.firstChild.outerHTML;
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
show() {
2017-08-17 22:00:37 +05:30
if (!this.hidden) return;
this.list.style.display = 'block';
this.currentIndex = 0;
this.hidden = false;
2018-03-17 18:26:18 +05:30
if (this.dropdownToggle) this.dropdownToggle.classList.add('active');
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
hide() {
2017-08-17 22:00:37 +05:30
if (this.hidden) return;
this.list.style.display = 'none';
this.currentIndex = 0;
this.hidden = true;
2018-03-17 18:26:18 +05:30
if (this.dropdownToggle) this.dropdownToggle.classList.remove('active');
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
toggle() {
if (this.hidden) return this.show();
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
return this.hide();
}
destroy() {
2017-08-17 22:00:37 +05:30
this.hide();
this.list.removeEventListener('click', this.eventWrapper.clickEvent);
2018-03-17 18:26:18 +05:30
this.list.removeEventListener('keyup', this.eventWrapper.closeDropdown);
2017-08-17 22:00:37 +05:30
}
2017-09-10 17:25:29 +05:30
static setImagesSrc(template) {
const images = [...template.querySelectorAll('img[data-src]')];
2018-12-13 13:39:08 +05:30
images.forEach(image => {
2017-09-10 17:25:29 +05:30
const img = image;
img.src = img.getAttribute('data-src');
img.removeAttribute('data-src');
});
}
}
2017-08-17 22:00:37 +05:30
export default DropDown;