diff --git a/js/search/search_form_criteria.js b/js/search/search_form_criteria.js index ef432d7c52..8121e0041d 100644 --- a/js/search/search_form_criteria.js +++ b/js/search/search_form_criteria.js @@ -191,8 +191,8 @@ $(function() // Close criteria this.element.on('itop.search.criteria.close', function(){ - //me._apply(); - return me._close(); + me._apply(); + me._close(); }); this.element @@ -325,8 +325,26 @@ $(function() this.element.find('.sfc_form_group').removeClass('advanced'); }, // - External events + /** + * + * @param oData + * @return {*}|null return oCriteriaData or null if there is no value + * @private + */ _onGetData: function(oData) { + var bHasToReturnNull = true; + this.options.values.forEach(function (oValue) { + if (oValue.value != '') + { + bHasToReturnNull = false; + } + }); + if (bHasToReturnNull) + { + return null; + } + var oCriteriaData = { 'ref': this.options.ref, 'operator': this.options.operator, @@ -358,9 +376,10 @@ $(function() // Bind events // Note: No event to handle criteria closing when clicking outside of it as it is already handle by the form handler. // - Toggler - this.element.find('.sfc_toggle, .sfc_title').on('click', function(oEvent){ + this.element.on('click', '.sfc_toggle, .sfc_title', function(oEvent){ // Prevent anchor oEvent.preventDefault(); + oEvent.stopPropagation(); // First memorize if current criteria is close var bOpen = !me.element.hasClass('opened'); diff --git a/js/search/search_form_criteria_hierarchical_key.js b/js/search/search_form_criteria_hierarchical_key.js index d8e175e2da..600ce906f2 100644 --- a/js/search/search_form_criteria_hierarchical_key.js +++ b/js/search/search_form_criteria_hierarchical_key.js @@ -55,7 +55,11 @@ $(function() _onGetData: function(oData) { var oCriteriaData = this._super(oData); - oCriteriaData.is_hierarchical = this.options.is_hierarchical; + + if (null != oCriteriaData) + { + oCriteriaData.is_hierarchical = this.options.is_hierarchical; + } return oCriteriaData; }, diff --git a/js/search/search_form_handler.js b/js/search/search_form_handler.js index ec6b56e276..b6dd92f430 100644 --- a/js/search/search_form_handler.js +++ b/js/search/search_form_handler.js @@ -104,13 +104,21 @@ $(function() //init others widgets : this.element.search_form_handler_history({'itop_root_class':me.options.search.class_name}); - // Prepare DOM elements + + // Prepare DOM elements this._prepareFormArea(); this._prepareCriterionArea(); this._prepareResultsArea(); // Binding events (eg. from search_form_criteria widgets) this._bindEvents(); + + //memorize the initial state so on first criteria close, we do not trigger a refresh if nothing has changed + this._updateSearch(); + this.oPreviousAjaxParams = JSON.stringify({ + 'base_oql': this.options.search.base_oql, + 'criterion': this.options.search.criterion, + }); }, // called when created, and later when changing options _refresh: function() @@ -232,7 +240,11 @@ $(function() oCriterion['or'][iIdx] = {'and': []}; oCriterionRowElem.find('.search_form_criteria').each(function(){ var oCriteriaData = $(this).triggerHandler('itop.search.criteria.get_data'); - oCriterion['or'][iIdx]['and'].push(oCriteriaData); + + if (null != oCriteriaData) + { + oCriterion['or'][iIdx]['and'].push(oCriteriaData); + } }); }); // - Update search @@ -449,9 +461,6 @@ $(function() // - Close menu on click anywhere else // - Intercept click to avoid propagation (mostly used for closing it when clicking outside of it) $('body').on('click', function(oEvent){ - // Prevent propagation to parents and therefore multiple attempts to close it - oEvent.stopPropagation(); - oEventTargetElem = $(oEvent.target); // If not more menu, close all criterion @@ -465,13 +474,8 @@ $(function() // If using the datetimepicker, do not close anything if (oEventTargetElem.closest('#ui-datepicker-div, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-current').length > 0 ) { - // No closing in this case + // No closing in this edge-case introduced by the use of css3's insertion on content using ::before and ::after that pop directly at the body instead of bubbling normally (and passing by their DOM parents) } - // //if the context is not document, then we have encountered a bug : the css ::after elements do have a context on click and thus, we cannot check if they are inside a #ui-datepicker-div - // else if (typeof oEventTargetElem.context != 'undefined' && $(oEventTargetElem.context).is('.ui-icon')) - // { - // //no closing in this case (bugfix) - // } // If criteria, close more menu & all criterion but me else if(oEventTargetElem.closest('.search_form_criteria').length > 0) { @@ -875,7 +879,7 @@ $(function() this._updateSearch(); if(this.options.auto_submit === true) { - this._submit(); + this._submit(true); } }, _onCriteriaRemoved: function(oData) @@ -954,7 +958,7 @@ $(function() this._submit(); }, // - Do the submit - _submit: function() + _submit: function(bAbortIfNoChange) { var me = this; @@ -979,6 +983,21 @@ $(function() $.extend(oListParams, this.options.list_params); oData.list_params = JSON.stringify(oListParams); + if (true === bAbortIfNoChange) + { + if (typeof me.oPreviousAjaxParams == "undefined") + { + me.oPreviousAjaxParams = oData.params; + return; + } + + if (me.oPreviousAjaxParams == oData.params) + { + return; + } + } + me.oPreviousAjaxParams = oData.params; + // Abort pending request if(this.submit.xhr !== null) {