You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
10 KiB
306 lines
10 KiB
// `
|
|
class SelectBox {
|
|
constructor($container, data, has_editable_container, vertical_child) {
|
|
this.container_id = $container.attr("id");
|
|
this.tree_data = new SpecTree(data);
|
|
// Вариант не выбран
|
|
this.selected_id = undefined;
|
|
let template = SelectBox.getTemplate("Header", this.container_id, has_editable_container, vertical_child);
|
|
$container.replaceWith(template);
|
|
this._buildComponents();
|
|
this._bindEvents();
|
|
if (!has_editable_container) this.hide();
|
|
}
|
|
|
|
static getTemplate(header, id, editable_container, vertical_child) {
|
|
let main = `
|
|
<div class="row">
|
|
<div class="col-lg-3 test">
|
|
<input class="select-box-search" type="text" placeholder="Выберите/Поиск">
|
|
<button class="button-add options">добавить</button>
|
|
</div>
|
|
<div class="col-lg-9">
|
|
<span class="editable-container"></span>
|
|
</div>
|
|
</div>
|
|
`;
|
|
let child = `
|
|
<input class="select-box-search" type="text" placeholder="Выберите/Поиск">
|
|
<span style="clear:both; display:block"></span>
|
|
<button class="button-add options">добавить</button>
|
|
`;
|
|
let insert_template = editable_container ? main : child;
|
|
vertical_child = vertical_child ? 'vertical-child' : '';
|
|
let htmlTemplate =
|
|
`
|
|
<span class="select-box-container ${vertical_child}" id="${id}">
|
|
<div class="select-box-header">
|
|
<span class="header">${header}</span>
|
|
<i class="fa fa-question-circle-o" aria-hidden="true" title="bla-bla-bla..."></i>
|
|
</div>
|
|
<span class="select-box-search">
|
|
${insert_template}
|
|
</span>
|
|
<span class="select-box-options">
|
|
<span class="box-wrapper">
|
|
<ul>
|
|
|
|
</ul>
|
|
</span>
|
|
</span>
|
|
<span class="select-box-results">
|
|
<span class="box-wrapper">
|
|
<span class="main-part">
|
|
<ul>
|
|
</ul>
|
|
</span>
|
|
<span class="other-part">
|
|
<span class="other-header">Из других категорий</span>
|
|
<ul>
|
|
</ul>
|
|
</span>
|
|
</span>
|
|
<button class="button-add results">добавить</button>
|
|
</span>
|
|
<span style="clear: both"></span>
|
|
</span>
|
|
`;
|
|
return htmlTemplate;
|
|
}
|
|
|
|
_buildComponents() {
|
|
this.$select_box = $(`#${this.container_id}`);
|
|
this.$header = this.$select_box.find('.select-box-header .header');
|
|
this.$results_box = this.$select_box.find('.select-box-results');
|
|
this.$options_box = this.$select_box.find('.select-box-options');
|
|
this.$search_input = this.$select_box.find('input.select-box-search');
|
|
this.$button_add = this.$results_box.find('.button-add');
|
|
this.$button_add_options = this.$select_box.find('.button-add.options');
|
|
this.$editable_container = this.$select_box.find('.editable-container');
|
|
this._fillOptionsData();
|
|
this.$results_box.hide();
|
|
this.$options_box.hide();
|
|
this.$button_add_options.hide();
|
|
// TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select
|
|
}
|
|
|
|
static highlight(string, sub_string) {
|
|
let index = string.toLowerCase().indexOf(sub_string.toLowerCase());
|
|
if (index === -1) return string;
|
|
let light_template = (el) => `<span class="highlight">${el}</span>`;
|
|
let [to, select, after] = [string.slice(0, index),
|
|
string.slice(index, index + sub_string.length),
|
|
string.slice(index + sub_string.length)];
|
|
return `${to}${light_template(select)}${after}`
|
|
}
|
|
|
|
hide() {
|
|
this.$select_box.hide();
|
|
}
|
|
|
|
show() {
|
|
this.$select_box.show();
|
|
}
|
|
|
|
clear() {
|
|
this.$search_input.val("");
|
|
this.$options_box.hide();
|
|
this.$results_box.hide();
|
|
this.$button_add_options.hide();
|
|
this.element_id = undefined;
|
|
this.parent_id = undefined;
|
|
this.$editable_container.html("");
|
|
if (this.prev_select_box) this.hide();
|
|
this.selected_id = undefined;
|
|
this.selected_val = "";
|
|
}
|
|
|
|
clearAll(only_next) {
|
|
// console.log("only_next = ", only_next);
|
|
if (this.next_select_box) {
|
|
this.next_select_box.clear()
|
|
}
|
|
if (!only_next) {
|
|
this.clear();
|
|
if (this.prev_select_box) this.prev_select_box.clearAll(only_next)
|
|
} else {
|
|
if (this.next_select_box) this.next_select_box.clearAll(only_next)
|
|
}
|
|
|
|
}
|
|
|
|
setHeader(header) {
|
|
this.$header.html(header);
|
|
this.show();
|
|
}
|
|
|
|
setParent(parent_id) {
|
|
// console.log("setParent id -->", parent_id);
|
|
this.parent_id = parent_id;
|
|
this._fillOptionsData();
|
|
}
|
|
|
|
setNearbySelectBox(next, prev) {
|
|
this.next_select_box = next;
|
|
this.prev_select_box = prev;
|
|
}
|
|
|
|
getSelectedElements() {
|
|
let all_checked = this.$results_box.find(":checked");
|
|
return all_checked.map(function () {
|
|
return $(this).data("id");
|
|
})
|
|
}
|
|
|
|
connectSelectedContainer(selected_container) {
|
|
this.selected_container = selected_container;
|
|
this.selected_container = selected_container;
|
|
|
|
}
|
|
|
|
updateEditableContainer(el_id) {
|
|
// Если нет контейнера для отображения ...
|
|
if (this.$editable_container.length) {
|
|
let chain_header = SelectedContainer.getHeader(
|
|
this.tree_data.getSpecChain(el_id, true), " / ");
|
|
let el_template = `<span class="">${chain_header}</span>`;
|
|
this.$editable_container.html(el_template);
|
|
return;
|
|
}
|
|
//..., передаем отображение предыдущему selectBox
|
|
if (this.prev_select_box) this.prev_select_box.updateEditableContainer(el_id);
|
|
}
|
|
|
|
_onclickOptionsElement(e) {
|
|
this.clearAll(true);
|
|
let el_id = $(e.target).data("id");
|
|
this.selected_id = el_id;
|
|
this.selected_val = $(e.target).html();
|
|
this.updateEditableContainer(el_id);
|
|
this.$search_input.val($(e.target).html());
|
|
// this.element_id = el_id;
|
|
if (this.next_select_box) {
|
|
this.next_select_box.setParent(el_id);
|
|
this.next_select_box.setHeader($(e.target).html());
|
|
}
|
|
if (this.prev_select_box) this.prev_select_box.$button_add_options.hide();
|
|
|
|
this.$button_add_options.show();
|
|
this.$options_box.hide();
|
|
}
|
|
|
|
_onButtonAdd(e) {
|
|
let self = this;
|
|
|
|
this.getSelectedElements().each(function () {
|
|
console.log("add el -->", this);
|
|
self.selected_container.add(this, 40);
|
|
});
|
|
this.clearAll();
|
|
e.preventDefault();
|
|
return false;
|
|
}
|
|
|
|
_onButtonAddOptions(e) {
|
|
this.selected_container.add(this.element_id, 40);
|
|
this.clearAll();
|
|
e.preventDefault();
|
|
return false;
|
|
}
|
|
|
|
_fillOptionsData() {
|
|
let self = this;
|
|
let spec_list = this.tree_data.dataToList(this.parent_id);
|
|
let $container = this.$options_box.find('ul');
|
|
$container.html("");
|
|
spec_list.forEach(function (el) {
|
|
let el_html = `<li data-id="${el.id}">${el.name}</li>`;
|
|
$container.append($(el_html))
|
|
});
|
|
this.$select_box.find('li').on("click", this._onclickOptionsElement.bind(self));
|
|
|
|
}
|
|
|
|
_fillResultsData(search_text) {
|
|
let self = this;
|
|
|
|
function search(search_text, parent_id, exclude_id) {
|
|
// :FORMAT spec_list [{name, id}, ...]
|
|
let spec_list = self.tree_data.dataToList(parent_id, true, exclude_id);
|
|
// console.log("search -->", spec_list.length);
|
|
console.log("parent_id ", parent_id);
|
|
return spec_list.filter(function (el) {
|
|
return el.name.toLowerCase().indexOf(search_text.toLowerCase()) !== -1;
|
|
});
|
|
}
|
|
|
|
function fillContainer($container, template, search_text, parent_id, exclude_id) {
|
|
$container.html("");
|
|
let search_res = search(search_text, parent_id, exclude_id);
|
|
if (!search_res.length || (!exclude_id && parent_id === null)) {
|
|
$container.append('<span>No Found</span>');
|
|
return;
|
|
}
|
|
search_res.forEach(function (el) {
|
|
$container.append(template(SelectBox.highlight(el.name, search_text), el.id));
|
|
});
|
|
}
|
|
|
|
// FILL RESULTS
|
|
let result_template = (el, id) =>
|
|
`<li><label><input type="checkbox" data-id="${id}"><span class="noselect">${el}</span></label></li>`;
|
|
// MAIN PART
|
|
let $container = this.$results_box.find('.main-part ul');
|
|
fillContainer($container, result_template, search_text, self.parent_id);
|
|
|
|
// OTHER PART
|
|
$container = this.$results_box.find('.other-part ul');
|
|
fillContainer($container, result_template, search_text, null, self.parent_id);
|
|
}
|
|
|
|
_looseFocus() {
|
|
this.$results_box.hide();
|
|
this.$options_box.hide();
|
|
if (!this.selected_id) {
|
|
this.$search_input.val("");
|
|
} else {
|
|
this.$search_input.val(this.selected_val);
|
|
}
|
|
}
|
|
|
|
_bindEvents() {
|
|
let self = this;
|
|
$(document).click(function (event) {
|
|
if ($(event.target).closest(`#${self.container_id}`).length) {
|
|
return;
|
|
}
|
|
self._looseFocus();
|
|
});
|
|
// console.log("out ", this.$options_box);
|
|
this.$search_input.on("input", function (e) {
|
|
self._fillResultsData(self.$search_input.val());
|
|
self.$results_box.show();
|
|
self.$options_box.hide();
|
|
|
|
});
|
|
|
|
this.$search_input.on("click", function (e) {
|
|
// console.log("in ", self.$options_box);
|
|
self.$options_box.show();
|
|
self.$results_box.hide();
|
|
self.$button_add_options.hide();
|
|
self.$search_input.val("");
|
|
|
|
});
|
|
|
|
|
|
this.$button_add.on("click", function (e) {
|
|
self._onButtonAdd(e);
|
|
});
|
|
|
|
this.$button_add_options.on("click", this._onButtonAddOptions.bind(self))
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|