From e78f8c803efd8b6b87654925aac6e2ca86852d09 Mon Sep 17 00:00:00 2001 From: Bruno Da Silva Date: Mon, 26 Mar 2018 09:10:33 +0000 Subject: [PATCH] search widget : between operator bugfixes SVN:b1162[5526] --- dictionaries/en.dictionary.itop.ui.php | 7 + .../search_form_criteria_date_abstract.js | 176 ++++++++++++------ js/search/search_form_criteria_numeric.js | 95 +++++++++- 3 files changed, 209 insertions(+), 69 deletions(-) diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index 0b0e4815f..5b7e78511 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -1427,6 +1427,9 @@ When associated with a trigger, each action is given an "order" number, specifyi 'UI:Search:Criteria:Title:Default:BetweenDates:All' => '%1$s All', 'UI:Search:Criteria:Title:Default:BetweenDates:From' => '%1$s From %2$s', 'UI:Search:Criteria:Title:Default:BetweenDates:Until' => '%1$s Until %2$s', + 'UI:Search:Criteria:Title:Default:Between:All' => '%1$s All', + 'UI:Search:Criteria:Title:Default:Between:From' => '%1$s From %2$s', + 'UI:Search:Criteria:Title:Default:Between:Until' => '%1$s Until %2$s', 'UI:Search:Criteria:Title:Default:BetweenDays' => '%1$s [%2$s]', // - String widget 'UI:Search:Criteria:Title:String:Contains' => '%1$s contains %2$s', @@ -1453,6 +1456,10 @@ When associated with a trigger, each action is given an "order" number, specifyi 'UI:Search:Value:Toggler:CheckAllNone' => 'Check all / none', // - Widget other translations + 'UI:Search:Criteria:Numeric:From' => 'From', + 'UI:Search:Criteria:Numeric:Until' => 'Until', + 'UI:Search:Criteria:Numeric:PlaceholderFrom' => 'Any', + 'UI:Search:Criteria:Numeric:PlaceholderUntil' => 'Any', 'UI:Search:Criteria:DateTime:From' => 'From', 'UI:Search:Criteria:DateTime:FromTime' => 'From', 'UI:Search:Criteria:DateTime:Until' => 'Until', diff --git a/js/search/search_form_criteria_date_abstract.js b/js/search/search_form_criteria_date_abstract.js index 76f14ce4b..16920add2 100644 --- a/js/search/search_form_criteria_date_abstract.js +++ b/js/search/search_form_criteria_date_abstract.js @@ -71,7 +71,7 @@ $(function() var oInputElem = oOpContentElem .find('input') .uniqueId() - .attr('data-no-auto-focus', true) + //.attr('data-no-auto-focus', true) ; oOpContentElem .find('label') @@ -87,14 +87,7 @@ $(function() } - // // Events - // // - Focus input on click (radio, label, ...) - // oOpElem.on('click', function(oEvent){ - // if ($(oEvent.target).is('input[type="text"], select')) { - // return; - // } - // oOpElem.find('input:visible:first').filter('[data-no-auto-focus]').focus(); - // }); + // - Apply on "enter" key hit //todo: this could be refactored oOpContentElem.on('keyup', function(oEvent){ @@ -129,66 +122,122 @@ $(function() buttonImage: GetAbsoluteUrlAppRoot()+"/images/calendar.png", buttonImageOnly: true, buttonText: "", - showOn:'both' + showOn:'button', + changeMonth:true, + changeYear:true lF }; for (var i = 0; i < aInputsParamLength; i++) { var oInputParam = aInputsParam[i]; - var odatetimepickerOptions = $.extend({}, odatetimepickerOptionsDefault, { - onClose: function(dateText, inst) { - var selectElem = $(this); - var sOnCLoseShow = selectElem.data('onclose_show'); + var fHandleSynchCallback = function(select, bSetDate) { + var selectElem = $(select); + var sSyncedWith = selectElem.data('synced_with'); + var oInputParam = selectElem.data('oInputParam'); - // if (typeof oInputParam.onclose_show != 'undefined') - // { - // oOpElem.find('input[name="'+oInputParam.onclose_show+'"]') - // [oInputParam.x_picker]('show') - // ; - // } + if (bSetDate) + { + selectElem[oInputParam.x_picker]('setDate', null); + } - // if (sOnCLoseShow != undefined && selectElem.is(':visible')) - // { - // var oOnCLoseShowInputElem = oOpElem.find('input[name="'+sOnCLoseShow+'"]'); - // oOnCLoseShowInputElem[oInputParam.x_picker]('show'); - // } + if (sSyncedWith != undefined) + { + var sCode = selectElem.data('code'); + var oInputParam = aInputsParam[oInputsParamIndexByCode[sCode]]; + var oSyncedInputParam = aInputsParam[oInputsParamIndexByCode[sSyncedWith]]; + var oSyncedInputElem = oOpElem.find('input[name="'+sSyncedWith+'"]'); - }, - onSelect: function(sDateText, oXPicker) { - var selectElem = $(this); - var sSyncedWith = selectElem.data('synced_with'); + var dSyncedDate = selectElem[oInputParam.x_picker]('getDate'); - - if (sSyncedWith != undefined) + if (null == dSyncedDate) { - var sCode = selectElem.data('code'); - var oInputParam = aInputsParam[oInputsParamIndexByCode[sCode]]; - var oSyncedInputParam = aInputsParam[oInputsParamIndexByCode[sSyncedWith]]; - var oSyncedInputElem = oOpElem.find('input[name="'+sSyncedWith+'"]'); - - var dSyncedDate = selectElem[oInputParam.x_picker]('getDate'); - - if (null == dSyncedDate) + // oSyncedInputElem.val(''); + oSyncedInputElem[oSyncedInputParam.x_picker]('setDate', null); + } + else + { + if (typeof oSyncedInputParam.default_time_add != 'undefined' && oSyncedInputParam.default_time_add) { - oSyncedInputElem.val(''); + dSyncedDate.setSeconds(dSyncedDate.getSeconds() + oSyncedInputParam.default_time_add); } - else - { - if (typeof oSyncedInputParam.default_time_add != 'undefined' && oSyncedInputParam.default_time_add) - { - dSyncedDate.setSeconds(dSyncedDate.getSeconds() + oSyncedInputParam.default_time_add); - } - oSyncedInputElem[oSyncedInputParam.x_picker]('setDate', dSyncedDate); - } - + oSyncedInputElem[oSyncedInputParam.x_picker]('setDate', dSyncedDate); } - me._apply(); } + + //me._apply(); + selectElem[oInputParam.x_picker]('hide'); + }; + + var odatetimepickerOptions = $.extend({}, odatetimepickerOptionsDefault, { + onSelect: function() { + fHandleSynchCallback(this, false); + $(this).focus(); + } + // onClose: function(dateText, inst) { + // var selectElem = $(this); + // var sOnCLoseShow = selectElem.data('onclose_show'); + // + // // if (typeof oInputParam.onclose_show != 'undefined') + // // { + // // oOpElem.find('input[name="'+oInputParam.onclose_show+'"]') + // // [oInputParam.x_picker]('show') + // // ; + // // } + // + // // if (sOnCLoseShow != undefined && selectElem.is(':visible')) + // // { + // // var oOnCLoseShowInputElem = oOpElem.find('input[name="'+sOnCLoseShow+'"]'); + // // oOnCLoseShowInputElem[oInputParam.x_picker]('show'); + // // } + // + // }, + // onSelect: function(sDateText, oXPicker) { + // var selectElem = $(this); + // var sSyncedWith = selectElem.data('synced_with'); + // + // + // if (sSyncedWith != undefined) + // { + // var sCode = selectElem.data('code'); + // var oInputParam = aInputsParam[oInputsParamIndexByCode[sCode]]; + // var oSyncedInputParam = aInputsParam[oInputsParamIndexByCode[sSyncedWith]]; + // var oSyncedInputElem = oOpElem.find('input[name="'+sSyncedWith+'"]'); + // + // var dSyncedDate = selectElem[oInputParam.x_picker]('getDate'); + // + // if (null == dSyncedDate) + // { + // oSyncedInputElem.val(''); + // } + // else + // { + // if (typeof oSyncedInputParam.default_time_add != 'undefined' && oSyncedInputParam.default_time_add) + // { + // dSyncedDate.setSeconds(dSyncedDate.getSeconds() + oSyncedInputParam.default_time_add); + // } + // oSyncedInputElem[oSyncedInputParam.x_picker]('setDate', dSyncedDate); + // } + // + // } + // + // //me._apply(); + // selectElem[oInputParam.x_picker]('hide'); + // } }); + + var oInputElem = oOpElem.find('input[name="'+oInputParam.code+'"]'); oInputElem.data('code', oInputParam.code); oInputElem.data('onclose_show', oInputParam.onclose_show); + oInputElem.data('oInputParam', oInputParam); + oInputElem.on('keydown', function(oEvent) { + // Synch if "enter" key + if(oEvent.key === 'Enter') + { + fHandleSynchCallback(this, true); + } + }); oInputElem[oInputParam.x_picker](odatetimepickerOptions); if (typeof aInputsParam[oInputsParamIndexByCode[oInputParam.synced_with]] != 'undefined') @@ -243,14 +292,15 @@ $(function() if (typeof aValues[oInputParam.value_index] != 'undefined' && typeof aValues[oInputParam.value_index].value != 'undefined') { var sDate = aValues[oInputParam.value_index].value; - var oDate = new Date(aValues[oInputParam.value_index].value); - // switch (true) - // { - // case (i == 0 && sDate.search(/(\s\d{2}:\d{2}:\d{2})/) === -1): - // //if there is no given hour, the GMT offset is appended by javascript, so we need to remove it (if not, we would have our GMT offset add, ie GMT +1 would become "00:01:00" - // oDate = new Date(oDate.valueOf() + oDate.getTimezoneOffset() * 60000); - // } - oInputElem[oInputParam.x_picker]('setDate', oDate); + if (sDate.trim() != '') + { + var oDate = new Date(sDate); + oInputElem[oInputParam.x_picker]('setDate', oDate); + } + else + { + oInputElem[oInputParam.x_picker]('setDate', sDate); + } } } }, @@ -269,7 +319,6 @@ $(function() var me = this; if (sTitle === undefined && me.options.operator == 'between_dates') { - var oActiveOpElem = me.element.find('.sfc_op_radio:checked').closest('.sfc_fg_operator'); var aValues = me._getValues(); switch (true) { @@ -315,11 +364,14 @@ $(function() _getValuesAsText: function(aRawValues) { var me = this; - var aRawValues = undefined; + + if (aRawValues == undefined) + { + aRawValues = me._getValues(); + } if (me.options.operator == 'between_dates') { - var oActiveOpElem = this.element.find('.sfc_op_radio[value="'+me.options.operator+'"]').closest('.sfc_fg_operator'); // me.element.find('.sfc_op_radio:checked').closest('.sfc_fg_operator'); - aRawValues = me._getValues(); + aRawValues = aRawValues.slice();//clone if (typeof aRawValues[1] == 'undefined' || typeof aRawValues[1].label == 'undefined' || aRawValues[1].label == '') { diff --git a/js/search/search_form_criteria_numeric.js b/js/search/search_form_criteria_numeric.js index 543d4ace8..8015e90e3 100644 --- a/js/search/search_form_criteria_numeric.js +++ b/js/search/search_form_criteria_numeric.js @@ -103,20 +103,23 @@ $(function() aValues = me._getValues();//TODO : tenir compte du refactoring de la structure // DOM elements - var oOpContentElemFrom = $('').uniqueId(); - if (0 in aValues && typeof aValues[0].value != 'undefined') + var oOpContentOuterElemFrom = $(''); + var oOpContentElemFrom = oOpContentOuterElemFrom.find('input').uniqueId(); + oOpContentOuterElemFrom.find('label').attr('for', oOpContentElemFrom.attr('id')); + if (typeof aValues[0] != 'undefined' && typeof aValues[0].value != 'undefined') { oOpContentElemFrom.val(aValues[0].value); } - - var oOpContentElemUntil = $('').uniqueId(); - if (1 in aValues && typeof aValues[1].value != 'undefined') + var oOpContentOuterElemUntil = $(''); + var oOpContentElemUntil = oOpContentOuterElemUntil.find('input').uniqueId(); + oOpContentOuterElemUntil.find('label').attr('for', oOpContentElemUntil.attr('id')); + if (typeof aValues[1] != 'undefined' && typeof aValues[1].value != 'undefined') { oOpContentElemUntil.val(aValues[1].value); } - oOpContentElem = $().add(oOpContentElemFrom).add(oOpContentElemUntil); + oOpContentElem = $().add(oOpContentOuterElemFrom).add(oOpContentOuterElemUntil); // Events // - Focus input on click (radio, label, ...) @@ -132,7 +135,12 @@ $(function() me._markAsDraft(); }); - oOpElem.find('.sfc_op_content').append(oOpContentElem); + oOpElem + .find('.sfc_op_name') + .remove() + .end() + .find('.sfc_op_content') + .append(oOpContentElem); }, _getBetweenOperatorValues: function(oOpElem) @@ -176,6 +184,79 @@ $(function() //------------------ + _setTitle: function(sTitle) + { + var me = this; + if (sTitle === undefined && me.options.operator == 'between') + { + var aValues = me._getValues(); + switch (true) + { + case (typeof aValues[0] == 'undefined' && typeof aValues[1] == 'undefined'): + case (typeof aValues[0].label == 'undefined' && typeof aValues[1].label == 'undefined'): + case (aValues[0].label.trim() == '' && aValues[1].label.trim() == ''): + var sDictEntrySuffix = ':All'; + break; + case (typeof aValues[0] == 'undefined' ): + case (typeof aValues[0].label == 'undefined' ): + case (aValues[0].label.trim() == '' ): + var sDictEntrySuffix = ':Until'; + break; + case (typeof aValues[1] == 'undefined'): + case (typeof aValues[1].label == 'undefined' ): + case (aValues[1].label.trim() == ''): + var sDictEntrySuffix = ':From'; + break; + default: + var sDictEntrySuffix = undefined; + break; + } + + if (sDictEntrySuffix != undefined) + { + var sDictEntry = 'UI:Search:Criteria:Title:' + this._toCamelCase(this.options.field.widget) + ':' + this._toCamelCase(me.options.operator) + sDictEntrySuffix ; + // Fallback to default widget dict entry if none exists for the current widget + if(Dict.S(sDictEntry) === sDictEntry) + { + sDictEntry = 'UI:Search:Criteria:Title:Default:' + this._toCamelCase(me.options.operator) + sDictEntrySuffix; + } + + sTitle = Dict.Format(sDictEntry, this.options.field.label, this._getValuesAsText()); + } + + } + + return me._super(sTitle); + }, + + + // - Convert values to a standard string + _getValuesAsText: function(aRawValues) + { + var me = this; + + if (aRawValues == undefined) + { + aRawValues = me._getValues(); + } + if (me.options.operator == 'between') + { + aRawValues = aRawValues.slice(); //clone + if (typeof aRawValues[1] == 'undefined' || typeof aRawValues[1].label == 'undefined' || aRawValues[1].label == '') + { + aRawValues.splice(1, 1); + } + if (typeof aRawValues[0] == 'undefined' || typeof aRawValues[0].label == 'undefined' || aRawValues[0].label == '') + { + aRawValues.splice(0, 1); + } + } + return me._super(aRawValues); + }, + + + + // Prepare operator's DOM element // - Base preparation, always called _prepareOperator: function(oOpElem, sOpIdx, oOp)