2016-12-02 21:04:10 +00:00
|
|
|
/* eslint-disable no-param-reassign */
|
|
|
|
((global) => {
|
|
|
|
const DATA_DROPDOWN_TRIGGER = 'data-dropdown-trigger';
|
|
|
|
|
|
|
|
class FilteredSearchDropdown {
|
2016-12-08 21:36:54 +00:00
|
|
|
constructor(droplab, dropdown, input) {
|
|
|
|
this.droplab = droplab;
|
2016-12-02 21:04:10 +00:00
|
|
|
this.hookId = 'filtered-search';
|
|
|
|
this.input = input;
|
|
|
|
this.dropdown = dropdown;
|
|
|
|
this.bindEvents();
|
|
|
|
}
|
|
|
|
|
|
|
|
bindEvents() {
|
2016-12-09 17:44:09 +00:00
|
|
|
this.itemClickedWrapper = this.itemClicked.bind(this);
|
|
|
|
this.dropdown.addEventListener('click.dl', this.itemClickedWrapper);
|
2016-12-02 21:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unbindEvents() {
|
2016-12-09 17:44:09 +00:00
|
|
|
this.dropdown.removeEventListener('click.dl', this.itemClickedWrapper);
|
|
|
|
}
|
|
|
|
|
|
|
|
getCurrentHook() {
|
|
|
|
return this.droplab.hooks.filter(h => h.id === this.hookId)[0];
|
2016-12-02 21:04:10 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 18:57:07 +00:00
|
|
|
getEscapedText(text) {
|
|
|
|
let escapedText = text;
|
|
|
|
|
|
|
|
// Encapsulate value with quotes if it has spaces
|
|
|
|
if (text.indexOf(' ') !== -1) {
|
|
|
|
if (text.indexOf('"') !== -1) {
|
|
|
|
// Use single quotes if value contains double quotes
|
|
|
|
escapedText = `'${text}'`;
|
|
|
|
} else {
|
|
|
|
// Known side effect: values's with both single and double quotes
|
|
|
|
// won't escape properly
|
|
|
|
escapedText = `"${text}"`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return escapedText;
|
|
|
|
}
|
|
|
|
|
2016-12-02 21:04:10 +00:00
|
|
|
getSelectedText(selectedToken) {
|
|
|
|
// TODO: Get last word from FilteredSearchTokenizer
|
|
|
|
const lastWord = this.input.value.split(' ').last();
|
|
|
|
const lastWordIndex = selectedToken.indexOf(lastWord);
|
|
|
|
|
|
|
|
return lastWordIndex === -1 ? selectedToken : selectedToken.slice(lastWord.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
itemClicked(e) {
|
|
|
|
// Overridden by dropdown sub class
|
|
|
|
}
|
|
|
|
|
2016-12-09 17:44:09 +00:00
|
|
|
renderContent() {
|
|
|
|
// Overriden by dropdown sub class
|
2016-12-05 22:05:30 +00:00
|
|
|
}
|
|
|
|
|
2016-12-02 21:04:10 +00:00
|
|
|
setAsDropdown() {
|
|
|
|
this.input.setAttribute(DATA_DROPDOWN_TRIGGER, `#${this.listId}`);
|
|
|
|
}
|
|
|
|
|
2016-12-05 21:12:34 +00:00
|
|
|
setOffset(offset = 0) {
|
|
|
|
this.dropdown.style.left = `${offset}px`;
|
|
|
|
}
|
|
|
|
|
2016-12-05 22:05:30 +00:00
|
|
|
setDataValueIfSelected(selected) {
|
|
|
|
const dataValue = selected.getAttribute('data-value');
|
|
|
|
|
|
|
|
if (dataValue) {
|
|
|
|
gl.FilteredSearchManager.addWordToInput(dataValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dataValue !== null;
|
|
|
|
}
|
|
|
|
|
2016-12-09 17:44:09 +00:00
|
|
|
dismissDropdown() {
|
|
|
|
this.input.focus();
|
|
|
|
// Propogate input change to FilteredSearchManager
|
|
|
|
// so that it can determine which dropdowns to open
|
|
|
|
this.input.dispatchEvent(new Event('input'));
|
|
|
|
}
|
2016-12-02 21:04:10 +00:00
|
|
|
|
2016-12-08 21:36:54 +00:00
|
|
|
render(forceRenderContent) {
|
2016-12-02 21:04:10 +00:00
|
|
|
this.setAsDropdown();
|
|
|
|
|
|
|
|
const firstTimeInitialized = this.getCurrentHook() === undefined;
|
|
|
|
|
2016-12-08 21:36:54 +00:00
|
|
|
if (firstTimeInitialized || forceRenderContent) {
|
2016-12-02 21:04:10 +00:00
|
|
|
this.renderContent();
|
|
|
|
} else if(this.getCurrentHook().list.list.id !== this.listId) {
|
2016-12-08 21:36:54 +00:00
|
|
|
// this.droplab.changeHookList(this.hookId, `#${this.listId}`);
|
2016-12-02 21:04:10 +00:00
|
|
|
this.renderContent();
|
|
|
|
}
|
2016-12-07 18:55:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
resetFilters() {
|
|
|
|
const currentHook = this.getCurrentHook();
|
|
|
|
|
|
|
|
if (currentHook) {
|
|
|
|
const list = currentHook.list;
|
|
|
|
|
|
|
|
if (list.data) {
|
|
|
|
const data = list.data.map((item) => {
|
|
|
|
item.droplab_hidden = false;
|
|
|
|
});
|
|
|
|
|
|
|
|
list.render(data);
|
|
|
|
}
|
|
|
|
}
|
2016-12-02 21:04:10 +00:00
|
|
|
}
|
2016-12-08 21:36:54 +00:00
|
|
|
|
2016-12-09 17:44:09 +00:00
|
|
|
filterWithSymbol(filterSymbol, item, query) {
|
2016-12-08 21:36:54 +00:00
|
|
|
const { value } = gl.FilteredSearchTokenizer.getLastTokenObject(query);
|
|
|
|
const valueWithoutColon = value.slice(1).toLowerCase();
|
|
|
|
const prefix = valueWithoutColon[0];
|
|
|
|
const valueWithoutPrefix = valueWithoutColon.slice(1);
|
|
|
|
|
|
|
|
const title = item.title.toLowerCase();
|
|
|
|
|
2016-12-09 17:44:09 +00:00
|
|
|
// Eg. filterSymbol = ~ for labels
|
|
|
|
const matchWithoutPrefix = prefix === filterSymbol && title.indexOf(valueWithoutPrefix) !== -1;
|
2016-12-08 21:36:54 +00:00
|
|
|
const match = title.indexOf(valueWithoutColon) !== -1;
|
|
|
|
|
|
|
|
item.droplab_hidden = !match && !matchWithoutPrefix;
|
|
|
|
return item;
|
|
|
|
}
|
2016-12-02 21:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
global.FilteredSearchDropdown = FilteredSearchDropdown;
|
|
|
|
})(window.gl || (window.gl = {}));
|