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

139 lines
3.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 {
constructor(list) {
this.currentIndex = 0;
this.hidden = true;
this.list = typeof list === 'string' ? document.querySelector(list) : list;
this.items = [];
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
this.eventWrapper = {};
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;
if (e.target.classList.contains(IGNORE_CLASS)) return;
2017-09-10 17:25:29 +05:30
const selected = utils.closest(e.target, 'LI');
2017-08-17 22:00:37 +05:30
if (!selected) return;
this.addSelectedClass(selected);
e.preventDefault();
this.hide();
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);
2017-08-17 22:00:37 +05:30
this.list.addEventListener('click', this.eventWrapper.clickEvent);
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)) : [];
const renderableList = this.list.querySelector('ul[data-dynamic]') || this.list;
renderableList.innerHTML = children.join('');
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;
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;
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);
}
2017-09-10 17:25:29 +05:30
static setImagesSrc(template) {
const images = [...template.querySelectorAll('img[data-src]')];
images.forEach((image) => {
const img = image;
img.src = img.getAttribute('data-src');
img.removeAttribute('data-src');
});
}
}
2017-08-17 22:00:37 +05:30
export default DropDown;