var EXPO = EXPO || {}; //isolated namespace EXPO.events = EXPO.events || {}; if (EXPO.events.feed) { console.warn('WARNING: EXPO.eventsFeed is already defined!'); } else { EXPO.events.feed = (function () { // variables var that = {}; //default module setting that.opt = {}; //dependence's var com = EXPO.common; //private var Filter = function (opt) { this.opt = opt; this.DOMbody = document.getElementById(opt.bodyId); }, /** * make ajax GET request and launch handler if exist or return data * @param {Object|string} dataToSend * @param {string} url * @param {function} handler - function to execute when task is ready */ getRequest = function (dataToSend,url,handler) { if(!dataToSend){ dataToSend = ''; } $.ajax({ type: 'GET', url: url, data:dataToSend, success: function(data) { if(typeof handler == 'function'){ handler(data); } else{ return data; } } }); }, /** * rename name of property of an object/ Check for the old property name to avoid a ReferenceError in strict mode. * @param {Object} obj object to rename its properties * @param {string} oldName * @param {string} newName * @returns {renameProperty} */ renameProperty = function (obj,oldName, newName) { if (obj.hasOwnProperty(oldName)) { obj[newName] = obj[oldName]; } return this; }, /** * analogue of Array.length but for object instance * @param {Object} obj - Object to count its method * @returns {number} */ getObjectLength = function (obj) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) size++; } return size; }, $waiter = $('.wait-ajax.absolute'), Json2URI = function (jsonObj) { var str = Object.keys(jsonObj).map(function(key){ return encodeURIComponent(key) + '=' + encodeURIComponent(jsonObj[key]); }).join('&'); return ('?'+str); }; // methods Filter.prototype = { show: function () { //$(this.DOMbody).show(); $(this.DOMbody).slideDown(); }, hide: function () { $(this.DOMbody).hide(); //$(this.DOMbody).slideUp(); } }; // places and subject modals /** * Constructor for modal window 'select subject' * @param {Object} options * @constructor */ var SubjectModal = function (options) { /** * options init * @type {Object} */ this.opt = options; var self = this, index = 0, $subjWrap = $('#' + self.opt.subjectTriggerWrapId), $topicBox, modalId = self.opt.id, $modal = $('#' + modalId), $checkBox = $('.csb-menu-input', $modal), $selectedItemsWrap = $('#'+this.opt.selectedItemsContainer, $modal), setDefault = self.opt.defaultOn, applyBtnClass = self.opt.applyBtnClass, $modalTrigger = $('#' + self.opt.modalTrigger), DOMfilterBox = document.getElementById(self.opt.bodyId), /** * executed after render of modal Window * @function */ afterRenderHandler = function () { $waiter.hide(); }, $waiter = $('.wait-ajax.absolute'); /** * this modal window DOM Instance * @type {*|jQuery|HTMLElement} */ this.$modalInst = $('#' + modalId); /** * clones of tags for selected(checked) subject (powered by dna.js objects: see http://dnajs.org/) * in modal window * @type {Object} */ this.itemsSelected = {}; /** * clones of tags for selected(checked) subject (powered by dna.js objects: see http://dnajs.org/) * on the page itself * @type {Object} */ this.tagsBoxItems = {}; /** * clones of sublist of selected(checked) subject (powered by dna.js objects: see http://dnajs.org/) * @type {Object} */ this.sublist = {}; /** * Jquery object of filtering input (autocomplete input) * @type {*|jQuery|HTMLElement} */ this.$inputFilter = $('#' + self.opt.filterInputId); /** * label span element that contain short description for active filter * @type {*|jQuery|HTMLElement} */ this.$label = $(document.getElementById(this.opt.labelId)); this.$selectedItemsWrap = $selectedItemsWrap; /** * flag for management of turn of asynchronous requests * @type {boolean} */ this.isReceived = true; $(function () { // topic checkbox selected event $('.topicChecks', $subjWrap).on('change', function () { if ($(this).prop('checked')) { self._setVisible($(this).val()); } else { self._setUnvisible($(this).val()); } }); // selected topic by default self.opt.defaultOn[] for (index = 0; index < setDefault.length; index++) { $topicBox = $('#' + setDefault[index]) $topicBox.prop('checked', true); $topicBox.trigger('change'); } //modal list and sublist behavior $modal.on('click', 'a.trigger', function () { var name = $(this).attr('data-name'), id = $(this).attr('data-id'), tmplId = $(this).attr('data-template-id'), $sublist = $(this).siblings('.dna-container'); // no more than once execution if ($(this).attr('data-sub') == 'true') { if ($(this).parent().hasClass('level1')) { if (!$sublist.children().length) { $waiter.show(); self._renderSublist({name: name, id: id}, tmplId, afterRenderHandler); $(this).parent().addClass('active'); } else { //slideUp & Down stuff self._slideToggle($sublist, $(this).parent()); } } } return false; }); // modal theme checkbox change behavior $checkBox.on('change', function (event, param) { var checkboxId = $(this).attr('id'), $label = $(this).closest('.custom-radio-check'), $parent = $(this).closest('.level'), $parentCheckBox = $parent.parent().closest('.level').children('.custom-radio-check').find('.csb-menu-input'), $sublist = $parent.children('.sublist'); if (!param) { if ($label.hasClass('active')) { $label.removeClass('active'); } else { $label.addClass('active'); } if (this.checked) { var text = $(this).closest('.level').find('.trigger').first().text(), tplObj = {'text': text, 'id': checkboxId}; //tags field logic if (!$selectedItemsWrap.hasClass('visible')) { $selectedItemsWrap.addClass('visible'); } self._addTag(checkboxId, tplObj); // proper selection and selection group logic if ($sublist.length) { $('.csb-menu-input', $sublist).each(function () { var thisId = this.getAttribute('id'), tagText = $(this).closest('.level').find('.trigger').first().text(), DOMlabel = com.closest(this, 'custom-radio-check'); this.checked = true; self._destroyTag(thisId); com.addClass(DOMlabel, 'active'); }); } else { $parent = $parent.parent().closest('.level') // if checked items count equals all items count then parent item is checked and tags for children - deleted if ($('.csb-menu-input', $parent.find('.sublist')).length == $('.csb-menu-input:checked', $parent.find('.sublist')).length) { var parentId = $parentCheckBox[0].getAttribute('id'), parentText = $parentCheckBox.closest('.level').find('.trigger').first().text(), DOMlabel = com.closest(this, 'custom-radio-check'), DOMParentLabel = com.closest(DOMlabel.parentNode.parentNode, 'level'), parentObj = {'text': parentText, 'id': parentId}; $('.csb-menu-input:checked', $parent.find('.sublist')).each(function () { self._destroyTag(this.getAttribute('id')); }); $parentCheckBox.prop('checked', true); com.addClass($(DOMParentLabel).find('.custom-radio-check')[0], 'active'); //$parentCheckBox.trigger('change',['true']); self._addTag(parentId, parentObj); } } //!uncheck event } else { self._destroyTag(checkboxId); if (!$selectedItemsWrap.children('.dna-clone').length) { $selectedItemsWrap.removeClass('visible'); } //uncheck all sublist items while parent item is unchecked if ($sublist.length) { //destroy all tags for sublist items $('.csb-menu-input', $sublist).each(function () { var thisId = $(this).attr('id'), DOMlabel = com.closest(this, 'custom-radio-check'); this.checked = false; com.removeClass(DOMlabel, 'active'); self._destroyTag(thisId); }); $sublist.addClass('hidden'); $parent.removeClass('active'); } else { // parent item is unchecked and tags for every children item are made if ($parentCheckBox.length && $parentCheckBox[0].checked) { var DOMlabel = com.closest($parentCheckBox[0], 'custom-radio-check'), DOMParentItem = com.closest(DOMlabel, 'level'), DOMSublist = DOMParentItem.querySelector('.sublist'); $parentCheckBox.prop('checked', false); com.removeClass(DOMlabel, 'active'); self._destroyTag($parentCheckBox.attr('id')); // checks children items $('.csb-menu-input:checked', DOMSublist).each(function () { var id = this.getAttribute('id'), tagText = com.closest(this, 'level').querySelector('.trigger').textContent, tagObj = {'text': tagText, 'id': id}; self._addTag(id, tagObj); }); } } } } }); //delete tag behavior $('.' + self.opt.deleteTagClass, $modal).on('click', function (e) { e.stopPropagation(); var checkboxId = $(this).attr('data-checkbox-id'), $uncheckBoxes = $('#' + checkboxId); $uncheckBoxes.prop('checked', false); $uncheckBoxes.trigger('change'); self._refreshLabel(); if (!$selectedItemsWrap.children('.dna-clone').length) { $selectedItemsWrap.removeClass('visible'); } return false; }); $('.del-on-page').on('click',function () { var dataCheckboxId = $(this).attr('data-checkbox-id'); $('.' + self.opt.deleteTagClass+'[data-checkbox-id="'+dataCheckboxId+'"]', $modal).trigger('click'); }); self._autocompleteInit(); $('.' + applyBtnClass, $modal).on('click', function () { self.applyHandler(this); return false; }); // кнопка "очистить параметры" $('.'+self.opt.clearAllButtonClass,$modal).on('click', function (e) { e.preventDefault(); self.resetList(); return false; }); }); }; /** * methods * @type {{_getAjax: Function, _setVisible: Function, _setUnvisible: Function, _checkCheckBox: Function, check: Function, _autocompleteInit: Function, _renderSublist: Function, _loadParentTree: Function, _destroyTag: Function, _addTag: Function, _slideToggle: Function, resetList: Function, applyHandler: Function}} */ SubjectModal.prototype = { /** * get ajax response when want sublists * @param {Object|sting} dataToSend * @param {function} handler - fires after request is complete * @private */ _getAjax: function (dataToSend, handler) { var self = this; if (!dataToSend) { dataToSend = ''; } $waiter.css({display: 'block'}); $.ajax({ type: 'GET', url: self.opt.ajaxUrl, data: dataToSend, success: function (data) { if (typeof handler == 'function') { $waiter.hide(); handler(data); } else { return data; } } }); }, /** * filter list accordingly to checked checkbox in 'select type' part of modal * @param {string} type * @private */ _setVisible: function (type) { var self = this; $('.' + type, self.$modalInst).addClass('visible'); }, /** * filter list accordingly to checked checkbox in 'select type' part of modal * @param {string} type * @private */ _setUnvisible: function (type) { var self = this, $li = $('.' + type, self.$modalInst); $li.find('input[type="checkbox"]').each(function () { var $this = $(this); if ($this.prop('checked')) { $this.prop('checked', false); $this.trigger('change'); } }); $li.find('.dna-container').each(function () { if ($(this).children().length) { $(this).addClass('hidden'); } }); $li.removeClass('visible'); }, /** * check particular checkbox input * @param {string} id * @param {string} name * @private */ _checkCheckBox: function (id, name) { var self = this, $chckBox; if (name == 'th') { $chckBox = $('#tid_' + self.opt.prefix + id, self.$modalInst); } else if (name == 'tg') { $chckBox = $('#tgid_' + self.opt.prefix + id, self.$modalInst); } if ($chckBox.length && !$chckBox.prop('checked')) { $chckBox.prop('checked', true); $chckBox.trigger('change'); } }, /** * check particular checkbox input * @param {string} id * @param {string} name * @public */ check: function (id, name) { var self = this, $chckBox; if (name == 'th') { $chckBox = $('#tid_' + self.opt.prefix + id, self.$modalInst); } else if (name == 'tg') { $chckBox = $('#tgid_' + self.opt.prefix + id, self.$modalInst); } if ($chckBox.length) { $chckBox.prop('checked', true); $chckBox.trigger('change'); $chckBox.parent().addClass('active'); } }, /** * initiliazing and setup autocomplete field for subject list * @private */ _autocompleteInit: function () { var self = this, dataObj, text, form = self.$inputFilter.attr('data-form'), index, $completeWrap = $('#' + self.opt.autoCompleteId), firstComplete = true, selectTag = function (event, ui) { //check of repeating execution $waiter.show(); var firstTime = true; for (var prop in self.sublist) { for (var prop2 in self.sublist[prop]) { if (prop2 == ui.item.value) { firstTime = false; } } } if ($('#tid_' + self.opt.prefix + ui.item.value + '[name="' + ui.item.name + '"]:checked').length) { firstTime = false; } // ban of repeating execution if (firstTime) { // konec var $checkbox = $('#tid_' + self.opt.prefix + ui.item.value + '[name="' + ui.item.name + '"]'), requestObj, requestName, treeLoadHandler = function (data) { // make checkboxes selected after loading if (getObjectLength(data)) { self._loadParentTree(data, function () { self._checkCheckBox(ui.item.value, 'tg'); $waiter.hide(); }); } else { $waiter.hide(); console.warn() } }; // load tree related to selected item if (!$checkbox.length) { requestObj = { id: ui.item.value, name: ui.item.name }; getRequest(requestObj, self.opt.getParentUrl, treeLoadHandler); } else { $waiter.hide(); $checkbox.prop('checked', true); $checkbox.trigger('change'); } } }, requestHandler = function (data) { dataObj = data; for (index = 0; index < dataObj.length; ++index) { renameProperty(dataObj[index], 'text', 'label'); } for (index = 0; index < dataObj.length; ++index) { renameProperty(dataObj[index], 'id', 'value'); } if (!self.$inputFilter.hasClass('ui-autocomplete-input')) { self.$inputFilter.placeComplete({ source: dataObj, minLength: 0, appendTo: $completeWrap, select: function (event, ui) { self.$inputFilter.val(''); self.$inputFilter.trigger('keyup'); selectTag(event, ui); event.preventDefault(); // return ui.label; } }); self.$inputFilter.placeComplete('search', ""); firstComplete = false; } else { self.$inputFilter.placeComplete('search', ""); } }; // var newData = ['banan','banan2','banan3','banan4','banan5']; self.$inputFilter.attr('autocomplete', 'on'); self.$inputFilter.on('keyup', function (event) { text = $(this).val(); event.stopImmediatePropagation(); if (text.length > 2 && firstComplete) { getRequest({'term': text, 'form': form}, self.opt.autoCompleteUrl, requestHandler); firstComplete = false; } else if (text.length == 0 && !firstComplete) { if (self.$inputFilter.hasClass('ui-autocomplete-input')) { self.$inputFilter.placeComplete("destroy"); firstComplete = true; } } return false; }).click(function () { return false; }); }, /** * render first level sublist * @param {Object} dataObj * @param {number|string} tmplId * @param {function} handler * @private */ _renderSublist: function (dataObj, tmplId, handler) { var self = this, index = 0, template = tmplId + '-sub', ajaxHandler = function (data) { if (data.length) { self.sublist[template] = {}; // for dna.clone definition see dnajs.org for (index; index < data.length; index++) { self.sublist[template][data[index].id] = dna.clone(tmplId, data[index]); } handler(data.length); } else { $waiter.hide(); } }; self._getAjax(dataObj, ajaxHandler); }, /** * if there is no children element in list, loads list that is parent to children element * @param {Object} data * @param {number|string} handler * @param {function} counter * @private */ _loadParentTree: function (data, handler, counter) { var self = this, dataObj = data, optObj, sublistTemplateId, nestedObj, nestedSublistTemplateId, /** * makes request in order to recieve children list information fires after request for parent list * @param {number} length * @function */ handlerParent = function () { $waiter.hide(); counter || counter === 0 ? handler(counter) : handler(); }; $waiter.show(); optObj = { name: dataObj.name, id: dataObj.id }; sublistTemplateId = $('#tid_' + self.opt.prefix + dataObj.id).closest('.level').children('.trigger').attr('data-template-id'); self._renderSublist(optObj, sublistTemplateId, handlerParent); }, /** * destroy tag and clear tags block.for dna.clone definition see dnajs.org * @param {string} checkboxId * @private */ _destroyTag: function (checkboxId, outer) { var self = this; if (self.itemsSelected[checkboxId]) { dna.destroy(self.itemsSelected[checkboxId]); } if (self.tagsBoxItems[checkboxId]) { dna.destroy(self.tagsBoxItems[checkboxId]); } }, /** * for dna.clone definition see dnajs.org * @param {number} checkboxId * @param {Object} tplObj * @private */ _addTag: function (checkboxId, tplObj) { var self = this; self.itemsSelected[checkboxId] = dna.clone(self.opt.selectedItemTemplate, tplObj); self.tagsBoxItems[checkboxId] = dna.clone(self.opt.tagsBoxId, tplObj); self._refreshLabel(); if(getObjectLength(self.itemsSelected)){ $(EXPO.events.feed.DOMapplyButton).show(); $(EXPO.events.feed.DOMhint).hide(); } }, /** * hide or show sublists according active selected link * @param {*|jQuery|HTMLElement} $sublist * @param {*|jQuery|HTMLElement} $this * @private */ _slideToggle: function ($sublist, $this) { if ($sublist.hasClass('hidden')) { $sublist.removeClass('hidden'); $this.addClass('active'); } else { $sublist.addClass('hidden').find('ul').addClass('hidden'); $this.removeClass('active'); } }, /** * reset all selected items, uncheck all selected checkboxes * @public */ resetList: function () { var self = this; for (var key in self.itemsSelected) { if (self.itemsSelected.hasOwnProperty(key)) { $('#'+key, self.$selfContainer).prop('checked', false).closest('.custom-radio-check').removeClass('active'); dna.destroy(self.itemsSelected[key]); dna.destroy(self.tagsBoxItems[key]); } } $('.level.active',this.$modal).removeClass('active'); this._refreshLabel(); this.$selectedItemsWrap.removeClass('visible'); }, /** * render label text, if there is no selected element then text will be default * @private */ _refreshLabel: function () { var oLength = this.$selectedItemsWrap.children().length; if (oLength){ this.$label.text(this.$label.attr('data-selected')); }else{ this.$label.text(this.$label.attr('data-default')); } }, // кнопка применить applyHandler: function (it) { EXPO.events.feed.modalWindow.close(); }, /** * select particular item and render its tag and check checkbox * @param {Object} item * @public */ selectTag:function (item) { //check of repeating execution var firstTime = true, self = this, waitHandler = function () { self.isReceived = false; if(!item.children){ for (var prop in self.itemsSelected) { if (prop == 'tid_'+ self.opt.prefix+item.id){ firstTime = false; } } if($('#tid_'+ self.opt.prefix+item.id+':checked').length){ firstTime = false; } if(firstTime){ self.check(item.id, item.name); self.isReceived = true; }else{ $('#tid_'+ self.opt.prefix + item.id).prop('checked', true); $('#tid_'+ self.opt.prefix + item.id).trigger('change'); self.isReceived = true; } }else{ if($('#tgid_'+ self.opt.prefix+item.children.id).length){ firstTime = false; } //Если выбран родитель if($('#tid_'+ self.opt.prefix+item.id+':checked').length){ firstTime = false; } if(firstTime) { self._loadParentTree({name: item.name, id: item.id}, function () { self.check(item.children.id, item.children.name); self.isReceived = true; }); }else if(!$('#tgid_'+ self.opt.prefix+item.id+':checked').length){ $('#tgid_'+ self.opt.prefix + item.children.id).prop('checked', true); $('#tgid_'+ self.opt.prefix + item.children.id).trigger('change'); self.isReceived = true; } } }; this.wait(waitHandler); }, /** * waits so far the previous request will be executed and execute a method * @param {function} method * @param {Object|Array} args * @public */ wait:function(method, args) { var self = this, waitImages, waitHandler = function(self, method, args) { if (self.isReceived) { if (args) { method(args); } else{ method(); } clearInterval(waitImages); } }; waitImages = setInterval(function() {waitHandler(self, method, args)}, 100); } }; /** * Constructor for modal window 'select place' * @param {Object} options * @constructor */ var PlacesModal = function (options) { /** * object properties * @type {Object} */ this.opt = options; var self = this, $modal = $('#' + self.opt.id), $checkBox = $('input[type="checkbox"]', $modal), $selectedItemsWrap = $('#'+this.opt.selectedItemsContainer, $modal), DOMTagsWrapper = $('#'+this.opt.selectedItemsContainer, $modal)[0], $modalTrigger = $('#' + self.opt.modalTrigger), applyBtnClass = self.opt.applyBtnClass, idPrefix = 'id_', DOMfilterBox = document.getElementById(self.opt.bodyId), /** * set trigger link text under the search field * @function */ triggerSetText = function () { var selectedString, cutLength = 16; }; /** * current template instances * @type {Object} */ this.curDNA = {}; /** * place modal list items that had selected * in modal window * @type {Object} */ this.itemsSelected = {}; /** * place modal list items that had selected * on page itself * @type {Object} */ this.tagsBoxItems = {}; this.selectedWrap = $selectedItemsWrap; this.$selfContainer = $modal; this.$modal = $modal; this.idPrefix = idPrefix; /** * flag for management of turn of asynchronous requests * @type {boolean} */ this.isReceived = true; /** * label span element that contain short description for active filter * @type {*|jQuery|HTMLElement} */ this.$label = $(document.getElementById(this.opt.labelId)); /** * Jquery object of filtering input (autocomplete input) * @type {*|jQuery|HTMLElement} */ this.$inputFilter = $('#' + self.opt.filterInputId); $(function () { self._autocompleteInit(); $modal.on('click', 'a.trigger', function () { var name = $(this).attr('data-name'), id = $(this).attr('data-id'), that = this, tmplId = $(this).attr('data-template-id'), $sublist = $(this).siblings('.dna-container'), afterRenderHandler = function (elem, data) { var DOMParent = com.closest(that, 'level'), DOMParentCheckbox = DOMParent.querySelector('.csb-menu-input'); $('.csb-menu-input', $sublist).each(function () { var DOMCheckboxWrap = com.closest(this, 'custom-radio-check'); if (!this.selected) { if (DOMParentCheckbox.checked) { this.checked = true; com.addClass(DOMCheckboxWrap, 'active'); } } }); $waiter.hide(); }; // no more than once execution if ($(this).attr('data-sub') == 'true') { if ($(this).parent().hasClass('level1')) { if (!$sublist.children().length) { $waiter.show(); self._renderSublist({name: name, id: id}, tmplId, afterRenderHandler); } else { //slideUp & Down stuff self._slideToggle($sublist, $(this).parent()); } } else if ($(this).parent().hasClass('level2')) { if (!$sublist.children().length) { self._renderNested({name: name, id: id}, afterRenderHandler, tmplId, id); $(this).parent().addClass('active'); } else { //slideUp & Down stuff self._slideToggle($sublist, $(this).parent()); } } } return false; }); $checkBox.on('change', function (event, param) { var id = this.getAttribute('id'), fakeCheckboxClass = 'custom-radio-check', fakeCheckbox = com.closest(this, fakeCheckboxClass), itemClass = 'level', activeClass = 'active', sublistClass = 'sublist', checkboxClass = 'csb-menu-input', highestItemClass = 'level1', tagClass = 'csb-selected', tagButtonClass = 'csbs-del', triggerClass = 'trigger', tagIdAttribute = 'data-checkbox-id', DOMParentRow = com.closest(this, itemClass), DOMParentItem = com.hasClass(DOMParentRow, highestItemClass) == false?com.closest(DOMParentRow.parentNode, itemClass):DOMParentRow, DOMParentCheckbox = DOMParentItem.querySelector('.'+checkboxClass), DOMSublist = DOMParentItem.querySelector('.'+sublistClass), DOMSublistInner = DOMParentRow.querySelector('.'+sublistClass), DOMHighestItem = com.closest(this, highestItemClass), DOMHighestCheckbox = DOMHighestItem.querySelector('.'+checkboxClass), DOMHighestSublist = DOMHighestItem.querySelector('.'+sublistClass), selectSublist = function (it) { var DOMParentItem = com.closest(it, itemClass) || this, DOMSublist = DOMParentItem.querySelector('.'+sublistClass); $('.'+checkboxClass, DOMSublist).each(function () { selectItem(this); }); }, unSelectSublist = function (it) { var DOMParentItem = com.closest(it, itemClass) || this, DOMSublist = DOMParentItem.querySelector('.'+sublistClass); $('.'+checkboxClass, DOMSublist).each(function () { unSelectItem(this); }); }, selectParent = function (it) { var DOMParentRow = com.closest(it, itemClass), DOMParentItem; if(com.hasClass(DOMParentRow,'level1')){ DOMParentItem = DOMParentRow; }else{ DOMParentItem = com.closest(DOMParentRow.parentNode, itemClass); } com.addClass(DOMParentItem.querySelector('.'+fakeCheckboxClass), activeClass); DOMParentItem.querySelector('.'+checkboxClass).checked = true; //it.selected = true; }, unSelectParent = function (it) { var DOMParentRow = com.closest(it, itemClass), DOMParentItem = com.closest(DOMParentRow.parentNode, itemClass) || DOMParentRow; com.removeClass(DOMParentItem.querySelector('.'+fakeCheckboxClass), activeClass); DOMParentItem.querySelector('.'+checkboxClass).checked = false; //it.checked = false; }, selectItem = function (it) { var itFakeCheckbox = com.closest(it, fakeCheckboxClass); com.addClass(itFakeCheckbox, activeClass); it.checked = true; com.addClass(DOMParentItem,activeClass); com.removeClass(DOMSublist,'hidden'); }, unSelectItem = function (it) { var itFakeCheckbox = com.closest(it, fakeCheckboxClass), DOMitem = com.closest(it, itemClass); com.removeClass(itFakeCheckbox, activeClass); it.checked = false; // if there is children items if(DOMitem.querySelector('.'+sublistClass) && !com.hasClass(DOMitem,highestItemClass)){ unSelectSublist(it); } }, allChildrenSelected = function () { //var DOMselected = DOMSublist.querySelectorAll('.'+checkboxClass+':checked'), var DOMSublistParent = com.closest(DOMSublist,sublistClass), $selected = $(DOMSublist).children('li').children('.'+fakeCheckboxClass).find('.'+checkboxClass+':checked'), selectedCount = $selected.length, //allCount = DOMSublist.querySelectorAll('.'+checkboxClass).length; allCount = $(DOMSublist).children('li').children('.'+fakeCheckboxClass).find('.'+checkboxClass).length; if(allCount == selectedCount && selectedCount != 0){ return true; } else{ return false; } }, allHighestSelected = function () { //var DOMselected = DOMSublist.querySelectorAll('.'+checkboxClass+':checked'), var $selected = $(DOMHighestSublist).children('li').children('.'+fakeCheckboxClass).find('.'+checkboxClass+':checked'), selectedCount = $selected.length, allCount = $(DOMHighestSublist).children('li').children('.'+fakeCheckboxClass).find('.'+checkboxClass).length; if(allCount == selectedCount && selectedCount != 0){ return true; } else{ return false; } }, parentSelected = function () { var parentCheckbox = DOMParentItem.querySelector('.'+checkboxClass); if(parentCheckbox.checked){ return true; }else{ return false; } }, // Функционал добавления тегов: если есть в панели выбранный элемент либо его дочерние то удалить эти эдементы; refreshTags = function (it) { var DOMSublist = com.closest(it,sublistClass); var DOMItem = com.closest(it,itemClass); var DOMSublistInner = DOMItem.querySelector('.'+sublistClass); var DOMAllTags = DOMTagsWrapper.querySelectorAll('.'+tagClass); var ARRsublist; var ARRsublistChildren = DOMSublist.querySelector('.'+sublistClass)?$('.'+checkboxClass+':checked',DOMSublist.querySelector('.'+sublistClass)):null; var ARRsublistChildrenLength = ARRsublistChildren?ARRsublistChildren.length:null; var ARRSublistIds = []; var ARRAllTagsIds = []; var allTagsLength = 0; var sublistIdsLength = 0; var itId = it.getAttribute('id'); var i = 0, j= 0, t= 0, tmp, k = 0; var tagId; var tagText = DOMParentRow.querySelector('.'+triggerClass).innerHTML; // если есть дочерние элементы if(DOMSublistInner){ ARRsublist = $(DOMSublistInner).children('li').children('.'+fakeCheckboxClass).find('.'+checkboxClass+':checked') //получаем массив id жлементовЮ для которых есть тег for(k; k < ARRsublist.length; k++){ tmp = ARRsublist[k].getAttribute('id'); ARRSublistIds.push(tmp); } //очистк for(t; t 2 && firstComplete) { $waiter.show(); getRequest({'term': text, 'form': form}, self.opt.autoCompleteUrl, requestHandler); firstComplete = false; } else if (text.length == 0 && !firstComplete) { if (self.$inputFilter.hasClass('ui-autocomplete-input')) { self.$inputFilter.autocomplete("destroy"); firstComplete = true; } } return false; }).click(function () { return false; }); }, /** * loads and shows list tree related to selected id * @param {Object} data - is JSON object with information about parent elements. * @param {function} handler - callback function * @param {number} counter * @private */ _loadParentTree: function (data, handler, counter) { var self = this, dataObj = data, optObj, sublistTemplateId, nestedObj, nestedSublistTemplateId, $midleLevelCheckbox = $('#id_' + self.opt.prefix + dataObj.id), /** * makes request in order to recieve children list information fires after request for parent list * @param {number} length * @function */ handlerNested = function (length) { var $checkbox = $('#id_' + self.opt.prefix + dataObj.id), index = 0, afterAll = function (number) { $waiter.hide(); index++ if(index == number){ counter||counter===0?handler(counter):handler(); } }; $waiter.hide(); if ($checkbox.length && getObjectLength(self.curDNA[sublistTemplateId + '-sub']) == length) { nestedObj = { name: dataObj.name, id: dataObj.id }; $waiter.show(); nestedSublistTemplateId = $('#id_' + self.opt.prefix + dataObj.id).closest('.level').children('.trigger').attr('data-template-id'); self._renderNested(nestedObj, afterAll, nestedSublistTemplateId, dataObj.id); } }, /** * @function */ handlerParent = function () { $waiter.hide(); counter || counter === 0 ? handler(counter) : handler(); }; $waiter.show(); //if element has parent element if (dataObj.hasOwnProperty('parent')) { //if checbox is existed if ($midleLevelCheckbox.length) { nestedObj = { name: dataObj.name, id: dataObj.id }; nestedSublistTemplateId = $midleLevelCheckbox.closest('.level').children('.trigger').attr('data-template-id'); self._renderNested(nestedObj, function () { $waiter.hide(); handler(); }, nestedSublistTemplateId, dataObj.id); } else { optObj = { name: dataObj.parent.name, id: dataObj.parent.id }; sublistTemplateId = $('#id_' + self.opt.prefix + dataObj.parent.id).closest('.level').children('.trigger').attr('data-template-id'); self._renderSublist(optObj, sublistTemplateId, handlerNested); } } else { optObj = { name: dataObj.name, id: dataObj.id }; sublistTemplateId = $('#id_' + self.opt.prefix + dataObj.id).closest('.level').children('.trigger').attr('data-template-id'); self._renderSublist(optObj, sublistTemplateId, handlerParent); } }, applyHandler: function (it) { EXPO.events.feed.modalWindow.close(); }, /** * render label text, if there is no selected element then text will be default * @private */ _refreshLabel: function () { var oLength = this.selectedWrap.children().length; if (oLength){ this.$label.text(this.$label.attr('data-selected')); }else{ this.$label.text(this.$label.attr('data-default')); } } }; /////////////////////////// //инициализация общих свойств that.init = function (options) { // settings extending $.extend(this.opt, options); // begin of initialization var self = this, submitHandler = function () { $(self.DOMform).find('input[name="~~name~~"]').remove(); }; if(this.opt.searchData != 'None' && this.opt.searchData){ this.previousSearch = JSON.parse(this.opt.searchData) } this.DOMform = document.getElementById(this.opt.formId); this.DOMhint = document.getElementById(this.opt.filter.hintId); $(this.DOMform).on('submit', function () { submitHandler(); }); $.widget( "custom.placeComplete", $.ui.autocomplete,{ _renderItem: function( ul, item ) { return $( "
  • " ) .append( $( "" ).text( item.label) ) .append(' ('+item.cat+')') .appendTo( ul ); } }); this.DOMapplyButton = document.getElementById(this.opt.applyButtonId); this.filterPane = new Filter(this.opt.filter); $('#' + this.opt.filter.buttonId).on('click', function () { if (com.hasClass(this, self.opt.activeClass)) { com.removeClass(this, self.opt.activeClass); self.filterPane.hide(); } else { com.addClass(this, self.opt.activeClass); self.filterPane.show(); } return false; }); $('#'+self.opt.bodyId+' .' + self.opt.modalTriggerClass).on('click', function (event) { event.preventDefault(); self.modalWindow.pullData(this.getAttribute('href')); self.modalWindow.open(); return false; }); //кнопка применить $('#'+self.opt.applyButtonId).on('click', function () { $(self.DOMform).submit(); return false; }); //modal //модальное окно this.modalWindow = new com.Modal(self.opt.modal); //modal windows this.placesModal = new PlacesModal(self.opt.place); this.subjModal = new SubjectModal(self.opt.subject); // заполнение полей предыдущими значениями $(function () { if(self.previousSearch.inputs.length){ $(self.DOMhint).hide(); for (var i = 0; i < self.previousSearch.inputs.length; i++) { // окно выбора тематики if (self.previousSearch.inputs[i].name == 'th'){ self.subjModal.selectTag(self.previousSearch.inputs[i]); // окно выбора мест } else if (self.previousSearch.inputs[i].name == 'area'){ if(self.previousSearch.inputs[i].children && self.previousSearch.inputs[i].children.children){ self.placesModal.selectTag(self.previousSearch.inputs[i].children.children); }else if (self.previousSearch.inputs[i].children){ self.placesModal.selectTag(self.previousSearch.inputs[i].children); } else if(self.previousSearch.inputs[i]){ self.placesModal.selectTag(self.previousSearch.inputs[i]); } } } }else{ $(self.DOMhint).fadeIn(); } //Если выбраны фильтры то появляется кнопка "применить" if(getObjectLength(self.placesModal.itemsSelected) || getObjectLength(self.subjModal.itemsSelected) ){ $(self.DOMapplyButton).show(); } }); }; return that; }()); }