// ` import DataTree from './data/DataTree' import NoTreeData from './data/NoTreeData' import onBind from './decorators' let tmpl_selectedElement = (header, name, id) => `
${header}
${name}
`; export default class SelectedContainer { constructor($container, {obj, noTree = false, noHeader = false, onlyOne = false}) { // TODO: rename variables to camelCase this.$self = $container; this.elements_id = []; // [spec_id, spec_id, ...] this.onlyOne = onlyOne; this.options = {noHeader}; const self = this; this.$self.hide(); this.dataPromise = obj.dataPromise; this.dataPromise .then( (data) => { data = data.results ? data.results : data; this.dataTree = noTree ? new NoTreeData(data) : new DataTree(data); this.$input = this.$self.find('input[type="hidden"]'); if (this.$input.length == 0) throw new URIError(`input for ${this.$self.attr("class")} not found`); this.restoreElements(); } ) .catch( self._onLoadDataError.bind(self) ); } restoreElements() { const self = this; if (this.$input && this.$input.val()) { let clearString = this.$input.val().replace(/[\[\]\'\'\"\"]/g, ''); let data = clearString.split(',').filter((el) => el); this.elements_id = []; if (this.$input) this.$input.val(this.elements_id.join(',')); data.forEach((el) => self.add(el)); } } static getTemplate(header, name, id) { return tmpl_selectedElement(header, name, id) } static getHeader(spec_chain, separator, max_len) { function toShortString(string, max_len) { return string.slice(0, max_len) + (string.length > max_len ? "..." : ""); } separator = separator || ' / '; let str_chain = ""; spec_chain.forEach(function (el) { str_chain = (max_len ? toShortString(el.name, max_len) : el.name) + (str_chain ? separator : "") + str_chain; }); return str_chain; } on(methodName, func) { this[methodName] = this[methodName].bind(this, {func, bindFunc: true}); } _removeById(id) { let index = this.elements_id.indexOf(id); if (index >= 0) { this.elements_id.splice(index, 1); } this.$self.find(`span[data-id='${id}']`).parents('.selected-element').remove(); } _onLoadDataError(error) { console.log("Error loading data -->", error); } removeAll() { for (let id of this.elements_id){ this._removeById(id); } } @onBind remove(e) { let spec_id = $(e.target).data("id"); this._removeById(spec_id); if (this.$input) this.$input.val(this.elements_id.join(',')); if (!this.elements_id.length) this.$self.hide(); e.preventDefault(); } replace(_id, max_len) { const id = Number(_id); if (this.elements_id.length > 1) throw new RangeError("Replace error: more than one element"); // Remove old this._removeById(this.elements_id[0]); //Add new this._addElementToHtml(id, max_len); this.elements_id = [id]; } _addElementToHtml(id, max_len) { let self = this; const header = SelectedContainer.getHeader(this.dataTree.getSpecChain(id), "", max_len); const name = this.dataTree.getElementById(id).name; this.elements_id.push(id); if (this.$input) this.$input.val(this.elements_id.join(',')); // console.log("header = ", header); this.$self.append(SelectedContainer.getTemplate(header || (this.options.noHeader ? "" : " ") , name, id)); this.btn_remove = this.$self.find('.icon-remove'); this.btn_remove.on("click", this.remove.bind(self)); if (this.elements_id.length) this.$self.show(); } @onBind add(_id, max_len) { const id = Number(_id); const el = this.dataTree.getElementById(id); if (!el){ throw new Error(`Элемент с id = ${_id} не найден и не может быть добавлен`) } let self = this; if (this.onlyOne) { this.replace(_id, max_len); return } let has_already = this.elements_id.filter(function (el) { return self.dataTree.isChild(el, id) }); if (has_already.length || (this.elements_id).indexOf(Number(id)) != -1) { //TODO: do popup messages return; } let not_valid = this.elements_id.filter(function (el) { return self.dataTree.isChild(id, el) }); not_valid.forEach(function (el) { self._removeById(el); }); this._addElementToHtml(id, max_len); } }