diff --git a/css/light-grey.css b/css/light-grey.css index a9b815c013..5b9e87631e 100644 --- a/css/light-grey.css +++ b/css/light-grey.css @@ -852,19 +852,24 @@ input.dp-applied { background-color: #eee; color: #2d2d2d; } -.search_form_handler .sf_criterion_area .search_form_criteria .sfc_close, .search_form_handler .sf_criterion_area .search_form_criteria .sfc_toggle { +.search_form_handler .sf_criterion_area .search_form_criteria .sfc_toggle, .search_form_handler .sf_criterion_area .search_form_criteria .sfc_close { position: absolute; top: 7px; color: #e87c1e; } -.search_form_handler .sf_criterion_area .search_form_criteria .sfc_close { - right: 7px; +.search_form_handler .sf_criterion_area .search_form_criteria .sfc_locked { + position: absolute; + top: 9px; + color: #808080; } .search_form_handler .sf_criterion_area .search_form_criteria .sfc_toggle { display: inline-block; right: 23px; transition: all 0.3s ease-in-out; } +.search_form_handler .sf_criterion_area .search_form_criteria .sfc_close, .search_form_handler .sf_criterion_area .search_form_criteria .sfc_locked { + right: 7px; +} .search_form_handler .sf_criterion_area .search_form_criteria .sfc_title { max-width: 240px; padding-right: 30px; @@ -997,6 +1002,8 @@ input.dp-applied { } .search_form_handler .sf_criterion_area .search_form_criteria.search_form_criteria_raw .sfc_title { cursor: initial; + padding-right: 20px; + /* Less than regular as there is no toggle icon */ } .search_form_handler .sf_criterion_area .search_form_criteria.search_form_criteria_raw .sfc_form_group { display: none; @@ -1139,19 +1146,47 @@ input.dp-applied { margin-top: 8px; margin-bottom: 8px; } +.search_form_handler .sf_filter input, .search_form_handler .sf_filter button, .search_form_handler .sf_filter .sff_picto { + vertical-align: middle; + height: 22px; +} +.search_form_handler .sf_filter input, .search_form_handler .sf_filter button { + border: 1px solid #ababab; +} .search_form_handler .sf_filter input { width: 100%; } -.search_form_handler .sf_filter .sff_picto { +.search_form_handler .sf_filter button { + width: 23px; + /* Must be equals to .sf_filter > *:height */ + background-color: #fff; + color: #ea7d1e; + font-size: 10px; +} +.search_form_handler .sf_filter button:first-of-type { + margin-left: 5px; +} +.search_form_handler .sf_filter button:not(:first-of-type) { + border-left: transparent; +} +.search_form_handler .sf_filter .sff_input_wrapper { + position: relative; +} +.search_form_handler .sf_filter .sff_input_wrapper .sff_picto { position: absolute; right: 5px; - top: 5px; + top: 2px; opacity: 0.6; user-select: none; } -.search_form_handler .sf_filter .sff_reset { +.search_form_handler .sf_filter .sff_input_wrapper .sff_reset { display: none; } +.search_form_handler .sf_filter.sf_with_buttons input { + width: initial; + /* Reset the 100% */ + min-width: 120px; +} .sf_results_area .sf_results_placeholder { margin-top: 100px; text-align: center; diff --git a/css/light-grey.scss b/css/light-grey.scss index b45822a47c..f1b1b74123 100644 --- a/css/light-grey.scss +++ b/css/light-grey.scss @@ -953,20 +953,26 @@ input.dp-applied { } /* Top left corner icons */ - .sfc_close, - .sfc_toggle{ + .sfc_toggle, + .sfc_close{ position: absolute; top: 7px; color: $search-criteria-box-picto-color; } - .sfc_close{ - right: 7px; + .sfc_locked{ + position: absolute; + top: 9px; + color: $gray-light; } .sfc_toggle{ display: inline-block; right: 23px; transition: all 0.3s ease-in-out; } + .sfc_close, + .sfc_locked{ + right: 7px; + } .sfc_title{ max-width: 240px; @@ -1142,6 +1148,7 @@ input.dp-applied { } .sfc_title{ cursor: initial; + padding-right: 20px; /* Less than regular as there is no toggle icon */ } .sfc_form_group{ display: none; @@ -1204,7 +1211,8 @@ input.dp-applied { } } - &.search_form_criteria_date_time, &.search_form_criteria_date { + &.search_form_criteria_date_time, + &.search_form_criteria_date { .sfc_form_group.advanced { .sfc_fg_operator_between { margin-bottom: 5px; @@ -1353,18 +1361,53 @@ input.dp-applied { margin-top: 8px; margin-bottom: 8px; + input, + button, + .sff_picto{ + vertical-align: middle; + height: 22px; + } + + input, + button{ + border: 1px solid #ABABAB; + } input{ width: 100%; } - .sff_picto{ - position: absolute; - right: 5px; - top: 5px; - opacity: 0.6; - user-select: none; + button{ + width: 23px; /* Must be equals to .sf_filter > *:height */ + background-color: $white; + color: $combodo-orange; + font-size: 10px; + + &:first-of-type{ + margin-left: 5px; + } + &:not(:first-of-type){ + border-left: transparent; + } } - .sff_reset{ - display: none; + .sff_input_wrapper{ + position: relative; + + .sff_picto{ + position: absolute; + right: 5px; + top: 2px; + opacity: 0.6; + user-select: none; + } + .sff_reset{ + display: none; + } + } + + &.sf_with_buttons{ + input{ + width: initial; /* Reset the 100% */ + min-width: 120px; + } } } } diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index f3aba9a90e..14e3262d9a 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -1453,6 +1453,7 @@ When associated with a trigger, each action is given an "order" number, specifyi // - Other translations 'UI:Search:Value:Filter:Placeholder' => 'Filter...', + 'UI:Search:Value:Search:Placeholder' => 'Search...', 'UI:Search:Value:Toggler:CheckAllNone' => 'Check all / none', // - Widget other translations diff --git a/js/search/search_form_criteria.js b/js/search/search_form_criteria.js index c2ecfede0f..407b1bc3e5 100644 --- a/js/search/search_form_criteria.js +++ b/js/search/search_form_criteria.js @@ -595,7 +595,7 @@ $(function() // Values helpers - // - Check if criteria has allowed values + // - Check if criteria has allowed values either preloaded or through autocomplete _hasAllowedValues: function() { return ( (this.options.field.allowed_values !== undefined) && (this.options.field.allowed_values !== null) ); @@ -615,6 +615,21 @@ $(function() { return (this._hasPreloadedAllowedValues()) ? this.options.field.allowed_values.values : {}; }, + // - Check if criteria has allowed values that should be loaded through autocomplete + _hasAutocompleteAllowedValues: function() + { + if(this._hasAllowedValues() && (this.options.field.allowed_values.autocomplete === true) ) + { + return true; + } + + return false; + }, + // - Return the allowed values from the autocomplete + _getAutocompleteAllowedValues: function() + { + console.log('TODO: Retrieve allowed values through autocomplete (get needle in the input)'); + }, // - Return current values _getValues: function() { diff --git a/js/search/search_form_criteria_enum.js b/js/search/search_form_criteria_enum.js index a3699bc2e2..641aeb17d0 100644 --- a/js/search/search_form_criteria_enum.js +++ b/js/search/search_form_criteria_enum.js @@ -95,12 +95,20 @@ $(function() // - Filter var sFilterId = 'filter_' + sOpId; + var sFilterPlaceholder = (this._hasAutocompleteAllowedValues()) ? Dict.S('UI:Search:Value:Search:Placeholder') : Dict.S('UI:Search:Value:Filter:Placeholder'); var oFilterElem = $('
') - .append('') + .append('') .appendTo(oOpContentElem); // - Allowed values - var oAllowedValuesElem = $(''); + var oAllowedValuesElem = $('') + .appendTo(oOpContentElem); + // - Static values: Always there no matter the field constraints + var oStaticValuesElem = $('') + .appendTo(oAllowedValuesElem); + // - Dynamic values: Depends on the field constraints + var oDynamicValuesElem = $('') + .appendTo(oAllowedValuesElem); // - Null value if allowed // Note: null values is NOT put among the allowed values for two reasons: @@ -114,7 +122,7 @@ $(function() .addClass('sfc_opc_mc_item') .attr('data-value-code', sValCode) .append('') - .appendTo(oAllowedValuesElem); + .appendTo(oStaticValuesElem); } // - Regular allowed values @@ -129,7 +137,7 @@ $(function() .addClass('sfc_opc_mc_item') .attr('data-value-code', sValCode) .append('') - .appendTo(oAllowedValuesElem); + .appendTo(oDynamicValuesElem); if (this._isSelectedValues(sValCode)) { @@ -137,7 +145,20 @@ $(function() } } } - oAllowedValuesElem.appendTo(oOpContentElem); + + // - Specific to autocomplete mode + if(this._hasAutocompleteAllowedValues()) + { + // Remove filter picto from input + oFilterElem.find('.sff_filter').remove(); + + // Add search dialog button + oFilterElem + .append('') + .addClass('sf_with_buttons'); + + // Prepare "selected" values area + } // Events // - Check / Uncheck all toggler @@ -151,7 +172,7 @@ $(function() }); // - Filter - // Note: "keyup" event is use instead of "keydown", otherwise, the inpu value would not be set yet. + // Note: "keyup" event is use instead of "keydown", otherwise, the input value would not be set yet. oFilterElem.find('input').on('keyup focus', function(oEvent){ // TODO: Move on values with up and down arrow keys; select with space or enter. @@ -204,6 +225,56 @@ $(function() me._apply(); }); + // - Specific to autocomplete mode + // TODO: We NEED to refactor all of this for a better integration. Most might be in the main widget as any widget could use XHR helpers. + if(this._hasAutocompleteAllowedValues()) + { + // // Autocomplete + // var oACXHR = null; + // var oACTimeout = null; + // oFilterElem.find('input').off('keyup focus').on('keyup focus', function(oEvent){ + // // TODO: Move on values with up and down arrow keys; select with space or enter. + // + // var sFilter = $(this).val(); + // + // if(sFilter === '') + // { + // oOpContentElem.find('.sfc_opc_mc_item').html(''); + // oFilterElem.find('.sff_reset').hide(); + // } + // else + // { + // oOpContentElem.find('.sfc_opc_mc_item').html('TOTR: Wait'); + // if(oACXHR !== null) + // { + // oACXHR.abort(); + // } + // oACXHR = $.post( + // AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), + // { + // sTargetClass: me.options.field.class, + // //iInputId: me.id, + // //iObjectId: iObjectId, + // sAttCode: me.options.field.code, + // bSearchMode: true, + // operation: 'getObjectName' + // } + // ) + // .done(function(oResponse, sStatus, oXHR){ console.log('ok', oResponse); }) + // .fail(function(oResponse, sStatus, oXHR){ console.log('fail', oResponse); }) + // .always(function(oResponse, sStatus, oXHR){ console.log('always', oResponse); }); + // + // oFilterElem.find('.sff_reset').show(); + // } + // }); + // + // // Open search dialog + // oFilterElem.find('.sff_search_dialog').on('click', function(){ + // // TODO: Open search dialog with right params + // alert('Not implemented yet'); + // }); + } + oOpElem.find('.sfc_op_content').append(oOpContentElem); }, _setTitle: function(sTitle) diff --git a/js/search/search_form_criteria_external_key.js b/js/search/search_form_criteria_external_key.js index 2d148befe7..03150329a6 100644 --- a/js/search/search_form_criteria_external_key.js +++ b/js/search/search_form_criteria_external_key.js @@ -9,11 +9,13 @@ $(function() // default options options: { + 'endpoint': AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), + // Null value 'null_value': { 'code': 0, 'label': Dict.S('UI:UndefinedObject'), - } + }, }, @@ -52,6 +54,5 @@ $(function() //------------------ // Inherited methods //------------------ - }); }); diff --git a/js/search/search_form_criteria_hierarchical_key.js b/js/search/search_form_criteria_hierarchical_key.js index 40f993c828..c8ba543078 100644 --- a/js/search/search_form_criteria_hierarchical_key.js +++ b/js/search/search_form_criteria_hierarchical_key.js @@ -48,5 +48,25 @@ $(function() // Inherited methods //------------------ + // DOM element helpers + prepareInOperator: function(oOpElem, sOpIdx, oOp) + { + var me = this; + + this._super(); + + // DOM elements + // - Add search dialog button + this.element.find('.sf_filter') + .append('') + .addClass('sf_with_buttons'); + + // Events + // - Open hierarchy dialog + this.element.find('.sff_hierarchy_dialog').on('click', function(){ + // TODO: Open hierarchy dialog with right params + alert('Not implemented yet'); + }); + }, }); }); diff --git a/js/search/search_form_handler.js b/js/search/search_form_handler.js index c9a5fecf2c..394c6fd19d 100644 --- a/js/search/search_form_handler.js +++ b/js/search/search_form_handler.js @@ -319,7 +319,7 @@ $(function() var oFilterElem = $('') .addClass('sf_filter') .addClass('sfm_filter') - .append('') + .append('') .appendTo(oContentElem); // - Lists container @@ -618,46 +618,54 @@ $(function() _addCriteria: function(oData) { var sRef = oData.ref; - var sType = (oData.widget !== undefined) ? oData.widget : this._getCriteriaTypeFromFieldRef(sRef); + var sType = sType = (oData.widget !== undefined) ? oData.widget : this._getCriteriaTypeFromFieldRef(sRef); - if(sType !== null) + // Force to raw for non removable criteria + if( (oData.is_removable !== undefined) && (oData.is_removable === false) ) { - // Retrieve widget class - var sWidgetName = this._getCriteriaWidgetNameFromType(sType); - - // Add some informations from the field - if(this._hasFieldDefinition(sRef)) - { - var oFieldDef = this._getFieldDefinition(sRef); - oData.field = { - label: oFieldDef.label, - class: oFieldDef.class, - class_alias: oFieldDef.class_alias, - code: oFieldDef.code, - widget: oFieldDef.widget, - allowed_values: oFieldDef.allowed_values, - is_null_allowed: oFieldDef.is_null_allowed, - }; - } - - if ('date' == sType || 'date_time' == sType) - { - oData.datepicker = this.options.datepicker; - } - - // Create DOM element - var oCriteriaElem = $('') - .addClass('sf_criteria') - //.insertBefore(this.elements.more_criterion); - .appendTo(this.elements.criterion_area); - - // Instanciate widget - $.itop[sWidgetName](oData, oCriteriaElem); + sType = 'raw'; } - else + + // Protection against bad initialization data + if(sType === null) { - this._trace('Could not add criteria as we could not retrieve type for ref "' + sRef + '".'); + this._trace('Could not add criteria as we could not retrieve type for ref "'+sRef+'".'); + return false; } + + // Retrieve widget class + var sWidgetName = this._getCriteriaWidgetNameFromType(sType); + + // Add some informations from the field + if(this._hasFieldDefinition(sRef)) + { + var oFieldDef = this._getFieldDefinition(sRef); + oData.field = { + label: oFieldDef.label, + class: oFieldDef.class, + class_alias: oFieldDef.class_alias, + code: oFieldDef.code, + widget: oFieldDef.widget, + allowed_values: oFieldDef.allowed_values, + is_null_allowed: oFieldDef.is_null_allowed, + }; + } + + if ('date' == sType || 'date_time' == sType) + { + oData.datepicker = this.options.datepicker; + } + + // Create DOM element + var oCriteriaElem = $('') + .addClass('sf_criteria') + //.insertBefore(this.elements.more_criterion); + .appendTo(this.elements.criterion_area); + + // Instanciate widget + $.itop[sWidgetName](oData, oCriteriaElem); + + return true; }, // - Find a criteria's type from a field's ref (usually