gitlab-org--gitlab-foss/app/assets/javascripts/droplab/drop_down.js

146 lines
3.3 KiB
JavaScript
Raw Normal View History

2017-04-06 10:36:26 +00:00
import utils from './utils';
import { SELECTED_CLASS, IGNORE_CLASS } from './constants';
2017-04-06 10:36:26 +00:00
class DropDown {
constructor(list) {
this.currentIndex = 0;
this.hidden = true;
this.list = typeof list === 'string' ? document.querySelector(list) : list;
this.items = [];
2017-04-06 10:36:26 +00:00
this.eventWrapper = {};
2017-04-06 10:36:26 +00:00
this.getItems();
this.initTemplateString();
this.addEvents();
2017-04-06 10:36:26 +00:00
this.initialState = list.innerHTML;
}
2017-04-06 10:36:26 +00:00
getItems() {
2017-04-06 10:36:26 +00:00
this.items = [].slice.call(this.list.querySelectorAll('li'));
return this.items;
}
2017-04-06 10:36:26 +00:00
initTemplateString() {
const items = this.items || this.getItems();
2017-04-06 10:36:26 +00:00
let templateString = '';
2017-04-06 10:36:26 +00:00
if (items.length > 0) templateString = items[items.length - 1].outerHTML;
this.templateString = templateString;
return this.templateString;
}
2017-04-06 10:36:26 +00:00
clickEvent(e) {
2017-04-06 23:56:46 +00:00
if (e.target.tagName === 'UL') return;
if (e.target.classList.contains(IGNORE_CLASS)) return;
2017-04-06 23:56:46 +00:00
const selected = utils.closest(e.target, 'LI');
2017-04-06 10:36:26 +00:00
if (!selected) return;
this.addSelectedClass(selected);
e.preventDefault();
this.hide();
const listEvent = new CustomEvent('click.dl', {
2017-04-06 10:36:26 +00:00
detail: {
list: this,
selected,
2017-04-06 10:36:26 +00:00
data: e.target.dataset,
},
});
this.list.dispatchEvent(listEvent);
}
2017-04-06 10:36:26 +00:00
addSelectedClass(selected) {
2017-04-06 10:36:26 +00:00
this.removeSelectedClasses();
selected.classList.add(SELECTED_CLASS);
}
2017-04-06 10:36:26 +00:00
removeSelectedClasses() {
2017-04-06 10:36:26 +00:00
const items = this.items || this.getItems();
items.forEach(item => item.classList.remove(SELECTED_CLASS));
}
2017-04-06 10:36:26 +00:00
addEvents() {
this.eventWrapper.clickEvent = this.clickEvent.bind(this);
2017-04-06 10:36:26 +00:00
this.list.addEventListener('click', this.eventWrapper.clickEvent);
}
2017-04-06 10:36:26 +00:00
setData(data) {
2017-04-06 10:36:26 +00:00
this.data = data;
this.render(data);
}
2017-04-06 10:36:26 +00:00
addData(data) {
2017-04-06 10:36:26 +00:00
this.data = (this.data || []).concat(data);
this.render(this.data);
}
2017-04-06 10:36:26 +00:00
render(data) {
2017-04-06 10:36:26 +00:00
const children = data ? data.map(this.renderChildren.bind(this)) : [];
const renderableList = this.list.querySelector('ul[data-dynamic]') || this.list;
renderableList.innerHTML = children.join('');
2017-08-30 07:48:55 +00:00
const listEvent = new CustomEvent('render.dl', {
detail: {
list: this,
},
});
this.list.dispatchEvent(listEvent);
}
2017-04-06 10:36:26 +00:00
renderChildren(data) {
const html = utils.template(this.templateString, data);
const template = document.createElement('div');
2017-04-06 10:36:26 +00:00
template.innerHTML = html;
DropDown.setImagesSrc(template);
2017-04-06 10:36:26 +00:00
template.firstChild.style.display = data.droplab_hidden ? 'none' : 'block';
return template.firstChild.outerHTML;
}
2017-04-06 10:36:26 +00:00
show() {
2017-04-06 10:36:26 +00:00
if (!this.hidden) return;
this.list.style.display = 'block';
this.currentIndex = 0;
this.hidden = false;
}
2017-04-06 10:36:26 +00:00
hide() {
2017-04-06 10:36:26 +00:00
if (this.hidden) return;
this.list.style.display = 'none';
this.currentIndex = 0;
this.hidden = true;
}
2017-04-06 10:36:26 +00:00
toggle() {
if (this.hidden) return this.show();
2017-04-06 10:36:26 +00:00
return this.hide();
}
destroy() {
2017-04-06 10:36:26 +00:00
this.hide();
this.list.removeEventListener('click', this.eventWrapper.clickEvent);
}
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-04-06 10:36:26 +00:00
export default DropDown;