diff --git a/apps/country/manager.py b/apps/country/manager.py index b0d104de..1b6334e9 100644 --- a/apps/country/manager.py +++ b/apps/country/manager.py @@ -133,7 +133,7 @@ class AreaManager(TranslationManager): result = cache.get(key) else: model = self.model - result = list(model.objects.language().filter()) + result = set(model.objects.language().filter()) #result.sort(key=lambda x: len(x.expos()), reverse=True) cache.set(key, result, self.cache_time) return result diff --git a/static/client/js/_modules/block.search.js b/static/client/js/_modules/block.search.js index b3192ca8..d602ebf6 100644 --- a/static/client/js/_modules/block.search.js +++ b/static/client/js/_modules/block.search.js @@ -3,2402 +3,2399 @@ var EXPO = EXPO || {}; //isolated namespace // module requires JQuery library, dna.js template engine (http://dnajs.org/) // protection against duplication of a module code if (EXPO.searchBlock){ - console.warn('WARNING: EXPO.searchBlock is already defined!'); + console.warn('WARNING: EXPO.searchBlock is already defined!'); }else{ - EXPO.searchBlock = (function() { - - // variables - - var that = {}; - /** - * default module setting - * @type {{place: {id: string, selectedItemTemplate: string, ajaxUrl: string}, subject: {id: string, ajaxUrl: string}}} - */ - that.settings = { - place:{ - id:'pw-place', - selectedItemTemplate:'csb-selected', - ajaxUrl: window.location.protocol + '//hit.expomap.ru/search-form/' - }, - subject:{ - id:'pw-subj', - ajaxUrl: window.location.protocol + '//hit.expomap.ru/search-form/' - } - }; - that.lang ={}; - //dependence's - // module require dna.js tiny templating engine - var common = EXPO.common; - //private - - var Json2URI = function (jsonObj) { - var str = Object.keys(jsonObj).map(function(key){ - return encodeURIComponent(key) + '=' + encodeURIComponent(jsonObj[key]); - }).join('&'); - return ('?'+str); - }, - /** - * 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 - * @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; - }, - /** - * getSelectedToString returns string that contains selected values in both modal windows. values separated by ',' - * @param {string} container - * @param {number} cutLength - length to cut off string - * @returns {string} string that is cutted off - */ - getSelectedToString = function(container, cutLength){ - var $container = $('#'+container), - index = 0, - stringToReturn = '', - closingSymbol = '...', - closerText = EXPO.searchBlock.settings.closerText, - closerTextSingle = EXPO.searchBlock.settings.closerTextSingle, - dividerSymbol = ''; - $element = $container.find('.csbs-text'); - if($element.length > 2){ - if($element.eq(0).text().length < cutLength){ - dividerSymbol = ', '; - stringToReturn += $element.eq(0).text() + dividerSymbol + $element.eq(1).text() + closerText.replace('_',$element.length-2); - }else{ - stringToReturn += $element.eq(0).text() + closerText.replace('_',$element.length-1); - } - - } else if($element.length == 2){ - if(($element.eq(0).text().length+$element.eq(1).text().length) < cutLength){ - dividerSymbol = ', '; - // если даже 2 первых слова вместе меньше чем порог, то не указывать количество позиций - stringToReturn += $element.eq(0).text() + dividerSymbol + $element.eq(1).text()+' '; - - } else if($element.eq(0).text().length < cutLength){ - dividerSymbol = ', '; - stringToReturn += $element.eq(0).text() + dividerSymbol + $element.eq(1).text()+' '; - }else{ - stringToReturn += $element.eq(0).text() + closerTextSingle.replace('_',$element.length-1); - } - }else if($element.length){ - stringToReturn += $element.eq(0).text()+' '; - }else{ - stringToReturn = false; - } - return stringToReturn; - }, - /** - * ajax pending process indicator - * @type {*|jQuery|HTMLElement} индикатор загрузки диалоговых окон - */ - $waiter = $('.wait-ajax.absolute'); - - /** - * 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 = $('.csb-selected-items',$modal), - setDefault = self.opt.defaultOn, - applyBtnClass = self.opt.applyBtnClass, - $modalTrigger = $('#'+self.opt.modalTrigger), - /** - * executed after render of modal Window - * @function - */ - afterRenderHandler = function () { - $waiter.hide(); - - }, - /** - * fill text beneth search field - * @function triggerSetText - */ - triggerSetText = function () { - var selectedString, - cutLength = 16; - if($(window).width() < 1086){ - cutLength = 12; - } - - selectedString = getSelectedToString(self.opt.selectedItemsContainer,cutLength); - if(selectedString && selectedString != '~~text~~' && selectedString != '~~text~~...'){ - $modalTrigger.text(selectedString); - $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).addClass('active'); - }else{ - $modalTrigger.text($modalTrigger.data('default')); - $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).removeClass('active'); - } - }; - - /** - * 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/) - * @type {Object} - */ - this.itemsSelected = {}; - /** - * 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); - 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(this.checked){ - $label.addClass('active'); - 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 = common.closest(this,'custom-radio-check'); - - this.checked = true; - self._destroyTag(thisId); - common.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 =common.closest(this,'custom-radio-check'), - DOMParentLabel = common.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); - common.addClass($(DOMParentLabel).find('.custom-radio-check')[0],'active'); - - //$parentCheckBox.trigger('change',['true']); - self._addTag(parentId,parentObj); - } - } - - //!uncheck event - }else { - $label.removeClass('active'); - 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 = common.closest(this,'custom-radio-check'); - this.checked = false; - - common.removeClass(DOMlabel, 'active'); - self._destroyTag(thisId); - }); - }else{ - // parent item is unchecked and tags for every children item are made - if($parentCheckBox.length && $parentCheckBox[0].checked){ - var DOMlabel = common.closest($parentCheckBox[0],'custom-radio-check'), - DOMParentItem = common.closest(DOMlabel,'level'), - DOMSublist = DOMParentItem.querySelector('.sublist'); - $parentCheckBox.prop('checked', false); - common.removeClass(DOMlabel, 'active'); - self._destroyTag($parentCheckBox.attr('id')); - // checks children items - - $('.csb-menu-input:checked',DOMSublist).each(function () { - var id = this.getAttribute('id'), - tagText = common.closest(this, 'level').querySelector('.trigger').textContent, - tagObj = {'text':tagText,'id':id}; - self._addTag(id,tagObj); - }); - } - } - - } - triggerSetText(); - } - }); - //delete tag behavior - $('.csbs-del', $selectedItemsWrap).on('click', function () { - var checkboxId = $(this).attr('data-checkbox-id'), - $uncheckBoxes = $('#'+checkboxId); - $uncheckBoxes.prop('checked', false); - $uncheckBoxes.trigger('change'); - dna.destroy(self.itemsSelected[checkboxId]); - if(!$selectedItemsWrap.children('.dna-clone').length){ - $selectedItemsWrap.removeClass('visible'); - } - return false; - }); - $('.modal-clear', $modal).on('click', function () { - self.resetList(); - return false; - }); - self._autocompleteInit(); - $('.'+applyBtnClass, $modal).on('click', function () { - self.applyHandler(this); - return false; - }); - // кнопка "очистить параметры" - $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).on('click', function () { - self.resetList(); - EXPO.searchBlock.exhibitionField.clearValue(); - - }); - }); - }; - /** - * 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 - * @param {boolean} strict - if true then select particular checkbox without 'popping' to parent category - * @private - */ - _checkCheckBox: function (id,name) { - var self = this, - $chckBox; - - if(name == 'th'){ - $chckBox = $('#tid_'+id, self.$modalInst); - }else if(name == 'tg'){ - $chckBox = $('#tgid_'+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_'+id, self.$modalInst); - }else if(name == 'tg'){ - $chckBox = $('#tgid_'+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){ - if($('#tid_'+ui.item.value+'[name="'+ui.item.name+'"]:checked').length){ - firstTime = false; - } - } - - } - } - if($('#tid_'+ui.item.value+'[name="'+ui.item.name+'"]:checked').length){ - firstTime = false; - } - // ban of repeating execution - if (firstTime) { // konec - var $checkbox = $('#tid_' + 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',""); - } - - }; - - /** - * the ID value of the timer that is set - */ - self.timeout; - self.$inputFilter.attr('autocomplete', 'on'); - - self.$inputFilter.on('keyup', function (event) { - text = $(this).val(); - event.stopImmediatePropagation(); - clearTimeout(self.timeout); - - if (text.length > 2 && firstComplete){ - self.timeout = setTimeout(function () { - getRequest({'term':text, 'form':form}, self.opt.autoCompleteUrl, requestHandler); - firstComplete = false; - }, 1000); - - }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 ITS Children sublist - * @param {Object} data - current (children) 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_'+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){ - var self = this; - if(self.itemsSelected[checkboxId]){ - dna.destroy(self.itemsSelected[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); - }, - /** - * 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).trigger('change'); - - dna.destroy(self.itemsSelected[key]); - - } - } - $('.level.active',self.$modalInst).removeClass('active'); - self.$selectedItemsWrap.removeClass('visible'); - $(this.$modalInst).find('input:checkbox:checked').prop('checked',false); - - }, - // кнопка применить - applyHandler: function (it) { - $waiter.show(); - }, - /** - * 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_'+item.id){ - firstTime = false; - } - - } - if($('#tid_'+item.id+':checked').length){ - firstTime = false; - } - if(firstTime){ - self.check(item.id, item.name); - self.isReceived = true; - }else{ - $('#tid_' + item.id).prop('checked', true); - $('#tid_' + item.id).trigger('change'); - self.isReceived = true; - - } - }else{ - if($('#tgid_'+item.children.id).length){ - firstTime = false; - } - //Если выбран родитель - if($('#tid_'+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_'+item.id+':checked').length){ - - $('#tgid_' + item.children.id).prop('checked', true); - $('#tgid_' + 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 = $('.csb-selected-items',$modal), - DOMTagsWrapper = $('.csb-selected-items',$modal)[0], - $modalTrigger = $('#'+self.opt.modalTrigger), - applyBtnClass = self.opt.applyBtnClass, - idPrefix = 'id_', - /** - * set trigger link text under the search field - * @function - */ - triggerSetText = function () { - var selectedString, - cutLength = 16; - if($(window).width() < 1086){ - cutLength = 6; - } - selectedString = getSelectedToString(self.opt.selectedItemsContainer,cutLength); - if(selectedString && selectedString != '~~text~~' && selectedString != '~~text~~...'){ - $modalTrigger.text(selectedString); - $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).addClass('active'); - - }else{ - $modalTrigger.text($modalTrigger.data('default')); - $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).removeClass('active'); - - } - }; - /** - * current template instances - * @type {Object} - */ - this.curDNA = {}; - /** - * place modal list items that had selected - * @type {Object} - */ - this.itemsSelected = {}; - 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; - - /** - * 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 = common.closest(that,'level'), - DOMParentCheckbox = DOMParent.querySelector('.csb-menu-input'); - $('.csb-menu-input', $sublist).each(function () { - var DOMCheckboxWrap = common.closest(this,'custom-radio-check'); - if(!this.checked){ - - if(DOMParentCheckbox.checked){ - this.checked = true; - common.addClass(DOMCheckboxWrap,'active'); - } - }else{ - if(!DOMParentCheckbox.checked){ - - this.checked = false; - common.removeClass(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 = common.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 = common.closest(this, itemClass), - - DOMParentItem = common.hasClass(DOMParentRow, highestItemClass) == false?common.closest(DOMParentRow.parentNode, itemClass):DOMParentRow, - DOMParentCheckbox = DOMParentItem.querySelector('.'+checkboxClass), - DOMSublist = DOMParentItem.querySelector('.'+sublistClass), - DOMSublistInner = DOMParentRow.querySelector('.'+sublistClass), - DOMHighestItem = common.closest(this, highestItemClass), - DOMHighestCheckbox = DOMHighestItem.querySelector('.'+checkboxClass), - DOMHighestSublist = DOMHighestItem.querySelector('.'+sublistClass), - - selectSublist = function (it) { - var DOMParentItem = common.closest(it, itemClass) || this, - DOMSublist = DOMParentItem.querySelector('.'+sublistClass); - $('.'+checkboxClass, DOMSublist).each(function () { - selectItem(this); - }); - - }, - unSelectSublist = function (it) { - var DOMParentItem = common.closest(it, itemClass) || this, - DOMSublist = DOMParentItem.querySelector('.'+sublistClass); - $('.'+checkboxClass, DOMSublist).each(function () { - unSelectItem(this); - - }); - - }, - selectParent = function (it) { - var DOMParentRow = common.closest(it, itemClass), - DOMParentItem; - if(common.hasClass(DOMParentRow,'level1')){ - DOMParentItem = DOMParentRow; - }else{ - DOMParentItem = common.closest(DOMParentRow.parentNode, itemClass); - } - - common.addClass(DOMParentItem.querySelector('.'+fakeCheckboxClass), activeClass); - DOMParentItem.querySelector('.'+checkboxClass).checked = true; - - //it.selected = true; - - }, - unSelectParent = function (it) { - var DOMParentRow = common.closest(it, itemClass), - DOMParentItem = common.closest(DOMParentRow.parentNode, itemClass) || DOMParentRow; - - common.removeClass(DOMParentItem.querySelector('.'+fakeCheckboxClass), activeClass); - DOMParentItem.querySelector('.'+checkboxClass).checked = false; - //it.checked = false; - - }, - selectItem = function (it) { - var itFakeCheckbox = common.closest(it, fakeCheckboxClass); - common.addClass(itFakeCheckbox, activeClass); - it.checked = true; - common.addClass(DOMParentItem,activeClass); - common.removeClass(DOMSublist,'hidden'); - - }, - unSelectItem = function (it) { - var itFakeCheckbox = common.closest(it, fakeCheckboxClass), - DOMitem = common.closest(it, itemClass); - common.removeClass(itFakeCheckbox, activeClass); - it.checked = false; - // if there is children items - if(DOMitem.querySelector('.'+sublistClass) && !common.hasClass(DOMitem,highestItemClass)){ - unSelectSublist(it); - } - }, - allChildrenSelected = function () { - //var DOMselected = DOMSublist.querySelectorAll('.'+checkboxClass+':checked'), - var DOMSublistParent = common.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 = common.closest(it,sublistClass); - var DOMItem = common.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){ - self.timeout = setTimeout(function () { - getRequest({'term':text, 'form':form}, self.opt.autoCompleteUrl, requestHandler); - firstComplete = false; - }, 1000); - - }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.({text: "Германия", id: 47, parent: {text: "Европа", id: 4, name: "area"}, name: "co"}) - * @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_'+dataObj.id), - /** - * makes request in order to recieve children list information fires after request for parent list - * @param {number} length - the number of received elements - * @function - */ - handlerNested = function (length) { - var $checkbox = $('#id_'+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_'+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_'+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_'+dataObj.id).closest('.level').children('.trigger').attr('data-template-id'); - self._renderSublist(optObj,sublistTemplateId,handlerParent); - } - - }, - /** - * @param it - * @public - */ - applyHandler: function (it) { - console.log(this); - - }, - _refreshText: function () { - var selectedString, - $modalTrigger = $('#'+this.opt.modalTrigger), - cutLength = 16; - selectedString = getSelectedToString(this.opt.selectedItemsContainer,cutLength); - if(selectedString && selectedString != '~~text~~' && selectedString != '~~text~~...'){ - $modalTrigger.text(selectedString); - $modalTrigger.siblings('.'+this.opt.clearAllButtonClass).addClass('active'); - - }else{ - $modalTrigger.text($modalTrigger.data('default')); - $modalTrigger.siblings('.'+this.opt.clearAllButtonClass).removeClass('active'); - - } - } - }; - - /** - * period selector modal window - * @param {Object} options - * @constructor - */ - var PeriodModal = function (options) { - this.opt = options; - var self = this, - $dateFrom = $('#'+self.opt.dateFrom), - $dateTo = $('#'+self.opt.dateTo), - $modal = $('#'+self.opt.id), - $modalTrigger = $('#'+self.opt.modalTrigger), - applyBtnClass = self.opt.applyBtnClass, - $activeField, - /** - * make string from input:text values - * @returns {string} - * @function - */ - inputsTostring = function(){ - var self = this, - stringToReturn = '', - toChar = $modalTrigger.data('lng-to'), - fromChar = $modalTrigger.data('lng-from'), - toVal = $.trim($dateTo.val()), - fromVal = $.trim($dateFrom.val()); - if(toVal != ''&& fromVal != ''){ - if($(window).width() < 1086){ - stringToReturn = fromChar+': '+fromVal+'
'+toChar+': '+toVal+'.'; - }else{ - stringToReturn = fromChar+': '+fromVal+' '+toChar+': '+toVal+'.'; - } - } else if (toVal != ''&& fromVal == ''){ - stringToReturn = toChar+': '+toVal+'.'; - } else if (toVal == ''&& fromVal != ''){ - stringToReturn = fromChar+': '+fromVal+'.'; - } - return stringToReturn; - - }, - /** - * set trigger link text - * @param {string} selectedString - * @function - */ - triggerSetText = function (selectedString) { - var cutLength = 24; - if($(window).width() < 1086){ - cutLength = 6; - } - - if(selectedString != ''){ - $modalTrigger.html(selectedString).siblings('.trigger-label').addClass('hidden'); - $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).addClass('active'); - - - }else{ - $modalTrigger.html($modalTrigger.data('default')).siblings('.trigger-label').removeClass('hidden'); - $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).removeClass('active'); - } - }, - /** - * checks and corrects value of fields of a modal and corrects values so that in the field from always there was a date "to" (less) date in the field "on" - * @param it - * @function - */ - checkInterval = function (it) { - var itId = it.getAttribute('id'), - itVal = it.value, - itValInt = Date.parse(itVal), - thatId, - thatVal, - thatValInt, - bfr; - - /** - * check if it is a valid date - */ - if (self.validate()){ - $(it).parent('.pwf-field').removeClass('err'); - if(itId == self.opt.dateFrom){ - thatId = $dateTo[0].getAttribute('id'); - thatVal = $dateTo[0].value; - }else { - thatId = $dateFrom[0].getAttribute('id'); - thatVal = $dateFrom[0].value; - } - thatValInt = Date.parse(thatVal); - /** - * swap values between date fields - */ - if(itValInt > thatValInt && itId == self.opt.dateFrom){ - bfr = document.getElementById(itId).value; - document.getElementById(itId).value = document.getElementById(thatId).value; - document.getElementById(thatId).value = bfr; - }else if(itValInt < thatValInt && itId == self.opt.dateTo){ - bfr = document.getElementById(thatId).value; - document.getElementById(thatId).value = document.getElementById(itId).value; - document.getElementById(itId).value = bfr; - } - } - - }; - this.$dateFrom = $dateFrom; - this.$dateTo = $dateTo; - this.$modalTrigger = $modalTrigger; - - $(function () { - $.datepicker.setDefaults($.datepicker.regional["ru"]); - - $dateFrom.datepicker({ - dateFormat: 'dd.mm.yy', - showOn: 'button', - showOtherMonths: true, - constrainInput: true, - onClose: function( selectedDate ) { - $dateTo.datepicker( "option", "minDate", selectedDate ); - } - }).inputmask("99.99.9999",{ - showMaskOnHover:false, - insertMode:false, - 'oncomplete': function () { - $activeField = this; - } - }); - $dateTo.datepicker({ - dateFormat: 'dd.mm.yy', - showOn: 'button', - showOtherMonths: true, - constrainInput: true, - onClose: function( selectedDate ) { - $dateFrom.datepicker( "option", "maxDate", selectedDate ); - } - }).inputmask("99.99.9999",{ - showMaskOnHover:false, - insertMode:false, - 'oncomplete': function () { - $activeField = this; - } - }); - $('input[type="text"]',$modal).on('change', function () { - var stringToset = inputsTostring(); - if (self.validate()){ - triggerSetText(stringToset); - } - - }); - $('.'+applyBtnClass, $modal).on('click', function () { - if($activeField){ - checkInterval($activeField); - } - self.applyHandler(this); - return false; - }); - $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).on('click', function () { - $(this).removeClass('active'); - self.resetList(); - }); - }); - - }; - /** - * methods - * @type {{resetList: Function, applyHandler: Function}} - */ - PeriodModal.prototype = { - /** - * clear all input fields of modal window - * @public - */ - resetList: function () { - this.$dateFrom.val(''); - this.$dateTo.val(''); - this.$modalTrigger.text(this.$modalTrigger.attr('data-default')); - - }, - /** - * checks input fields to have valid date values, if not - adds err class to its container - * @returns {boolean} - */ - validate: function () { - var toVal = this.$dateTo.val(), - fromVal = this.$dateFrom.val(), - toValArr = toVal.split('.'), - fromValArr = fromVal.split('.'), - timestamps =[], - validationResult = true; - timestamps[0] = Date.parse(toValArr[1]+'.'+toValArr[0]+'.'+toValArr[2]); - timestamps[1] = Date.parse(fromValArr[1]+'.'+fromValArr[0]+'.'+fromValArr[2]); - - if (!timestamps[0] && $.trim(toVal) != ''){ - this.$dateTo.parent('.pwf-field').addClass('err'); - validationResult = false; - }else{ - this.$dateTo.parent('.pwf-field').removeClass('err'); - } - - if (!timestamps[1] && $.trim(fromVal) != ''){ - this.$dateFrom.parent('.pwf-field').addClass('err'); - validationResult = false; - }else{ - this.$dateFrom.parent('.pwf-field').removeClass('err'); - - } - return validationResult; - - }, - applyHandler: function (it) { - } - }; - /** - * constructor for main searchfield - * @param {Object} options - * @constructor - */ - var MainField = function (options) { - this.opt = options; - this.opt.anyChar = false; - var self = this, - firstComplete = true; - this.$field = $('#'+self.opt.id); - /** - * much faster than JQuery - * @type {HTMLElement} - */ - this.DOMcompleteWrap = document.getElementById(self.opt.autoCompleteWrapId); - this.afterClear; - /** - * data from ajax response - * @type {{items: Array, set: Function, get: Function, _rawDataChange: Function}} - */ - this.rawData = { - items:[], - /** - * setter - * @param data - * @public - */ - set:function (data) { - this.items = data; - this._rawDataChange(); - }, - /** - * get data - * @returns {*} - * @public - */ - get: function () { - return this.items; - }, - /** - * executes when this.rawData changes - * @param {Object} e - * @private - */ - _rawDataChange: function (e) { - var self = this, index; - for(index = 0; index < self.items.length; index++) { - renameProperty(self.items[index],'text','label') - renameProperty(self.items[index],'id','value') - } - } - }; - this.completeName = 'autocomplete'; - this.firstComplete = true; - this.$field.attr('autocomplete','off'); - - /** - * the ID value of the timer that is set - */ - this.timeout; - //autocomplete behaviour - self.$field.on('keyup', function (event) { - var reqObj; - text = $(this).val(); - event.stopImmediatePropagation(); - clearTimeout(self.timeout); - if(self.dataForm){ - reqObj = { - 'term':text, - 'form':self.dataForm - } - }else{ - reqObj = { - 'term':text - } - } - if(self.opt.anyChar){ - if (text.length > 2){ - self.timeout = setTimeout(function () { - getRequest(reqObj, self.opt.autoCompleteUrl, function (data) { - if(self.$field.hasClass('ui-autocomplete-input')){ - self.$field[self.completeName]( "destroy" ); - - } - self.rawData.set(data); - self._initAutoComplete(); - self.showList(''); - }); - }, 1000); - - } else if(text.length === 0){ - if(self.$field.hasClass('ui-autocomplete-input')){ - self.$field[self.completeName]( "destroy" ); - common.removeClass(self.DOMcompleteWrap,'full-visible'); - self._resetmodals(self.afterClear); - } - } - }else{ - if (text.length > 2 && firstComplete){ - self.timeout = setTimeout(function () { - getRequest(reqObj, self.opt.autoCompleteUrl, function (data) { - self.rawData.set(data); - self._initAutoComplete(); - self.showList(''); - }); - firstComplete = false; - }, 1000); - - }else if(text.length == 0 && !firstComplete){ - if(self.$field.hasClass('ui-autocomplete-input')){ - - self.$field[self.completeName]( "destroy" ); - common.removeClass(self.DOMcompleteWrap,'full-visible'); - self._resetmodals(self.afterClear); - firstComplete = true; - } - }else{ - if(self.$field.hasClass('ui-autocomplete-input')){ - self.showList(text); - - } - } - - } - //for autocomplete on each keypress - //for normal flow autocomplete - return false; - }).click(function () { - return false; - }); - - - - }; - /** - * methods - * @type {{_initAutoComplete: Function, _afterSelect: Function, _resetmodals: Function, selectHandler: Function, newRender: Function, selectCheckBoxes: Function, showList: Function, pullData: Function}} - */ - MainField.prototype = { - /** - * Jquery autocomplete initialization and autocomplete functionality on this.$field - * @private - */ - _initAutoComplete: function () { - var self = this; - self.$field[self.completeName]({ - source:self.rawData.get(), - minLength: 0, - appendTo:self.DOMcompleteWrap, - select:function(event, ui){ - self._afterSelect(event, ui); - }, - close: function () { - common.removeClass(self.DOMcompleteWrap,'full-visible'); - - - }, - open: function () { - common.addClass(self.DOMcompleteWrap,'full-visible'); - } - }); - - }, - /** - * fires after autocomplete is done and user selects item in it - * @param {Object} event - * @param {Object} ui - * @private - */ - _afterSelect: function (event, ui) { - var self = this; - event.preventDefault(); - // much faster than jquery - if(ui.item.url){ - window.location = ui.item.url; - } else if(ui.item.label.length){ - self.$field[0].value = ui.item.label; - self.selectCheckBoxes(ui.item.id, ui.item.name); - } - - }, - /** - * method fires callback when field is cleared - * @param {function} callback - * @returns {number} - * @private - */ - _resetmodals: function (callback) { - if(callback){ - callback(); - }else{ - return 0; - } - - }, - /** - * public property for redefine _afterSelect - * @public - */ - selectHandler: function () { - - }, - /** - * this property must be redefined for each individual instances of MainField Object - * select checkboxes if there is coincidence with search result and modal subject modal window - * @param {number} id - * @param {string} name - * @public - */ - selectCheckBoxes: function (id, name) { - - }, - /** - * simple shows out autocomplete list - * @param {string} text - */ - showList: function (text) { - self = this; - this.$field[self.completeName]('search',text); - - }, - /** - * brings data from server and transfer it to handler function - * @param {function} handler - */ - pullData: function (handler) { - - }, - clearValue: function () { - this.$field.val(''); - } - - }; - - /** - * whole module initialization - * @param {Object} options - * @public - */ - that.init = function(options) { - // settings extending - $.extend(this.lang, options.lang); - options.lang = null; - $.extend(this.settings, options); - // begin of initialization - var self = this, - submitHandler = function () { - $(self.DOMform).find('input[name="~~name~~"]').remove(); - }; - if(this.settings.searchData != 'None' && this.settings.searchData){ - this.previousSearch = JSON.parse(this.settings.searchData) - - } - this.DOMform = document.getElementById(this.settings.formId); - - $(this.DOMform).on('submit', function () { - submitHandler(); - }); - - // custom autocomplete realization for exibition input - $.widget( "custom.exibitionComplete", $.ui.autocomplete,{ - _renderMenu: function( ul, items ) { - var that = this, - currentCategory = ""; - $.each( items, function( index, item ) { - if ( item.cat != currentCategory && item.cat) { - ul.append( "
  • " + item.cat + "
  • " ); - currentCategory = item.cat; - } - that._renderItemData( ul, item ); - }); - } - }); - $.widget( "custom.exibitionComplete", $.ui.autocomplete,{ - _renderMenu: function( ul, items ) { - var that = this, - currentCategory = ""; - $.each( items, function( index, item ) { - if ( item.cat != currentCategory && item.cat) { - ul.append( "
  • " + item.cat + "
  • " ); - currentCategory = item.cat; - } - that._renderItemData( ul, item ); - }); - } - }); - $.widget( "custom.placeComplete", $.ui.autocomplete,{ - _renderItem: function( ul, item ) { - return $( "
  • " ) - .append( $( "" ).text( item.label) ) - .append(' ('+item.cat+')') - .appendTo( ul ); - } - }); - this.exhibitionField = new MainField(self.settings.firstField); - this.exhibitionField.completeName = 'exibitionComplete'; - - this.exhibitionField.opt.anyChar = true; - - - //modal windows - this.placesModal = new PlacesModal(self.settings.place); - this.subjModal = new SubjectModal(self.settings.subject); - this.periodModal = new PeriodModal(self.settings.period); - this.exhibitionField.selectCheckBoxes = function (id, name) { - var self = this, - DOMCheckboxes, - nestedObj, - iName = name; - if(name == 'th'){ - DOMCheckboxes = document.getElementById(self.opt.prefix+id); - - }else if(name == 'tg'){ - DOMCheckboxes = document.getElementById(self.opt.prefixInner+id); - iName = 'th'; - - } - $waiter.show(); - // load tree related to selected item - if (!DOMCheckboxes) { - nestedObj = { - name:name, - id:id - }; - EXPO.searchBlock.subjModal.resetList(); - getRequest(nestedObj, EXPO.searchBlock.subjModal.opt.getParentUrl, function (data) { - - EXPO.searchBlock.subjModal._loadParentTree(data, function(){ - - EXPO.searchBlock.subjModal._checkCheckBox(id, name); - }); - }); - } else{ - $waiter.hide(); - EXPO.searchBlock.subjModal.resetList(); - $(DOMCheckboxes).prop('checked', true); - $(DOMCheckboxes).trigger('change'); - } - }; - - this.placesField = new MainField(self.settings.placeField); - this.placesField.dataForm = EXPO.searchBlock.placesModal.$inputFilter.attr('data-form'); - this.placesField.selectCheckBoxes = function(id,name){ - var self = this, - DOMCheckboxes, - nestedObj; - DOMCheckboxes = document.getElementById(self.opt.prefix+id); - if (!DOMCheckboxes) { - nestedObj = { - name:name, - id:id - }; - EXPO.searchBlock.placesModal.resetList(); - getRequest(nestedObj, EXPO.searchBlock.placesModal.opt.getParentUrl, function (data) { - - EXPO.searchBlock.placesModal._loadParentTree(data, function(){ - - EXPO.searchBlock.placesModal._checkCheckBox(id, true); - }); - }); - } else{ - $waiter.hide(); - EXPO.searchBlock.placesModal.resetList(); - - $(DOMCheckboxes).prop('checked', true); - $(DOMCheckboxes).trigger('change'); - } - }; - - // uncheck all checboxes in modal and clear label beneath searchfield - this.exhibitionField.afterClear = function () { - self.subjModal.resetList(); - }; - this.placesField.afterClear = function () { - self.placesModal.resetList(); - }; - //модальное окно - this.modalWindow = new common.Modal(self.settings.modal); - - this.periodModal.applyHandler = function () { - if(this.validate()){ - $waiter.show(); - $(self.DOMform).submit(); - } - - }; - this.placesModal.applyHandler = function () { - $waiter.show(); - $(self.DOMform).submit(); - }; - this.subjModal.applyHandler = function () { - $waiter.show(); - $(self.DOMform).submit(); - }; - - // - // modal window calling - $('.'+self.settings.modalTriggerClass).on('click', function (event) { - event.preventDefault(); - self.modalWindow.pullData(this.getAttribute('href')); - self.modalWindow.open(); - return false; - }); - - // заполнение полей предыдущими значениями - $(function () { - if(self.previousSearch){ - 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]); - } - } - } - - } - }); - - - }; - - return that; - }()); + EXPO.searchBlock = (function() { + + // variables + + var that = {}; + /** + * default module setting + * @type {{place: {id: string, selectedItemTemplate: string, ajaxUrl: string}, subject: {id: string, ajaxUrl: string}}} + */ + that.settings = { + place:{ + id:'pw-place', + selectedItemTemplate:'csb-selected', + ajaxUrl: window.location.protocol + '//hit.expomap.ru/search-form/' + }, + subject:{ + id:'pw-subj', + ajaxUrl: window.location.protocol + '//hit.expomap.ru/search-form/' + } + }; + that.lang ={}; + //dependence's + // module require dna.js tiny templating engine + var common = EXPO.common; + //private + + var Json2URI = function (jsonObj) { + var str = Object.keys(jsonObj).map(function(key){ + return encodeURIComponent(key) + '=' + encodeURIComponent(jsonObj[key]); + }).join('&'); + return ('?'+str); + }, + /** + * 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 + * @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; + }, + /** + * getSelectedToString returns string that contains selected values in both modal windows. values separated by ',' + * @param {string} container + * @param {number} cutLength - length to cut off string + * @returns {string} string that is cutted off + */ + getSelectedToString = function(container, cutLength){ + var $container = $('#'+container), + index = 0, + stringToReturn = '', + closingSymbol = '...', + closerText = EXPO.searchBlock.settings.closerText, + closerTextSingle = EXPO.searchBlock.settings.closerTextSingle, + dividerSymbol = ''; + $element = $container.find('.csbs-text'); + if($element.length > 2){ + if($element.eq(0).text().length < cutLength){ + dividerSymbol = ', '; + stringToReturn += $element.eq(0).text() + dividerSymbol + $element.eq(1).text() + closerText.replace('_',$element.length-2); + }else{ + stringToReturn += $element.eq(0).text() + closerText.replace('_',$element.length-1); + } + + } else if($element.length == 2){ + if(($element.eq(0).text().length+$element.eq(1).text().length) < cutLength){ + dividerSymbol = ', '; + // если даже 2 первых слова вместе меньше чем порог, то не указывать количество позиций + stringToReturn += $element.eq(0).text() + dividerSymbol + $element.eq(1).text()+' '; + + } else if($element.eq(0).text().length < cutLength){ + dividerSymbol = ', '; + stringToReturn += $element.eq(0).text() + dividerSymbol + $element.eq(1).text()+' '; + }else{ + stringToReturn += $element.eq(0).text() + closerTextSingle.replace('_',$element.length-1); + } + }else if($element.length){ + stringToReturn += $element.eq(0).text()+' '; + }else{ + stringToReturn = false; + } + return stringToReturn; + }, + /** + * ajax pending process indicator + * @type {*|jQuery|HTMLElement} индикатор загрузки диалоговых окон + */ + $waiter = $('.wait-ajax.absolute'); + + /** + * 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 = $('.csb-selected-items',$modal), + setDefault = self.opt.defaultOn, + applyBtnClass = self.opt.applyBtnClass, + $modalTrigger = $('#'+self.opt.modalTrigger), + /** + * executed after render of modal Window + * @function + */ + afterRenderHandler = function () { + $waiter.hide(); + + }, + /** + * fill text beneth search field + * @function triggerSetText + */ + triggerSetText = function () { + var selectedString, + cutLength = 16; + if($(window).width() < 1086){ + cutLength = 12; + } + + selectedString = getSelectedToString(self.opt.selectedItemsContainer,cutLength); + if(selectedString && selectedString != '~~text~~' && selectedString != '~~text~~...'){ + $modalTrigger.text(selectedString); + $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).addClass('active'); + }else{ + $modalTrigger.text($modalTrigger.data('default')); + $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).removeClass('active'); + } + }; + + /** + * 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/) + * @type {Object} + */ + this.itemsSelected = {}; + /** + * 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); + 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(this.checked){ + $label.addClass('active'); + 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 = common.closest(this,'custom-radio-check'); + + this.checked = true; + self._destroyTag(thisId); + common.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 =common.closest(this,'custom-radio-check'), + DOMParentLabel = common.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); + common.addClass($(DOMParentLabel).find('.custom-radio-check')[0],'active'); + + //$parentCheckBox.trigger('change',['true']); + self._addTag(parentId,parentObj); + } + } + + //!uncheck event + }else { + $label.removeClass('active'); + 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 = common.closest(this,'custom-radio-check'); + this.checked = false; + + common.removeClass(DOMlabel, 'active'); + self._destroyTag(thisId); + }); + }else{ + // parent item is unchecked and tags for every children item are made + if($parentCheckBox.length && $parentCheckBox[0].checked){ + var DOMlabel = common.closest($parentCheckBox[0],'custom-radio-check'), + DOMParentItem = common.closest(DOMlabel,'level'), + DOMSublist = DOMParentItem.querySelector('.sublist'); + $parentCheckBox.prop('checked', false); + common.removeClass(DOMlabel, 'active'); + self._destroyTag($parentCheckBox.attr('id')); + // checks children items + + $('.csb-menu-input:checked',DOMSublist).each(function () { + var id = this.getAttribute('id'), + tagText = common.closest(this, 'level').querySelector('.trigger').textContent, + tagObj = {'text':tagText,'id':id}; + self._addTag(id,tagObj); + }); + } + } + + } + triggerSetText(); + } + }); + //delete tag behavior + $('.csbs-del', $selectedItemsWrap).on('click', function () { + var checkboxId = $(this).attr('data-checkbox-id'), + $uncheckBoxes = $('#'+checkboxId); + $uncheckBoxes.prop('checked', false); + $uncheckBoxes.trigger('change'); + dna.destroy(self.itemsSelected[checkboxId]); + if(!$selectedItemsWrap.children('.dna-clone').length){ + $selectedItemsWrap.removeClass('visible'); + } + return false; + }); + $('.modal-clear', $modal).on('click', function () { + self.resetList(); + return false; + }); + self._autocompleteInit(); + $('.'+applyBtnClass, $modal).on('click', function () { + self.applyHandler(this); + return false; + }); + // кнопка "очистить параметры" + $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).on('click', function () { + self.resetList(); + EXPO.searchBlock.exhibitionField.clearValue(); + + }); + }); + }; + /** + * 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 + * @param {boolean} strict - if true then select particular checkbox without 'popping' to parent category + * @private + */ + _checkCheckBox: function (id,name) { + var self = this, + $chckBox; + + if(name == 'th'){ + $chckBox = $('#tid_'+id, self.$modalInst); + }else if(name == 'tg'){ + $chckBox = $('#tgid_'+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_'+id, self.$modalInst); + }else if(name == 'tg'){ + $chckBox = $('#tgid_'+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){ + if($('#tid_'+ui.item.value+'[name="'+ui.item.name+'"]:checked').length){ + firstTime = false; + } + } + + } + } + if($('#tid_'+ui.item.value+'[name="'+ui.item.name+'"]:checked').length){ + firstTime = false; + } + // ban of repeating execution + if (firstTime) { // konec + var $checkbox = $('#tid_' + 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',""); + } + + }; + + /** + * the ID value of the timer that is set + */ + self.timeout; + self.$inputFilter.attr('autocomplete', 'on'); + + self.$inputFilter.on('keyup', function (event) { + text = $(this).val(); + event.stopImmediatePropagation(); + clearTimeout(self.timeout); + + if (text.length > 2 && firstComplete){ + self.timeout = setTimeout(function () { + getRequest({'term':text, 'form':form}, self.opt.autoCompleteUrl, requestHandler); + firstComplete = false; + }, 1000); + + }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 ITS Children sublist + * @param {Object} data - current (children) 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_'+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){ + var self = this; + if(self.itemsSelected[checkboxId]){ + dna.destroy(self.itemsSelected[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); + }, + /** + * 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).trigger('change'); + + dna.destroy(self.itemsSelected[key]); + + } + } + $('.level.active',self.$modalInst).removeClass('active'); + self.$selectedItemsWrap.removeClass('visible'); + $(this.$modalInst).find('input:checkbox:checked').prop('checked',false); + + }, + // кнопка применить + applyHandler: function (it) { + $waiter.show(); + }, + /** + * 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_'+item.id){ + firstTime = false; + } + + } + if($('#tid_'+item.id+':checked').length){ + firstTime = false; + } + if(firstTime){ + self.check(item.id, item.name); + self.isReceived = true; + }else{ + $('#tid_' + item.id).prop('checked', true); + $('#tid_' + item.id).trigger('change'); + self.isReceived = true; + + } + }else{ + if($('#tgid_'+item.children.id).length){ + firstTime = false; + } + //Если выбран родитель + if($('#tid_'+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_'+item.id+':checked').length){ + + $('#tgid_' + item.children.id).prop('checked', true); + $('#tgid_' + 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 = $('.csb-selected-items',$modal), + DOMTagsWrapper = $('.csb-selected-items',$modal)[0], + $modalTrigger = $('#'+self.opt.modalTrigger), + applyBtnClass = self.opt.applyBtnClass, + idPrefix = 'id_', + /** + * set trigger link text under the search field + * @function + */ + triggerSetText = function () { + var selectedString, + cutLength = 16; + if($(window).width() < 1086){ + cutLength = 6; + } + selectedString = getSelectedToString(self.opt.selectedItemsContainer,cutLength); + if(selectedString && selectedString != '~~text~~' && selectedString != '~~text~~...'){ + $modalTrigger.text(selectedString); + $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).addClass('active'); + + }else{ + $modalTrigger.text($modalTrigger.data('default')); + $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).removeClass('active'); + + } + }; + /** + * current template instances + * @type {Object} + */ + this.curDNA = {}; + /** + * place modal list items that had selected + * @type {Object} + */ + this.itemsSelected = {}; + 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; + + /** + * 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 = common.closest(that,'level'), + DOMParentCheckbox = DOMParent.querySelector('.csb-menu-input'); + $('.csb-menu-input', $sublist).each(function () { + var DOMCheckboxWrap = common.closest(this,'custom-radio-check'); + if(!this.checked){ + + if(DOMParentCheckbox.checked){ + this.checked = true; + common.addClass(DOMCheckboxWrap,'active'); + } + }else{ + if(!DOMParentCheckbox.checked){ + + this.checked = false; + common.removeClass(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 = common.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 = common.closest(this, itemClass), + + DOMParentItem = common.hasClass(DOMParentRow, highestItemClass) == false?common.closest(DOMParentRow.parentNode, itemClass):DOMParentRow, + DOMParentCheckbox = DOMParentItem.querySelector('.'+checkboxClass), + DOMSublist = DOMParentItem.querySelector('.'+sublistClass), + DOMSublistInner = DOMParentRow.querySelector('.'+sublistClass), + DOMHighestItem = common.closest(this, highestItemClass), + DOMHighestCheckbox = DOMHighestItem.querySelector('.'+checkboxClass), + DOMHighestSublist = DOMHighestItem.querySelector('.'+sublistClass), + + selectSublist = function (it) { + var DOMParentItem = common.closest(it, itemClass) || this, + DOMSublist = DOMParentItem.querySelector('.'+sublistClass); + $('.'+checkboxClass, DOMSublist).each(function () { + selectItem(this); + }); + + }, + unSelectSublist = function (it) { + var DOMParentItem = common.closest(it, itemClass) || this, + DOMSublist = DOMParentItem.querySelector('.'+sublistClass); + $('.'+checkboxClass, DOMSublist).each(function () { + unSelectItem(this); + + }); + + }, + selectParent = function (it) { + var DOMParentRow = common.closest(it, itemClass), + DOMParentItem; + if(common.hasClass(DOMParentRow,'level1')){ + DOMParentItem = DOMParentRow; + }else{ + DOMParentItem = common.closest(DOMParentRow.parentNode, itemClass); + } + + common.addClass(DOMParentItem.querySelector('.'+fakeCheckboxClass), activeClass); + DOMParentItem.querySelector('.'+checkboxClass).checked = true; + + //it.selected = true; + + }, + unSelectParent = function (it) { + var DOMParentRow = common.closest(it, itemClass), + DOMParentItem = common.closest(DOMParentRow.parentNode, itemClass) || DOMParentRow; + + common.removeClass(DOMParentItem.querySelector('.'+fakeCheckboxClass), activeClass); + DOMParentItem.querySelector('.'+checkboxClass).checked = false; + //it.checked = false; + + }, + selectItem = function (it) { + var itFakeCheckbox = common.closest(it, fakeCheckboxClass); + common.addClass(itFakeCheckbox, activeClass); + it.checked = true; + common.addClass(DOMParentItem,activeClass); + common.removeClass(DOMSublist,'hidden'); + + }, + unSelectItem = function (it) { + var itFakeCheckbox = common.closest(it, fakeCheckboxClass), + DOMitem = common.closest(it, itemClass); + common.removeClass(itFakeCheckbox, activeClass); + it.checked = false; + // if there is children items + if(DOMitem.querySelector('.'+sublistClass) && !common.hasClass(DOMitem,highestItemClass)){ + unSelectSublist(it); + } + }, + allChildrenSelected = function () { + //var DOMselected = DOMSublist.querySelectorAll('.'+checkboxClass+':checked'), + var DOMSublistParent = common.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 = common.closest(it,sublistClass); + var DOMItem = common.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){ + self.timeout = setTimeout(function () { + getRequest({'term':text, 'form':form}, self.opt.autoCompleteUrl, requestHandler); + firstComplete = false; + }, 1000); + + }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.({text: "Германия", id: 47, parent: {text: "Европа", id: 4, name: "area"}, name: "co"}) + * @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_'+dataObj.id), + /** + * makes request in order to recieve children list information fires after request for parent list + * @param {number} length - the number of received elements + * @function + */ + handlerNested = function (length) { + var $checkbox = $('#id_'+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_'+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_'+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_'+dataObj.id).closest('.level').children('.trigger').attr('data-template-id'); + self._renderSublist(optObj,sublistTemplateId,handlerParent); + } + + }, + /** + * @param it + * @public + */ + applyHandler: function (it) { + console.log(this); + + }, + _refreshText: function () { + var selectedString, + $modalTrigger = $('#'+this.opt.modalTrigger), + cutLength = 16; + selectedString = getSelectedToString(this.opt.selectedItemsContainer,cutLength); + if(selectedString && selectedString != '~~text~~' && selectedString != '~~text~~...'){ + $modalTrigger.text(selectedString); + $modalTrigger.siblings('.'+this.opt.clearAllButtonClass).addClass('active'); + + }else{ + $modalTrigger.text($modalTrigger.data('default')); + $modalTrigger.siblings('.'+this.opt.clearAllButtonClass).removeClass('active'); + + } + } + }; + + /** + * period selector modal window + * @param {Object} options + * @constructor + */ + var PeriodModal = function (options) { + this.opt = options; + var self = this, + $dateFrom = $('#'+self.opt.dateFrom), + $dateTo = $('#'+self.opt.dateTo), + $modal = $('#'+self.opt.id), + $modalTrigger = $('#'+self.opt.modalTrigger), + applyBtnClass = self.opt.applyBtnClass, + $activeField, + /** + * make string from input:text values + * @returns {string} + * @function + */ + inputsTostring = function(){ + var self = this, + stringToReturn = '', + toChar = $modalTrigger.data('lng-to'), + fromChar = $modalTrigger.data('lng-from'), + toVal = $.trim($dateTo.val()), + fromVal = $.trim($dateFrom.val()); + if(toVal != ''&& fromVal != ''){ + if($(window).width() < 1086){ + stringToReturn = fromChar+': '+fromVal+'
    '+toChar+': '+toVal+'.'; + }else{ + stringToReturn = fromChar+': '+fromVal+' '+toChar+': '+toVal+'.'; + } + } else if (toVal != ''&& fromVal == ''){ + stringToReturn = toChar+': '+toVal+'.'; + } else if (toVal == ''&& fromVal != ''){ + stringToReturn = fromChar+': '+fromVal+'.'; + } + return stringToReturn; + + }, + /** + * set trigger link text + * @param {string} selectedString + * @function + */ + triggerSetText = function (selectedString) { + var cutLength = 24; + if($(window).width() < 1086){ + cutLength = 6; + } + + if(selectedString != ''){ + $modalTrigger.html(selectedString).siblings('.trigger-label').addClass('hidden'); + $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).addClass('active'); + + + }else{ + $modalTrigger.html($modalTrigger.data('default')).siblings('.trigger-label').removeClass('hidden'); + $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).removeClass('active'); + } + }, + /** + * checks and corrects value of fields of a modal and corrects values so that in the field from always there was a date "to" (less) date in the field "on" + * @param it + * @function + */ + checkInterval = function (it) { + var itId = it.getAttribute('id'), + itVal = it.value, + itValInt = Date.parse(itVal), + thatId, + thatVal, + thatValInt, + bfr; + + /** + * check if it is a valid date + */ + if (self.validate()){ + $(it).parent('.pwf-field').removeClass('err'); + if(itId == self.opt.dateFrom){ + thatId = $dateTo[0].getAttribute('id'); + thatVal = $dateTo[0].value; + }else { + thatId = $dateFrom[0].getAttribute('id'); + thatVal = $dateFrom[0].value; + } + thatValInt = Date.parse(thatVal); + /** + * swap values between date fields + */ + if(itValInt > thatValInt && itId == self.opt.dateFrom){ + bfr = document.getElementById(itId).value; + document.getElementById(itId).value = document.getElementById(thatId).value; + document.getElementById(thatId).value = bfr; + }else if(itValInt < thatValInt && itId == self.opt.dateTo){ + bfr = document.getElementById(thatId).value; + document.getElementById(thatId).value = document.getElementById(itId).value; + document.getElementById(itId).value = bfr; + } + } + + }; + this.$dateFrom = $dateFrom; + this.$dateTo = $dateTo; + this.$modalTrigger = $modalTrigger; + + $(function () { + $.datepicker.setDefaults($.datepicker.regional["ru"]); + + $dateFrom.datepicker({ + dateFormat: 'dd.mm.yy', + showOn: 'button', + showOtherMonths: true, + constrainInput: true, + onClose: function( selectedDate ) { + $dateTo.datepicker( "option", "minDate", selectedDate ); + } + }).inputmask("99.99.9999",{ + showMaskOnHover:false, + insertMode:false, + 'oncomplete': function () { + $activeField = this; + } + }); + $dateTo.datepicker({ + dateFormat: 'dd.mm.yy', + showOn: 'button', + showOtherMonths: true, + constrainInput: true, + onClose: function( selectedDate ) { + $dateFrom.datepicker( "option", "maxDate", selectedDate ); + } + }).inputmask("99.99.9999",{ + showMaskOnHover:false, + insertMode:false, + 'oncomplete': function () { + $activeField = this; + } + }); + $('input[type="text"]',$modal).on('change', function () { + var stringToset = inputsTostring(); + if (self.validate()){ + triggerSetText(stringToset); + } + + }); + $('.'+applyBtnClass, $modal).on('click', function () { + if($activeField){ + checkInterval($activeField); + } + self.applyHandler(this); + return false; + }); + $modalTrigger.siblings('.'+self.opt.clearAllButtonClass).on('click', function () { + $(this).removeClass('active'); + self.resetList(); + }); + }); + + }; + /** + * methods + * @type {{resetList: Function, applyHandler: Function}} + */ + PeriodModal.prototype = { + /** + * clear all input fields of modal window + * @public + */ + resetList: function () { + this.$dateFrom.val(''); + this.$dateTo.val(''); + this.$modalTrigger.text(this.$modalTrigger.attr('data-default')); + + }, + /** + * checks input fields to have valid date values, if not - adds err class to its container + * @returns {boolean} + */ + validate: function () { + var toVal = this.$dateTo.val(), + fromVal = this.$dateFrom.val(), + toValArr = toVal.split('.'), + fromValArr = fromVal.split('.'), + timestamps =[], + validationResult = true; + timestamps[0] = Date.parse(toValArr[1]+'.'+toValArr[0]+'.'+toValArr[2]); + timestamps[1] = Date.parse(fromValArr[1]+'.'+fromValArr[0]+'.'+fromValArr[2]); + + if (!timestamps[0] && $.trim(toVal) != ''){ + this.$dateTo.parent('.pwf-field').addClass('err'); + validationResult = false; + }else{ + this.$dateTo.parent('.pwf-field').removeClass('err'); + } + + if (!timestamps[1] && $.trim(fromVal) != ''){ + this.$dateFrom.parent('.pwf-field').addClass('err'); + validationResult = false; + }else{ + this.$dateFrom.parent('.pwf-field').removeClass('err'); + + } + return validationResult; + + }, + applyHandler: function (it) { + } + }; + /** + * constructor for main searchfield + * @param {Object} options + * @constructor + */ + var MainField = function (options) { + this.opt = options; + this.opt.anyChar = false; + var self = this, + firstComplete = true; + this.$field = $('#'+self.opt.id); + /** + * much faster than JQuery + * @type {HTMLElement} + */ + this.DOMcompleteWrap = document.getElementById(self.opt.autoCompleteWrapId); + this.afterClear; + /** + * data from ajax response + * @type {{items: Array, set: Function, get: Function, _rawDataChange: Function}} + */ + this.rawData = { + items:[], + /** + * setter + * @param data + * @public + */ + set:function (data) { + this.items = data; + this._rawDataChange(); + }, + /** + * get data + * @returns {*} + * @public + */ + get: function () { + return this.items; + }, + /** + * executes when this.rawData changes + * @param {Object} e + * @private + */ + _rawDataChange: function (e) { + var self = this, index; + for(index = 0; index < self.items.length; index++) { + renameProperty(self.items[index],'text','label') + renameProperty(self.items[index],'id','value') + } + } + }; + this.completeName = 'autocomplete'; + this.firstComplete = true; + this.$field.attr('autocomplete','off'); + + /** + * the ID value of the timer that is set + */ + this.timeout; + //autocomplete behaviour + self.$field.on('keyup', function (event) { + var reqObj; + text = $(this).val(); + event.stopImmediatePropagation(); + clearTimeout(self.timeout); + if(self.dataForm){ + reqObj = { + 'term':text, + 'form':self.dataForm + } + }else{ + reqObj = { + 'term':text + } + } + if(self.opt.anyChar){ + if (text.length > 2){ + self.timeout = setTimeout(function () { + getRequest(reqObj, self.opt.autoCompleteUrl, function (data) { + if(self.$field.hasClass('ui-autocomplete-input')){ + self.$field[self.completeName]( "destroy" ); + + } + self.rawData.set(data); + self._initAutoComplete(); + self.showList(''); + }); + }, 1000); + + } else if(text.length === 0){ + if(self.$field.hasClass('ui-autocomplete-input')){ + self.$field[self.completeName]( "destroy" ); + common.removeClass(self.DOMcompleteWrap,'full-visible'); + self._resetmodals(self.afterClear); + } + } + }else{ + if (text.length > 2 && firstComplete){ + self.timeout = setTimeout(function () { + getRequest(reqObj, self.opt.autoCompleteUrl, function (data) { + self.rawData.set(data); + self._initAutoComplete(); + self.showList(''); + }); + firstComplete = false; + }, 1000); + + }else if(text.length == 0 && !firstComplete){ + if(self.$field.hasClass('ui-autocomplete-input')){ + + self.$field[self.completeName]( "destroy" ); + common.removeClass(self.DOMcompleteWrap,'full-visible'); + self._resetmodals(self.afterClear); + firstComplete = true; + } + }else{ + if(self.$field.hasClass('ui-autocomplete-input')){ + self.showList(text); + + } + } + + } + //for autocomplete on each keypress + //for normal flow autocomplete + return false; + }).click(function () { + return false; + }); + + + + }; + /** + * methods + * @type {{_initAutoComplete: Function, _afterSelect: Function, _resetmodals: Function, selectHandler: Function, newRender: Function, selectCheckBoxes: Function, showList: Function, pullData: Function}} + */ + MainField.prototype = { + /** + * Jquery autocomplete initialization and autocomplete functionality on this.$field + * @private + */ + _initAutoComplete: function () { + var self = this; + self.$field[self.completeName]({ + source:self.rawData.get(), + minLength: 0, + appendTo:self.DOMcompleteWrap, + select:function(event, ui){ + self._afterSelect(event, ui); + }, + close: function () { + common.removeClass(self.DOMcompleteWrap,'full-visible'); + + + }, + open: function () { + common.addClass(self.DOMcompleteWrap,'full-visible'); + } + }); + + }, + /** + * fires after autocomplete is done and user selects item in it + * @param {Object} event + * @param {Object} ui + * @private + */ + _afterSelect: function (event, ui) { + var self = this; + event.preventDefault(); + // much faster than jquery + if(ui.item.url){ + window.location = ui.item.url; + } else if(ui.item.label.length){ + self.$field[0].value = ui.item.label; + self.selectCheckBoxes(ui.item.id, ui.item.name); + } + + }, + /** + * method fires callback when field is cleared + * @param {function} callback + * @returns {number} + * @private + */ + _resetmodals: function (callback) { + if(callback){ + callback(); + }else{ + return 0; + } + + }, + /** + * public property for redefine _afterSelect + * @public + */ + selectHandler: function () { + + }, + /** + * this property must be redefined for each individual instances of MainField Object + * select checkboxes if there is coincidence with search result and modal subject modal window + * @param {number} id + * @param {string} name + * @public + */ + selectCheckBoxes: function (id, name) { + + }, + /** + * simple shows out autocomplete list + * @param {string} text + */ + showList: function (text) { + self = this; + this.$field[self.completeName]('search',text); + + }, + /** + * brings data from server and transfer it to handler function + * @param {function} handler + */ + pullData: function (handler) { + + }, + clearValue: function () { + this.$field.val(''); + } + + }; + + /** + * whole module initialization + * @param {Object} options + * @public + */ + that.init = function(options) { + // settings extending + $.extend(this.lang, options.lang); + options.lang = null; + $.extend(this.settings, options); + // begin of initialization + var self = this, + submitHandler = function () { + $(self.DOMform).find('input[name="~~name~~"]').remove(); + }; + if(this.settings.searchData != 'None' && this.settings.searchData){ + this.previousSearch = JSON.parse(this.settings.searchData) + + } + this.DOMform = document.getElementById(this.settings.formId); + + $(this.DOMform).on('submit', function () { + submitHandler(); + }); + + // custom autocomplete realization for exibition input + $.widget( "custom.exibitionComplete", $.ui.autocomplete,{ + _renderMenu: function( ul, items ) { + var that = this, + currentCategory = ""; + $.each( items, function( index, item ) { + if ( item.cat != currentCategory && item.cat) { + ul.append( "
  • " + item.cat + "
  • " ); + currentCategory = item.cat; + } + that._renderItemData( ul, item ); + }); + } + }); + $.widget( "custom.exibitionComplete", $.ui.autocomplete,{ + _renderMenu: function( ul, items ) { + var that = this, + currentCategory = ""; + $.each( items, function( index, item ) { + if ( item.cat != currentCategory && item.cat) { + ul.append( "
  • " + item.cat + "
  • " ); + currentCategory = item.cat; + } + that._renderItemData( ul, item ); + }); + } + }); + $.widget( "custom.placeComplete", $.ui.autocomplete,{ + _renderItem: function( ul, item ) { + return $( "
  • " ) + .append( $( "" ).text( item.label) ) + .append(' ('+item.cat+')') + .appendTo( ul ); + } + }); + this.exhibitionField = new MainField(self.settings.firstField); + this.exhibitionField.completeName = 'exibitionComplete'; + + this.exhibitionField.opt.anyChar = true; + + + //modal windows + this.placesModal = new PlacesModal(self.settings.place); + this.subjModal = new SubjectModal(self.settings.subject); + this.periodModal = new PeriodModal(self.settings.period); + this.exhibitionField.selectCheckBoxes = function (id, name) { + var self = this, + DOMCheckboxes, + nestedObj, + iName = name; + if(name == 'th'){ + DOMCheckboxes = document.getElementById(self.opt.prefix+id); + + }else if(name == 'tg'){ + DOMCheckboxes = document.getElementById(self.opt.prefixInner+id); + iName = 'th'; + + } + $waiter.show(); + // load tree related to selected item + if (!DOMCheckboxes) { + nestedObj = { + name:name, + id:id + }; + EXPO.searchBlock.subjModal.resetList(); + getRequest(nestedObj, EXPO.searchBlock.subjModal.opt.getParentUrl, function (data) { + + EXPO.searchBlock.subjModal._loadParentTree(data, function(){ + + EXPO.searchBlock.subjModal._checkCheckBox(id, name); + }); + }); + } else{ + $waiter.hide(); + EXPO.searchBlock.subjModal.resetList(); + $(DOMCheckboxes).prop('checked', true); + $(DOMCheckboxes).trigger('change'); + } + }; + + this.placesField = new MainField(self.settings.placeField); + this.placesField.dataForm = EXPO.searchBlock.placesModal.$inputFilter.attr('data-form'); + this.placesField.selectCheckBoxes = function(id,name){ + var self = this, + DOMCheckboxes, + nestedObj; + DOMCheckboxes = document.getElementById(self.opt.prefix+id); + if (!DOMCheckboxes) { + nestedObj = { + name:name, + id:id + }; + EXPO.searchBlock.placesModal.resetList(); + getRequest(nestedObj, EXPO.searchBlock.placesModal.opt.getParentUrl, function (data) { + EXPO.searchBlock.placesModal._loadParentTree(data, function(){ + EXPO.searchBlock.placesModal._checkCheckBox(id, true); + }); + }); + } else{ + $waiter.hide(); + EXPO.searchBlock.placesModal.resetList(); + + $(DOMCheckboxes).prop('checked', true); + $(DOMCheckboxes).trigger('change'); + } + }; + + // uncheck all checboxes in modal and clear label beneath searchfield + this.exhibitionField.afterClear = function () { + self.subjModal.resetList(); + }; + this.placesField.afterClear = function () { + self.placesModal.resetList(); + }; + //модальное окно + this.modalWindow = new common.Modal(self.settings.modal); + + this.periodModal.applyHandler = function () { + if(this.validate()){ + $waiter.show(); + $(self.DOMform).submit(); + } + + }; + this.placesModal.applyHandler = function () { + $waiter.show(); + $(self.DOMform).submit(); + }; + this.subjModal.applyHandler = function () { + $waiter.show(); + $(self.DOMform).submit(); + }; + + // + // modal window calling + $('.'+self.settings.modalTriggerClass).on('click', function (event) { + event.preventDefault(); + self.modalWindow.pullData(this.getAttribute('href')); + self.modalWindow.open(); + return false; + }); + + // заполнение полей предыдущими значениями + $(function () { + if(self.previousSearch){ + 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]); + } + } + } + + } + }); + + + }; + + return that; + }()); } diff --git a/static/client/js_min/_modules/block.search.min.js b/static/client/js_min/_modules/block.search.min.js index ef9b4fa8..961b644e 100644 --- a/static/client/js_min/_modules/block.search.min.js +++ b/static/client/js_min/_modules/block.search.min.js @@ -1 +1 @@ -var EXPO=EXPO||{};EXPO.searchBlock?console.warn("WARNING: EXPO.searchBlock is already defined!"):EXPO.searchBlock=function(){var e={};e.settings={place:{id:"pw-place",selectedItemTemplate:"csb-selected",ajaxUrl:window.location.protocol+"//hit.expomap.ru/search-form/"},subject:{id:"pw-subj",ajaxUrl:window.location.protocol+"//hit.expomap.ru/search-form/"}},e.lang={};var t=EXPO.common,i=function(e){var t=Object.keys(e).map(function(t){return encodeURIComponent(t)+"="+encodeURIComponent(e[t])}).join("&");return"?"+t},n=function(e,t,i){e||(e=""),$.ajax({type:"GET",url:t,data:e,success:function(e){return"function"!=typeof i?e:void i(e)}})},a=function(e,t,i){return e.hasOwnProperty(t)&&(e[i]=e[t]),this},s=function(e){var t,i=0;for(t in e)e.hasOwnProperty(t)&&i++;return i},l=function(e,t){var i=$("#"+e),n="",a=EXPO.searchBlock.settings.closerText,s=EXPO.searchBlock.settings.closerTextSingle,l="";return $element=i.find(".csbs-text"),$element.length>2?$element.eq(0).text().length2&&d?l.timeout=setTimeout(function(){n({term:t,form:o},l.opt.autoCompleteUrl,u),d=!1},1e3):0!=t.length||d||l.$inputFilter.hasClass("ui-autocomplete-input")&&(l.$inputFilter.placeComplete("destroy"),d=!0),!1}).click(function(){return!1})},_renderSublist:function(e,t,i){var n=this,a=0,s=t+"-sub",l=function(e){if(e.length){for(n.sublist[s]={},a;aS;S++)for(o=y[S],I=0;w>I;I++)o==_[I]&&q(i[I]);for(S=0;x>S;S++)o=y[S],o==T&&q(e);k.querySelectorAll(".final-tire")&&$("."+a+"."+l,k.querySelectorAll(".final-tire")).each(function(){q($("."+d,this)[0])})}else for(S=0;x>S;S++)o=y[S],o==T&&q(T)},q=function(e){var t=e.getAttribute("id");i._destroyTag(t),j()},E=function(e){var n=t.closest(e,s),a=n.querySelector("."+f),l="",r=e.getAttribute("id"),o={};l=a.innerHTML,o={id:r,text:l},i._addTag(r,o),j()},j=function(){o.find("."+m).length&&"~~id~~"!=o.find("."+m)[0].getAttribute(g)?o.addClass("visible"):o.removeClass("visible")},N=function(e){var t=$(e).children("li").children("."+a).find("."+d+":checked");t.each(function(){E(this)})},L=function(){var e=$(b).children("li").children("."+a).find("."+d+":checked");e.each(function(){q(this)})};i.strictMode?this.checked?(F(this),P(this),E(this)):(M(this),P(this),q(this)):this.checked?($(_).find("."+d)[0]&&_&&"~~id~~"!=$(_).find("."+d)[0].value&&P(this),O()?(I(this),F(this),P(C),E(C),L(b),C.getAttribute("id")!=x.getAttribute("id")||x.checked?A()&&(F(x),P(x),E(x)):(F(x),P(x),E(x))):(F(this),P(this),E(this)),_&&T(this)):(D()?(B(this),M(this),P(C),q(C),N(b),x.checked&&(M(x),q(x),N(w))):(M(this),P(this),q(this)),_&&(S(this),P(this))),p()}),$(".csbs-del",o).on("click",function(){var e=$(this).attr("data-checkbox-id"),t=$("#"+e);return t.prop("checked",!1),t.trigger("change"),dna.destroy(i.itemsSelected[e]),o.children(".dna-clone").length||o.removeClass("visible"),!1}),$(".modal-clear",a).on("click",function(){return i.resetList(),!1}),$(".q-sel a",a).on("click",function(){var e=$(this),t=e.attr("data-name"),a=e.attr("data-id"),s={name:t,id:a},l=function(e){i._loadParentTree(e,function(){i._checkCheckBox(a)})};return $("#id_"+a).length?$("#id_"+a).prop("checked",!0).trigger("change"):n(s,i.opt.getParentUrl,l),!1}),$("."+h,a).on("click",function(){return i.applyHandler(this),!1}),d.siblings("."+i.opt.clearAllButtonClass).on("click",function(){i.resetList(),EXPO.searchBlock.placesField.clearValue()})})};c.prototype={_getAjax:function(e,t){var i=this;e||(e=""),$.ajax({type:"GET",url:i.opt.ajaxUrl,data:e,success:function(e){return"function"!=typeof t?(i.rawData=e,e):(i.rawData=e,void t(e))}})},_renderSublist:function(e,t,i){var n=this,a=0,s=t+"-sub",l=function(e){if(e.length){for(n.curDNA[s]={},a;a2&&o?s.timeout=setTimeout(function(){n({term:t,form:l},s.opt.autoCompleteUrl,d),o=!1},1e3):0!=t.length||o||s.$inputFilter.hasClass("ui-autocomplete-input")&&(s.$inputFilter.autocomplete("destroy"),o=!0),!1}).click(function(){return!1})},_loadParentTree:function(e,t,i){var n,a,l,o,c=this,d=e,h=$("#id_"+d.id),u=function(e){var n=$("#id_"+d.id),h=0,u=function(e){r.hide(),h++,h==e&&(i||0===i?t(i):t())};r.hide(),n.length&&s(c.curDNA[a+"-sub"])==e&&(l={name:d.name,id:d.id},r.show(),o=$("#id_"+d.id).closest(".level").children(".trigger").attr("data-template-id"),c._renderNested(l,u,o,d.id))},p=function(){r.hide(),i||0===i?t(i):t()};r.show(),d.hasOwnProperty("parent")?h.length?(l={name:d.name,id:d.id},o=h.closest(".level").children(".trigger").attr("data-template-id"),c._renderNested(l,function(){r.hide(),t()},o,d.id)):(n={name:d.parent.name,id:d.parent.id},a=$("#id_"+d.parent.id).closest(".level").children(".trigger").attr("data-template-id"),c._renderSublist(n,a,u)):(n={name:d.name,id:d.id},a=$("#id_"+d.id).closest(".level").children(".trigger").attr("data-template-id"),c._renderSublist(n,a,p))},applyHandler:function(e){console.log(this)},_refreshText:function(){var e,t=$("#"+this.opt.modalTrigger),i=16;e=l(this.opt.selectedItemsContainer,i),e&&"~~text~~"!=e&&"~~text~~..."!=e?(t.text(e),t.siblings("."+this.opt.clearAllButtonClass).addClass("active")):(t.text(t.data("default")),t.siblings("."+this.opt.clearAllButtonClass).removeClass("active"))}};var d=function(e){this.opt=e;var t,i=this,n=$("#"+i.opt.dateFrom),a=$("#"+i.opt.dateTo),s=$("#"+i.opt.id),l=$("#"+i.opt.modalTrigger),r=i.opt.applyBtnClass,o=function(){var e="",t=l.data("lng-to"),i=l.data("lng-from"),s=$.trim(a.val()),r=$.trim(n.val());return""!=s&&""!=r?e=$(window).width()<1086?i+": "+r+"
    "+t+": "+s+".":i+": "+r+" "+t+": "+s+".":""!=s&&""==r?e=t+": "+s+".":""==s&&""!=r&&(e=i+": "+r+"."),e},c=function(e){var t=24;$(window).width()<1086&&(t=6),""!=e?(l.html(e).siblings(".trigger-label").addClass("hidden"),l.siblings("."+i.opt.clearAllButtonClass).addClass("active")):(l.html(l.data("default")).siblings(".trigger-label").removeClass("hidden"),l.siblings("."+i.opt.clearAllButtonClass).removeClass("active"))},d=function(e){var t,s,l,r,o=e.getAttribute("id"),c=e.value,d=Date.parse(c);i.validate()&&($(e).parent(".pwf-field").removeClass("err"),o==i.opt.dateFrom?(t=a[0].getAttribute("id"),s=a[0].value):(t=n[0].getAttribute("id"),s=n[0].value),l=Date.parse(s),d>l&&o==i.opt.dateFrom?(r=document.getElementById(o).value,document.getElementById(o).value=document.getElementById(t).value,document.getElementById(t).value=r):l>d&&o==i.opt.dateTo&&(r=document.getElementById(t).value,document.getElementById(t).value=document.getElementById(o).value,document.getElementById(o).value=r))};this.$dateFrom=n,this.$dateTo=a,this.$modalTrigger=l,$(function(){$.datepicker.setDefaults($.datepicker.regional.ru),n.datepicker({dateFormat:"dd.mm.yy",showOn:"button",showOtherMonths:!0,constrainInput:!0,onClose:function(e){a.datepicker("option","minDate",e)}}).inputmask("99.99.9999",{showMaskOnHover:!1,insertMode:!1,oncomplete:function(){t=this}}),a.datepicker({dateFormat:"dd.mm.yy",showOn:"button",showOtherMonths:!0,constrainInput:!0,onClose:function(e){n.datepicker("option","maxDate",e)}}).inputmask("99.99.9999",{showMaskOnHover:!1,insertMode:!1,oncomplete:function(){t=this}}),$('input[type="text"]',s).on("change",function(){var e=o();i.validate()&&c(e)}),$("."+r,s).on("click",function(){return t&&d(t),i.applyHandler(this),!1}),l.siblings("."+i.opt.clearAllButtonClass).on("click",function(){$(this).removeClass("active"),i.resetList()})})};d.prototype={resetList:function(){this.$dateFrom.val(""),this.$dateTo.val(""),this.$modalTrigger.text(this.$modalTrigger.attr("data-default"))},validate:function(){var e=this.$dateTo.val(),t=this.$dateFrom.val(),i=e.split("."),n=t.split("."),a=[],s=!0;return a[0]=Date.parse(i[1]+"."+i[0]+"."+i[2]),a[1]=Date.parse(n[1]+"."+n[0]+"."+n[2]),a[0]||""==$.trim(e)?this.$dateTo.parent(".pwf-field").removeClass("err"):(this.$dateTo.parent(".pwf-field").addClass("err"),s=!1),a[1]||""==$.trim(t)?this.$dateFrom.parent(".pwf-field").removeClass("err"):(this.$dateFrom.parent(".pwf-field").addClass("err"),s=!1),s},applyHandler:function(e){}};var h=function(e){this.opt=e,this.opt.anyChar=!1;var i=this,s=!0;this.$field=$("#"+i.opt.id),this.DOMcompleteWrap=document.getElementById(i.opt.autoCompleteWrapId),this.afterClear,this.rawData={items:[],set:function(e){this.items=e,this._rawDataChange()},get:function(){return this.items},_rawDataChange:function(e){var t,i=this;for(t=0;t2?i.timeout=setTimeout(function(){n(a,i.opt.autoCompleteUrl,function(e){i.$field.hasClass("ui-autocomplete-input")&&i.$field[i.completeName]("destroy"),i.rawData.set(e),i._initAutoComplete(),i.showList("")})},1e3):0===text.length&&i.$field.hasClass("ui-autocomplete-input")&&(i.$field[i.completeName]("destroy"),t.removeClass(i.DOMcompleteWrap,"full-visible"),i._resetmodals(i.afterClear)):text.length>2&&s?i.timeout=setTimeout(function(){n(a,i.opt.autoCompleteUrl,function(e){i.rawData.set(e),i._initAutoComplete(),i.showList("")}),s=!1},1e3):0!=text.length||s?i.$field.hasClass("ui-autocomplete-input")&&i.showList(text):i.$field.hasClass("ui-autocomplete-input")&&(i.$field[i.completeName]("destroy"),t.removeClass(i.DOMcompleteWrap,"full-visible"),i._resetmodals(i.afterClear),s=!0),!1}).click(function(){return!1})};return h.prototype={_initAutoComplete:function(){var e=this;e.$field[e.completeName]({source:e.rawData.get(),minLength:0,appendTo:e.DOMcompleteWrap,select:function(t,i){e._afterSelect(t,i)},close:function(){t.removeClass(e.DOMcompleteWrap,"full-visible")},open:function(){t.addClass(e.DOMcompleteWrap,"full-visible")}})},_afterSelect:function(e,t){var i=this;e.preventDefault(),t.item.url?window.location=t.item.url:t.item.label.length&&(i.$field[0].value=t.item.label,i.selectCheckBoxes(t.item.id,t.item.name))},_resetmodals:function(e){return e?void e():0},selectHandler:function(){},selectCheckBoxes:function(e,t){},showList:function(e){self=this,this.$field[self.completeName]("search",e)},pullData:function(e){},clearValue:function(){this.$field.val("")}},e.init=function(e){$.extend(this.lang,e.lang),e.lang=null,$.extend(this.settings,e);var i=this,a=function(){$(i.DOMform).find('input[name="~~name~~"]').remove()};"None"!=this.settings.searchData&&this.settings.searchData&&(this.previousSearch=JSON.parse(this.settings.searchData)),this.DOMform=document.getElementById(this.settings.formId),$(this.DOMform).on("submit",function(){a()}),$.widget("custom.exibitionComplete",$.ui.autocomplete,{_renderMenu:function(e,t){var i=this,n="";$.each(t,function(t,a){a.cat!=n&&a.cat&&(e.append("
  • "+a.cat+"
  • "),n=a.cat),i._renderItemData(e,a)})}}),$.widget("custom.exibitionComplete",$.ui.autocomplete,{_renderMenu:function(e,t){var i=this,n="";$.each(t,function(t,a){a.cat!=n&&a.cat&&(e.append("
  • "+a.cat+"
  • "),n=a.cat),i._renderItemData(e,a)})}}),$.widget("custom.placeComplete",$.ui.autocomplete,{_renderItem:function(e,t){return $("
  • ").append($("").text(t.label)).append(' ('+t.cat+")").appendTo(e)}}),this.exhibitionField=new h(i.settings.firstField),this.exhibitionField.completeName="exibitionComplete",this.exhibitionField.opt.anyChar=!0,this.placesModal=new c(i.settings.place),this.subjModal=new o(i.settings.subject),this.periodModal=new d(i.settings.period),this.exhibitionField.selectCheckBoxes=function(e,t){var i,a,s=this,l=t;"th"==t?i=document.getElementById(s.opt.prefix+e):"tg"==t&&(i=document.getElementById(s.opt.prefixInner+e),l="th"),r.show(),i?(r.hide(),EXPO.searchBlock.subjModal.resetList(),$(i).prop("checked",!0),$(i).trigger("change")):(a={name:t,id:e},EXPO.searchBlock.subjModal.resetList(),n(a,EXPO.searchBlock.subjModal.opt.getParentUrl,function(i){EXPO.searchBlock.subjModal._loadParentTree(i,function(){EXPO.searchBlock.subjModal._checkCheckBox(e,t)})}))},this.placesField=new h(i.settings.placeField),this.placesField.dataForm=EXPO.searchBlock.placesModal.$inputFilter.attr("data-form"),this.placesField.selectCheckBoxes=function(e,t){var i,a,s=this;i=document.getElementById(s.opt.prefix+e),i?(r.hide(),EXPO.searchBlock.placesModal.resetList(),$(i).prop("checked",!0),$(i).trigger("change")):(a={name:t,id:e},EXPO.searchBlock.placesModal.resetList(),n(a,EXPO.searchBlock.placesModal.opt.getParentUrl,function(t){EXPO.searchBlock.placesModal._loadParentTree(t,function(){EXPO.searchBlock.placesModal._checkCheckBox(e,!0)})}))},this.exhibitionField.afterClear=function(){i.subjModal.resetList()},this.placesField.afterClear=function(){i.placesModal.resetList()},this.modalWindow=new t.Modal(i.settings.modal),this.periodModal.applyHandler=function(){this.validate()&&(r.show(),$(i.DOMform).submit())},this.placesModal.applyHandler=function(){r.show(),$(i.DOMform).submit()},this.subjModal.applyHandler=function(){r.show(),$(i.DOMform).submit()},$("."+i.settings.modalTriggerClass).on("click",function(e){return e.preventDefault(),i.modalWindow.pullData(this.getAttribute("href")),i.modalWindow.open(),!1}),$(function(){if(i.previousSearch)for(var e=0;e2?$element.eq(0).text().length2&&d?l.timeout=setTimeout(function(){n({term:t,form:o},l.opt.autoCompleteUrl,u),d=!1},1e3):0!=t.length||d||l.$inputFilter.hasClass("ui-autocomplete-input")&&(l.$inputFilter.placeComplete("destroy"),d=!0),!1}).click(function(){return!1})},_renderSublist:function(e,t,i){var n=this,a=0,s=t+"-sub",l=function(e){if(e.length){for(n.sublist[s]={},a;aS;S++)for(o=y[S],I=0;w>I;I++)o==_[I]&&q(i[I]);for(S=0;x>S;S++)o=y[S],o==T&&q(e);k.querySelectorAll(".final-tire")&&$("."+a+"."+l,k.querySelectorAll(".final-tire")).each(function(){q($("."+d,this)[0])})}else for(S=0;x>S;S++)o=y[S],o==T&&q(T)},q=function(e){var t=e.getAttribute("id");i._destroyTag(t),j()},E=function(e){var n=t.closest(e,s),a=n.querySelector("."+f),l="",r=e.getAttribute("id"),o={};l=a.innerHTML,o={id:r,text:l},i._addTag(r,o),j()},j=function(){o.find("."+m).length&&"~~id~~"!=o.find("."+m)[0].getAttribute(g)?o.addClass("visible"):o.removeClass("visible")},N=function(e){var t=$(e).children("li").children("."+a).find("."+d+":checked");t.each(function(){E(this)})},L=function(){var e=$(b).children("li").children("."+a).find("."+d+":checked");e.each(function(){q(this)})};i.strictMode?this.checked?(F(this),P(this),E(this)):(M(this),P(this),q(this)):this.checked?($(_).find("."+d)[0]&&_&&"~~id~~"!=$(_).find("."+d)[0].value&&P(this),O()?(I(this),F(this),P(C),E(C),L(b),C.getAttribute("id")!=x.getAttribute("id")||x.checked?A()&&(F(x),P(x),E(x)):(F(x),P(x),E(x))):(F(this),P(this),E(this)),_&&T(this)):(D()?(B(this),M(this),P(C),q(C),N(b),x.checked&&(M(x),q(x),N(w))):(M(this),P(this),q(this)),_&&(S(this),P(this))),p()}),$(".csbs-del",o).on("click",function(){var e=$(this).attr("data-checkbox-id"),t=$("#"+e);return t.prop("checked",!1),t.trigger("change"),dna.destroy(i.itemsSelected[e]),o.children(".dna-clone").length||o.removeClass("visible"),!1}),$(".modal-clear",a).on("click",function(){return i.resetList(),!1}),$(".q-sel a",a).on("click",function(){var e=$(this),t=e.attr("data-name"),a=e.attr("data-id"),s={name:t,id:a},l=function(e){i._loadParentTree(e,function(){i._checkCheckBox(a)})};return $("#id_"+a).length?$("#id_"+a).prop("checked",!0).trigger("change"):n(s,i.opt.getParentUrl,l),!1}),$("."+h,a).on("click",function(){return i.applyHandler(this),!1}),d.siblings("."+i.opt.clearAllButtonClass).on("click",function(){i.resetList(),EXPO.searchBlock.placesField.clearValue()})})};c.prototype={_getAjax:function(e,t){var i=this;e||(e=""),$.ajax({type:"GET",url:i.opt.ajaxUrl,data:e,success:function(e){return"function"!=typeof t?(i.rawData=e,e):(i.rawData=e,void t(e))}})},_renderSublist:function(e,t,i){var n=this,a=0,s=t+"-sub",l=function(e){if(e.length){for(n.curDNA[s]={},a;a2&&o?s.timeout=setTimeout(function(){n({term:t,form:l},s.opt.autoCompleteUrl,d),o=!1},1e3):0!=t.length||o||s.$inputFilter.hasClass("ui-autocomplete-input")&&(s.$inputFilter.autocomplete("destroy"),o=!0),!1}).click(function(){return!1})},_loadParentTree:function(e,t,i){var n,a,l,o,c=this,d=e,h=$("#id_"+d.id),u=function(e){var n=$("#id_"+d.id),h=0,u=function(e){r.hide(),h++,h==e&&(i||0===i?t(i):t())};r.hide(),n.length&&s(c.curDNA[a+"-sub"])==e&&(l={name:d.name,id:d.id},r.show(),o=$("#id_"+d.id).closest(".level").children(".trigger").attr("data-template-id"),c._renderNested(l,u,o,d.id))},p=function(){r.hide(),i||0===i?t(i):t()};r.show(),d.hasOwnProperty("parent")?h.length?(l={name:d.name,id:d.id},o=h.closest(".level").children(".trigger").attr("data-template-id"),c._renderNested(l,function(){r.hide(),t()},o,d.id)):(n={name:d.parent.name,id:d.parent.id},a=$("#id_"+d.parent.id).closest(".level").children(".trigger").attr("data-template-id"),c._renderSublist(n,a,u)):(n={name:d.name,id:d.id},a=$("#id_"+d.id).closest(".level").children(".trigger").attr("data-template-id"),c._renderSublist(n,a,p))},applyHandler:function(e){console.log(this)},_refreshText:function(){var e,t=$("#"+this.opt.modalTrigger),i=16;e=l(this.opt.selectedItemsContainer,i),e&&"~~text~~"!=e&&"~~text~~..."!=e?(t.text(e),t.siblings("."+this.opt.clearAllButtonClass).addClass("active")):(t.text(t.data("default")),t.siblings("."+this.opt.clearAllButtonClass).removeClass("active"))}};var d=function(e){this.opt=e;var t,i=this,n=$("#"+i.opt.dateFrom),a=$("#"+i.opt.dateTo),s=$("#"+i.opt.id),l=$("#"+i.opt.modalTrigger),r=i.opt.applyBtnClass,o=function(){var e="",t=l.data("lng-to"),i=l.data("lng-from"),s=$.trim(a.val()),r=$.trim(n.val());return""!=s&&""!=r?e=$(window).width()<1086?i+": "+r+"
    "+t+": "+s+".":i+": "+r+" "+t+": "+s+".":""!=s&&""==r?e=t+": "+s+".":""==s&&""!=r&&(e=i+": "+r+"."),e},c=function(e){var t=24;$(window).width()<1086&&(t=6),""!=e?(l.html(e).siblings(".trigger-label").addClass("hidden"),l.siblings("."+i.opt.clearAllButtonClass).addClass("active")):(l.html(l.data("default")).siblings(".trigger-label").removeClass("hidden"),l.siblings("."+i.opt.clearAllButtonClass).removeClass("active"))},d=function(e){var t,s,l,r,o=e.getAttribute("id"),c=e.value,d=Date.parse(c);i.validate()&&($(e).parent(".pwf-field").removeClass("err"),o==i.opt.dateFrom?(t=a[0].getAttribute("id"),s=a[0].value):(t=n[0].getAttribute("id"),s=n[0].value),l=Date.parse(s),d>l&&o==i.opt.dateFrom?(r=document.getElementById(o).value,document.getElementById(o).value=document.getElementById(t).value,document.getElementById(t).value=r):l>d&&o==i.opt.dateTo&&(r=document.getElementById(t).value,document.getElementById(t).value=document.getElementById(o).value,document.getElementById(o).value=r))};this.$dateFrom=n,this.$dateTo=a,this.$modalTrigger=l,$(function(){$.datepicker.setDefaults($.datepicker.regional.ru),n.datepicker({dateFormat:"dd.mm.yy",showOn:"button",showOtherMonths:!0,constrainInput:!0,onClose:function(e){a.datepicker("option","minDate",e)}}).inputmask("99.99.9999",{showMaskOnHover:!1,insertMode:!1,oncomplete:function(){t=this}}),a.datepicker({dateFormat:"dd.mm.yy",showOn:"button",showOtherMonths:!0,constrainInput:!0,onClose:function(e){n.datepicker("option","maxDate",e)}}).inputmask("99.99.9999",{showMaskOnHover:!1,insertMode:!1,oncomplete:function(){t=this}}),$('input[type="text"]',s).on("change",function(){var e=o();i.validate()&&c(e)}),$("."+r,s).on("click",function(){return t&&d(t),i.applyHandler(this),!1}),l.siblings("."+i.opt.clearAllButtonClass).on("click",function(){$(this).removeClass("active"),i.resetList()})})};d.prototype={resetList:function(){this.$dateFrom.val(""),this.$dateTo.val(""),this.$modalTrigger.text(this.$modalTrigger.attr("data-default"))},validate:function(){var e=this.$dateTo.val(),t=this.$dateFrom.val(),i=e.split("."),n=t.split("."),a=[],s=!0;return a[0]=Date.parse(i[1]+"."+i[0]+"."+i[2]),a[1]=Date.parse(n[1]+"."+n[0]+"."+n[2]),a[0]||""==$.trim(e)?this.$dateTo.parent(".pwf-field").removeClass("err"):(this.$dateTo.parent(".pwf-field").addClass("err"),s=!1),a[1]||""==$.trim(t)?this.$dateFrom.parent(".pwf-field").removeClass("err"):(this.$dateFrom.parent(".pwf-field").addClass("err"),s=!1),s},applyHandler:function(e){}};var h=function(e){this.opt=e,this.opt.anyChar=!1;var i=this,s=!0;this.$field=$("#"+i.opt.id),this.DOMcompleteWrap=document.getElementById(i.opt.autoCompleteWrapId),this.afterClear,this.rawData={items:[],set:function(e){this.items=e,this._rawDataChange()},get:function(){return this.items},_rawDataChange:function(e){var t,i=this;for(t=0;t2?i.timeout=setTimeout(function(){n(a,i.opt.autoCompleteUrl,function(e){i.$field.hasClass("ui-autocomplete-input")&&i.$field[i.completeName]("destroy"),i.rawData.set(e),i._initAutoComplete(),i.showList("")})},1e3):0===text.length&&i.$field.hasClass("ui-autocomplete-input")&&(i.$field[i.completeName]("destroy"),t.removeClass(i.DOMcompleteWrap,"full-visible"),i._resetmodals(i.afterClear)):text.length>2&&s?i.timeout=setTimeout(function(){n(a,i.opt.autoCompleteUrl,function(e){i.rawData.set(e),i._initAutoComplete(),i.showList("")}),s=!1},1e3):0!=text.length||s?i.$field.hasClass("ui-autocomplete-input")&&i.showList(text):i.$field.hasClass("ui-autocomplete-input")&&(i.$field[i.completeName]("destroy"),t.removeClass(i.DOMcompleteWrap,"full-visible"),i._resetmodals(i.afterClear),s=!0),!1}).click(function(){return!1})};return h.prototype={_initAutoComplete:function(){var e=this;e.$field[e.completeName]({source:e.rawData.get(),minLength:0,appendTo:e.DOMcompleteWrap,select:function(t,i){e._afterSelect(t,i)},close:function(){t.removeClass(e.DOMcompleteWrap,"full-visible")},open:function(){t.addClass(e.DOMcompleteWrap,"full-visible")}})},_afterSelect:function(e,t){var i=this;e.preventDefault(),t.item.url?window.location=t.item.url:t.item.label.length&&(i.$field[0].value=t.item.label,i.selectCheckBoxes(t.item.id,t.item.name))},_resetmodals:function(e){return e?void e():0},selectHandler:function(){},selectCheckBoxes:function(e,t){},showList:function(e){self=this,this.$field[self.completeName]("search",e)},pullData:function(e){},clearValue:function(){this.$field.val("")}},e.init=function(e){$.extend(this.lang,e.lang),e.lang=null,$.extend(this.settings,e);var i=this,a=function(){$(i.DOMform).find('input[name="~~name~~"]').remove()};"None"!=this.settings.searchData&&this.settings.searchData&&(this.previousSearch=JSON.parse(this.settings.searchData)),this.DOMform=document.getElementById(this.settings.formId),$(this.DOMform).on("submit",function(){a()}),$.widget("custom.exibitionComplete",$.ui.autocomplete,{_renderMenu:function(e,t){var i=this,n="";$.each(t,function(t,a){a.cat!=n&&a.cat&&(e.append("
  • "+a.cat+"
  • "),n=a.cat),i._renderItemData(e,a)})}}),$.widget("custom.exibitionComplete",$.ui.autocomplete,{_renderMenu:function(e,t){var i=this,n="";$.each(t,function(t,a){a.cat!=n&&a.cat&&(e.append("
  • "+a.cat+"
  • "),n=a.cat),i._renderItemData(e,a)})}}),$.widget("custom.placeComplete",$.ui.autocomplete,{_renderItem:function(e,t){return $("
  • ").append($("").text(t.label)).append(' ('+t.cat+")").appendTo(e)}}),this.exhibitionField=new h(i.settings.firstField),this.exhibitionField.completeName="exibitionComplete",this.exhibitionField.opt.anyChar=!0,this.placesModal=new c(i.settings.place),this.subjModal=new o(i.settings.subject),this.periodModal=new d(i.settings.period),this.exhibitionField.selectCheckBoxes=function(e,t){var i,a,s=this,l=t;"th"==t?i=document.getElementById(s.opt.prefix+e):"tg"==t&&(i=document.getElementById(s.opt.prefixInner+e),l="th"),r.show(),i?(r.hide(),EXPO.searchBlock.subjModal.resetList(),$(i).prop("checked",!0),$(i).trigger("change")):(a={name:t,id:e},EXPO.searchBlock.subjModal.resetList(),n(a,EXPO.searchBlock.subjModal.opt.getParentUrl,function(i){EXPO.searchBlock.subjModal._loadParentTree(i,function(){EXPO.searchBlock.subjModal._checkCheckBox(e,t)})}))},this.placesField=new h(i.settings.placeField),this.placesField.dataForm=EXPO.searchBlock.placesModal.$inputFilter.attr("data-form"),this.placesField.selectCheckBoxes=function(e,t){var i,a,s=this;i=document.getElementById(s.opt.prefix+e),i?(r.hide(),EXPO.searchBlock.placesModal.resetList(),$(i).prop("checked",!0),$(i).trigger("change")):(a={name:t,id:e},EXPO.searchBlock.placesModal.resetList(),n(a,EXPO.searchBlock.placesModal.opt.getParentUrl,function(t){EXPO.searchBlock.placesModal._loadParentTree(t,function(){EXPO.searchBlock.placesModal._checkCheckBox(e,!0)})}))},this.exhibitionField.afterClear=function(){i.subjModal.resetList()},this.placesField.afterClear=function(){i.placesModal.resetList()},this.modalWindow=new t.Modal(i.settings.modal),this.periodModal.applyHandler=function(){this.validate()&&(r.show(),$(i.DOMform).submit())},this.placesModal.applyHandler=function(){r.show(),$(i.DOMform).submit()},this.subjModal.applyHandler=function(){r.show(),$(i.DOMform).submit()},$("."+i.settings.modalTriggerClass).on("click",function(e){return e.preventDefault(),i.modalWindow.pullData(this.getAttribute("href")),i.modalWindow.open(),!1}),$(function(){if(i.previousSearch)for(var e=0;e - function updateTextFields(elem){ - if ($(elem).data('insertedText')) + function updateTextFields(elem){ + if ($(elem).data('insertedText')) elem.text($(this).data('insertedText')) - }; + }; + + + + +
    + + + {% trans 'Уточнить тему' %} + {% if hasDate %}{% trans 'Уточнить дату' %}{% endif %} +
    + +