From 2033c171f0346addb13774bd982b388958e725f7 Mon Sep 17 00:00:00 2001 From: Guillaume Lajarige Date: Thu, 8 Mar 2018 16:50:10 +0000 Subject: [PATCH] Advanced search: Integration with endpoint POC & WIP. SVN:b1162[5394] --- application/nicewebpage.class.inc.php | 1 + css/css-variables.scss | 24 ++- css/light-grey.css | 88 ++++++-- css/light-grey.scss | 75 +++++++ js/search/search_form_criteria.js | 124 ++++++------ js/search/search_form_criteria_raw.js | 55 +++++ js/search/search_form_handler.js | 277 ++++++++++++++++++++------ 7 files changed, 498 insertions(+), 146 deletions(-) create mode 100644 js/search/search_form_criteria_raw.js diff --git a/application/nicewebpage.class.inc.php b/application/nicewebpage.class.inc.php index a533c044a..d1a4a65bd 100644 --- a/application/nicewebpage.class.inc.php +++ b/application/nicewebpage.class.inc.php @@ -52,6 +52,7 @@ class NiceWebPage extends WebPage $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.popupmenu.js'); $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_handler.js'); $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria.js'); + $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_raw.js'); $this->add_ready_script( <<< EOF //add new widget called TruncatedList to properly display truncated lists when they are sorted diff --git a/css/css-variables.scss b/css/css-variables.scss index 6e61874f8..e4e13bdcd 100644 --- a/css/css-variables.scss +++ b/css/css-variables.scss @@ -1,8 +1,28 @@ -$highlight-color: #E87C1E; +// Base colors +$gray-base: #000 !default; +$gray-darker: lighten($gray-base, 13.5%) !default; // #222 +$gray-dark: #444 !default; +$gray: #777 !default; +$gray-light: #808080 !default; +$gray-lighter: #ddd !default; +$gray-extra-light: #F1F1F1 !default; + +$white: #FFFFFF !default; + +$combodo-orange: #EA7D1E !default; +$combodo-dark-gray: #585653 !default; + +$combodo-orange-dark: darken($combodo-orange, 13.8%) !default; +$combodo-orange-darker: darken($combodo-orange, 18%) !default; +$combodo-dark-gray-dark: darken($combodo-dark-gray, 13.5%) !default; +$combodo-dark-gray-darker: darken($combodo-dark-gray, 18%) !default; + +// Vars +$highlight-color: $combodo-orange; $grey-color: #555555; $complement-color: #1c94c4; $complement-light: #d6e8ef; -$frame-background-color: #F1F1F1; +$frame-background-color: $gray-extra-light; $text-color: #000; // Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0 $version: "v2.4.0"; \ No newline at end of file diff --git a/css/light-grey.css b/css/light-grey.css index 1c3555356..f46ed2059 100644 --- a/css/light-grey.css +++ b/css/light-grey.css @@ -58,7 +58,7 @@ label { cursor: pointer; } .hilite, .hilite a, .hilite a:visited { - color: #e87c1e; + color: #ea7d1e; text-decoration: none; } table.datatable { @@ -114,7 +114,7 @@ table.listResults td .view-image img { cursor: pointer; margin-bottom: 3px; padding: 2px; - background-color: #e87c1e; + background-color: #ea7d1e; } .edit-image .edit-buttons .button.disabled { cursor: default; @@ -275,7 +275,7 @@ legend.transparent { } .ui-widget-content td a:hover, p a:hover, td a:hover { text-decoration: underline; - color: #e87c1e; + color: #ea7d1e; } .cke_reset_all *:hover { text-decoration: none; @@ -283,8 +283,8 @@ legend.transparent { } table.cke_dialog_contents a.cke_dialog_ui_button_ok { color: #000; - border-color: #e87c1e; - background: #e87c1e; + border-color: #ea7d1e; + background: #ea7d1e; } .cke_notifications_area { display: none; @@ -309,7 +309,7 @@ td a.mailto, td a.mailto:visited { } td a.mailto:hover { text-decoration: underline; - color: #e87c1e; + color: #ea7d1e; padding-left: 20px; background: url(../images/mail.png?v=v2.4.0) no-repeat left; } @@ -329,7 +329,7 @@ a.small_action { padding-left: 5px; padding-top: 2px; padding-bottom: 2px; - background: #e87c1e url(../images/actions_left.png?v=v2.4.0) no-repeat left; + background: #ea7d1e url(../images/actions_left.png?v=v2.4.0) no-repeat left; } .actions_details span { background: url(../images/actions_right.png?v=v2.4.0) no-repeat right; @@ -424,7 +424,7 @@ div.ui-accordion-content { text-decoration: none; } .ui-accordion-content a:hover { - color: #e87c1e; + color: #ea7d1e; text-decoration: none; } .ui-accordion-content ul { @@ -455,7 +455,7 @@ a.CollapsibleLabel.open, td a.CollapsibleLabel.open { padding: 0px 0pt 0px 16px; font-size: 8pt; text-decoration: none; - color: #e87c1e; + color: #ea7d1e; background: url(../images/mini-arrow-orange-open.gif) no-repeat left; } .page_header { @@ -506,7 +506,7 @@ div.actions_menu > ul { nowidth: 70px; padding-left: 5px; /* Nasty work-around for IE... en attendant mieux */ - background: #e87c1e url(../images/actions_left.png?v=v2.4.0) no-repeat top left; + background: #ea7d1e url(../images/actions_left.png?v=v2.4.0) no-repeat top left; cursor: pointer; margin: 0; } @@ -588,7 +588,7 @@ div.actions_menu > ul > li { text-align: left; } .itop_popup li ul li a:hover, #logOffBtn li ul li a:hover { - background: #e87c1e; + background: #ea7d1e; color: #fff; font-weight: bold; } @@ -675,6 +675,7 @@ input.dp-applied { float: left; } /* For search forms */ +/* TODO: Remove when cleaning up old search */ .SearchDrawer { border-top: 5px solid #1c94c4; border-left: 5px solid #1c94c4; @@ -753,6 +754,57 @@ div.HRDrawer { nopadding-right: 1em; margin-top: 0; } +/* Search forms v2 */ +/* TODO: Remove comment before final commit */ +.search_form_handler { + /* Sizing reset */ + /* Hyperlink reset */ +} +.search_form_handler * { + box-sizing: border-box; +} +.search_form_handler a { + color: inherit; + text-decoration: none; +} +.search_form_handler .sf_criterion_area { + /* Common style between criterion and more criterion */ + /* Criteria tags */ + /* More criterion */ +} +.search_form_handler .sf_criterion_area .sf_active_criterion, .search_form_handler .sf_criterion_area .sf_more_criterion { + display: inline-block; +} +.search_form_handler .sf_criterion_area .sf_more_criterion, .search_form_handler .sf_criterion_area .search_form_criteria { + position: relative; + padding: 8px 10px; + background-color: #ea7d1e; + color: #fff; +} +.search_form_handler .sf_criterion_area .search_form_criteria { + display: inline-block; + margin-right: 3px; +} +.search_form_handler .sf_criterion_area .search_form_criteria.locked { + background-color: #f1f1f1; +} +.search_form_handler .sf_criterion_area .search_form_criteria .sfc_form_group { + display: none; +} +.search_form_handler .sf_criterion_area .search_form_criteria .sfc_form_group.opened { + display: block; +} +.search_form_handler .sf_criterion_area .sf_more_criterion .sf_mc_list { + position: absolute; + margin: 0px; + top: 100%; + left: 0px; + background-color: #ea7d1e; +} +.search_form_handler .sf_criterion_area .sf_more_criterion .sf_mc_list .sf_mc_field { + cursor: pointer; + white-space: nowrap; +} .mandatory { border: 1px solid #f00; } @@ -892,7 +944,7 @@ div#logo div { margin-top: 2px; margin-right: 4px; padding: 6px 9px; - background-color: #e87c1e; + background-color: #ea7d1e; color: white; border-radius: 6px; text-align: left; @@ -1499,7 +1551,7 @@ img.prev, img.first, img.next, img.last { } div.actions_button { float: right; - background: #e87c1e url("../images/actions_left.png?v=v2.4.0") no-repeat scroll left top; + background: #ea7d1e url("../images/actions_left.png?v=v2.4.0") no-repeat scroll left top; padding-left: 5px; margin-top: 0; margin-right: 10px; @@ -1507,7 +1559,7 @@ div.actions_button { vertical-align: middle; } div.actions_button a, .actions_button a:hover, .actions_button a:visited { - background: #e87c1e url(../images/actions_bkg.png?v=v2.4.0) no-repeat scroll right top; + background: #ea7d1e url(../images/actions_bkg.png?v=v2.4.0) no-repeat scroll right top; color: #fff; padding-right: 8px; cursor: pointer; @@ -1540,7 +1592,7 @@ select#org_id { position: relative; } .edit_mode .dashlet-selected { - background: #e87c1e !important; + background: #ea7d1e !important; padding: 5px; margin: 0; } @@ -1706,7 +1758,7 @@ a.summary, a.summary:hover { z-index: 999; } #DashboardMenu li ul li a:hover { - background: #e87c1e; + background: #ea7d1e; color: #fff; font-weight: bold; list-style: none; @@ -2063,7 +2115,7 @@ span.refresh-button { } #itop-breadcrumb .breadcrumb-item a:hover { text-decoration: none; - color: #e87c1e; + color: #ea7d1e; } #itop-breadcrumb .breadcrumb-item a::after { content: ''; @@ -2127,7 +2179,7 @@ span.refresh-button { margin-bottom: 1px; } .object-ref-icon.fa { - color: #e87c1e; + color: #ea7d1e; font-size: smaller; vertical-align: 1px; margin-right: 1px; diff --git a/css/light-grey.scss b/css/light-grey.scss index aaf3e6658..063cd959c 100644 --- a/css/light-grey.scss +++ b/css/light-grey.scss @@ -756,6 +756,7 @@ input.dp-applied { } /* For search forms */ +/* TODO: Remove when cleaning up old search */ .SearchDrawer { //background: $complement-color url(../images/search-top-left-corner.png?v=#{$version}) top left no-repeat; border-top: 5px solid $complement-color; @@ -839,6 +840,80 @@ div.HRDrawer { nopadding-right: 1em; margin-top: 0; } +/* Search forms v2 */ +/* TODO: Remove comment before final commit */ +.search_form_handler{ + /* Sizing reset */ + *{ + box-sizing: border-box; + } + /* Hyperlink reset */ + a{ + color: inherit; + text-decoration: none; + } + + .sf_criterion_area{ + /* Common style between criterion and more criterion */ + .sf_active_criterion, + .sf_more_criterion{ + display: inline-block; + } + .sf_more_criterion, + .search_form_criteria{ + position: relative; + padding: 8px 10px; + background-color: $combodo-orange; + color: $white; + } + + /* Criteria tags */ + .search_form_criteria{ + display: inline-block; + margin-right: 3px; + + &.locked{ + background-color: $gray-extra-light; + } + + .sfc_close{ + + } + .sfc_toggle{ + &.opened{ + + } + } + .sfc_title{ + + } + .sfc_form_group{ + display: none; + + &.opened{ + display: block; + } + } + } + + /* More criterion */ + .sf_more_criterion{ + .sf_mc_list{ + position: absolute; + margin: 0px; + top: 100%; + left: 0px; + background-color: $combodo-orange; + + .sf_mc_field{ + cursor: pointer; + white-space: nowrap; + } + } + } + } +} + .mandatory { border: 1px solid #f00; } diff --git a/js/search/search_form_criteria.js b/js/search/search_form_criteria.js index 27d5e0a87..0047f9a10 100644 --- a/js/search/search_form_criteria.js +++ b/js/search/search_form_criteria.js @@ -9,15 +9,15 @@ $(function() // default options options: { - handled_classes: [], - get_current_value_callback: 'getCurrentValue', - set_current_value_callback: function(me, oEvent, oData){ console.log('Search form criteria: set_current_value_callback must be overloaded, this is the default callback.'); }, + get_current_values_callback: 'getCurrentValues', + set_current_values_callback: function(me, oEvent, oData){ console.log('Search form criteria: set_current_values_callback must be overloaded, this is the default callback.'); }, - ref: "", - operator: "=", + ref: '', + operator: '=', values: [], - oql: "", + oql: '', is_removable: true, + is_modified: false, // TODO: change this on value change and remove oql property value }, // the constructor @@ -25,12 +25,14 @@ $(function() { var me = this; - this.element - .addClass('search_form_criteria'); + this.element.addClass('search_form_criteria'); - // Get/SetCurrentValue callbacks handler - this.element - .bind('get_current_value set_current_value', function(oEvent, oData){ + // GetData + this.element.bind('itop.search.criteria.get_data', function(oEvent, oData){ + return me._onGetData(oData); + }); + // Get/SetCurrentValues callbacks handler + this.element.bind('itop.search.criteria.get_current_values itop.search.criteria.set_current_values', function(oEvent, oData){ oEvent.stopPropagation(); var callback = me.options[oEvent.type+'_callback']; @@ -61,8 +63,7 @@ $(function() // revert other modifications here _destroy: function() { - this.element - .removeClass('search_form_criteria'); + this.element.removeClass('search_form_criteria'); }, // _setOptions is called with a hash of all options that are changing // always refresh when changing options @@ -77,52 +78,30 @@ $(function() }, - getCurrentValue: function() + // Public methods + getCurrentValues: function() { - // TODO - // var value = null; - // - // this.element.find(':input').each(function(iIndex, oElem){ - // if($(oElem).is(':hidden') || $(oElem).is(':text') || $(oElem).is(':password') || $(oElem).is('textarea')) - // { - // value = $(oElem).val(); - // } - // else if($(oElem).is('select')) - // { - // if($(oElem).is('select[multiple]')) - // { - // value = []; - // $(oElem).find('option:selected').each(function(){ - // value.push($(this).val()); - // }); - // } - // else - // { - // value = $(oElem).val(); - // } - // } - // else if($(oElem).is(':checkbox') || $(oElem).is(':radio')) - // { - // if(value === null) - // { - // value = []; - // } - // if($(oElem).is(':checked')) - // { - // value.push($(oElem).val()); - // } - // } - // else - // { - // console.log('Form field : Input type not handle yet.'); - // } - // }); - // - // return value; + var aValues = this.options.values; + return aValues; }, - // Prepare DOM element + // Event callbacks + _onGetData: function(oData) + { + var oData = { + 'ref': this.options.ref, + 'operator': this.options.operator, + 'values': this.options.values, + 'is_removable': this.options.is_removable, + 'oql': this.options.oql, + }; + return oData; + }, + + + // DOM element helpers + // - Prepare element DOM structure _prepareElement: function() { // Prepare base DOM structure @@ -130,26 +109,51 @@ $(function() this.element .append('
') .append('
') - .append('
'); + .append('
'); // Removable / locked decoration if(this.options.is_removable === true) { - this.element.append('
'); + this.element.append('
'); } else { this.element.append('
'); } - // Fill + // Fill criteria + this._setTitle(); + }, + _setTitle: function(sTitle) + { + if(sTitle === undefined) + { + // TODO: Make nice label + } + this.element.find('.sfc_title').text(sTitle); }, - // Debug helper + // Debug helpers + // - Show a trace in the javascript console + _trace: function(sMessage, oData) + { + if(window.console) + { + if(oData !== undefined) + { + console.log('Search form criteria: ' + sMessage, oData); + } + else + { + console.log('Search form criteria: ' + sMessage); + } + } + }, + // - Show current options showOptions: function() { - return this.options; + this._trace('Options', this.options); } }); }); diff --git a/js/search/search_form_criteria_raw.js b/js/search/search_form_criteria_raw.js new file mode 100644 index 000000000..7b628316d --- /dev/null +++ b/js/search/search_form_criteria_raw.js @@ -0,0 +1,55 @@ +//iTop Search form criteria raw +; +$(function() +{ + // the widget definition, where 'itop' is the namespace, + // 'search_form_criteria_raw' the widget name + $.widget( 'itop.search_form_criteria_raw', $.itop.search_form_criteria, + { + // default options + options: + { + }, + + // the constructor + _create: function() + { + var me = this; + + this._super(); + this.element.addClass('search_form_criteria_raw'); + }, + // called when created, and later when changing options + _refresh: function() + { + + }, + // events bound via _bind are removed automatically + // revert other modifications here + _destroy: function() + { + this.element.removeClass('search_form_criteria_raw'); + this._super(); + }, + // _setOptions is called with a hash of all options that are changing + // always refresh when changing options + _setOptions: function() + { + this._superApply(arguments); + }, + // _setOption is called for each individual option that is changing + _setOption: function( key, value ) + { + this._super( key, value ); + }, + + _setTitle: function(sTitle) + { + if(sTitle === undefined) + { + sTitle = this.options.oql; + } + this._super(sTitle); + }, + }); +}); diff --git a/js/search/search_form_handler.js b/js/search/search_form_handler.js index d8e2c65aa..5ed8e3335 100644 --- a/js/search/search_form_handler.js +++ b/js/search/search_form_handler.js @@ -9,54 +9,57 @@ $(function() // default options options: { - "criterion_outer_selector": null, - "result_list_outer_selector": null, - "submit_button_selector": null, - "hide_initial_criterion": false, // What is that? - "endpoint": null, - "search": { - "base_oql": "", - "criterion": [ + 'criterion_outer_selector': null, + 'result_list_outer_selector': null, + 'submit_button_selector': null, + 'hide_initial_criterion': false, // TODO: What is that? + 'endpoint': null, + 'search': { + 'base_oql': '', + 'criterion': [ // Structure // { - // "or": [ + // 'or': [ // { - // "and": [ + // 'and': [ // { - // "ref": "alias.code", - // "operator": "contains", - // "values": [ + // 'ref': 'alias.code', + // 'operator': 'contains', + // 'values': [ // { - // "value": "foo", - // "label": "bar", + // 'value': 'foo', + // 'label': 'bar', // } // ], - // "is_removable": true, - // "oql": "", + // 'is_removable': true, + // 'oql': '', // }, // ] // }, // ] // }, ], - "fields": [ + 'fields': [ // Structure - // "alias.code": { - // "class_alias": "", - // "class": "", - // "code": "", - // "label": "", - // "type": "", - // "allowed_values": {...}, + // 'alias.code': { + // 'class_alias': '', + // 'class': '', + // 'code': '', + // 'label': '', + // 'type': '', + // 'allowed_values': {...}, // }, ], }, + 'supported_criterion_types': ['raw'], + 'default_criteria_type': 'raw', }, // jQuery elements elements: { - criterion_area: null, + active_criterion: null, + more_criterion: null, }, // the constructor @@ -64,26 +67,20 @@ $(function() { var me = this; - this.element - .addClass('search_form_handler'); + this.element.addClass('search_form_handler'); - // Binding events - // this.element.bind('update_fields', function(oEvent, oData){ - // me._onUpdateFields(oEvent, oData); - // }); + // Prepare DOM elements + this._prepareCriterionArea(); + this._prepareResultsArea(); // Binding buttons if(this.options.submit_button_selector !== null) { - this.options.submit_button_selector.off('click').on('click', function(oEvent){ me._onSubmitClick(oEvent); }); + $(this.options.submit_button_selector).off('click').on('click', function(oEvent){ me._onSubmitClick(oEvent); }); } - // if(this.options.cancel_btn_selector !== null) - // { - // this.options.cancel_btn_selector.off('click').on('click', function(oEvent){ me._onCancelClick(oEvent); }); - // } - // Prepare criterion area - this._prepareCriterionArea(); + // Binding events (eg. from search_form_criteria widgets) + this._bindEvents(); }, // called when created, and later when changing options @@ -111,39 +108,137 @@ $(function() }, - getCurrentValues: function() + // + _bindEvents: function() { - // TODO - // return this.options.field_set.triggerHandler('get_current_values'); + var me = this; + + // Criteria events + this.element.bind('itop.search.criteria.value_changed', function(oEvent, oData){ + me._onCriteriaValueChanged(oData); + }); + }, + // - Update search option of the widget + _updateSearch: function() + { + var me = this; + + // Criterion + // - Note: As of today, only a "or" level with a "and" is supported, so the following part + // will need some refactoring when introducing new stuff. + var oCriterion = { + 'or': [{ + 'and': [] + }] + }; + // - Retrieve criterion + this.elements.active_criterion.find('.search_form_criteria').each(function(){ + var oCriteriaData = $(this).triggerHandler('itop.search.criteria.get_data'); + oCriterion['or'][0]['and'].push(oCriteriaData); + }); + // - Update search + this.options.search.criterion = oCriterion; + + // No need to update base OQL and fields }, + // DOM helpers // - Prepare criterion area _prepareCriterionArea: function() { + var oCriterionAreaElem; + // Build area element if(this.options.criterion_outer_selector !== null && $(this.options.criterion_outer_selector).length > 0) { - this.elements.criterion_area = $(this.options.criterion_outer_selector); + oCriterionAreaElem = $(this.options.criterion_outer_selector); } else { - var oCriterionAreaElem = $('
').appendTo(this.element); - this.elements.criterion_area = oCriterionAreaElem; + oCriterionAreaElem = $('
').appendTo(this.element); } - this.elements.criterion_area.addClass('sf_criterion_area'); + oCriterionAreaElem.addClass('sf_criterion_area'); // Clean area - this.elements.criterion_area.html(''); + oCriterionAreaElem + .html('') + .append('
') + .append('
'); + this.elements.active_criterion = oCriterionAreaElem.find('.sf_active_criterion'); + this.elements.more_criterion = oCriterionAreaElem.find('.sf_more_criterion'); - // Fill area with existing criterion - for(var i in this.options.search.criterion) + // Prepare content + this._prepareExistingCriterion(); + this._prepareMoreCriterionMenu(); + + // TODO: Delete this + oCriterionAreaElem.append( $('') ); + this.options.submit_button_selector = '.sf_submit_btn'; + }, + // - Prepare existing criterion + _prepareExistingCriterion: function() + { + // - OR conditions + var aORs = (this.options.search.criterion['or'] !== undefined) ? this.options.search.criterion['or'] : []; + for(var iORIdx in aORs) { - console.log(i, this.options.search.criterion[i]); + // Note: We might want to create a OR container here when handling several OR conditions. + + var aANDs = (aORs[iORIdx]['and'] !== undefined) ? aORs[iORIdx]['and'] : []; + for(var iANDIdx in aANDs) + { + var oCriteriaData = aANDs[iANDIdx]; + this._addCriteria(oCriteriaData); + } } }, + // - Prepare "more" button + _prepareMoreCriterionMenu: function() + { + var me = this; + + // Add fields + // TODO: Find a widget to handle dropdown menu + for(var sFieldRef in this.options.search.fields) + { + var oField = this.options.search.fields[sFieldRef]; + var oFieldElem = $('
  • ') + .addClass('sf_mc_field') + .attr('data-field-ref', sFieldRef) + .text(oField.label); + this.elements.more_criterion.find('> .sf_mc_list').append(oFieldElem); + } + + // Bind event + this.elements.more_criterion.find('.sf_mc_field').on('click', function(){ + // Prepare new criterion data + var oData = { + 'ref': $(this).attr('data-field-ref'), + }; + + // Add criteria but don't submit form as the user has not specified the value yet. + me._addCriteria(oData); + }); + }, + // - Prepare results area + _prepareResultsArea: function() + { + var oResultAreaElem; + + // Build area element + if(this.options.result_list_outer_selector !== null && $(this.options.result_list_outer_selector).length > 0) + { + oResultAreaElem = $(this.options.result_list_outer_selector); + } + else + { + oResultAreaElem = $('
    ').appendTo(this.element); + } + oResultAreaElem.addClass('sf_results_area'); + }, - // Criteria handlers + // Criteria helpers // - Add a criteria to the form _addCriteria: function(oData) { @@ -152,11 +247,11 @@ $(function() if(sType !== null) { - var sWidgetClass = 'search_form_criteria' + ((sType === 'raw') ? '' : '_' + sType); + var sWidgetClass = 'search_form_criteria' + '_' + sType; oCriteriaElem = $('
    ') .addClass('sf_criteria') - .appendTo(this.elements.criterion_area) - .search_form_criteria(oData); + .appendTo(this.elements.active_criterion); + $.itop[sWidgetClass](oData, oCriteriaElem); } else { @@ -170,17 +265,35 @@ $(function() if(this.options.search.fields[sRef] !== undefined) { - sType = this.options.search.fields[sRef].type; + sType = this.options.search.fields[sRef].widget.toLowerCase(); + + // Make sure the criteria type is supported, otherwise we might try to initialize a unknown widget. + if(this.options.supported_criterion_types.indexOf(sType) < 0) + { + sType = this.options.default_criteria_type; + } + } + // Fallback for unknown widget types or unknown field refs + else + { + sType = this.options.default_criteria_type; } return sType; }, - + // Criteria handlers + // - Event value changed + _onCriteriaValueChanged: function(oData) + { + this._updateSearch(); + this._submit(); + }, // Button handlers _onSubmitClick: function(oEvent) { - // TODO + // Assertion: the search is already up to date + this._submit(); }, _onCancelClick: function(oEvent) { @@ -188,9 +301,29 @@ $(function() }, - // Update handlers - // - Called on form update successes - _onUpdateSuccess: function(oData, sFormPath) + // Submit handlers + _submit: function() + { + var oData = { + 'params': JSON.stringify({ + 'base_oql': this.options.search.base_oql, + 'criterion': this.options.search.criterion, + }), + }; + + $.post( + this.options.endpoint, + oData, + function(oResponse, sStatus, oXHR){ + console.log('POST success', oResponse, sStatus, oXHR); + } + ) + .done(function(a,b,c,d){ console.log('POST done', a,b,c,d);}) + .fail(function(a,b,c,d){ console.log('POST fail', a,b,c,d);}) + .always(function(a,b,c,d){ console.log('POST always', a,b,c,d);}); + }, + // - Called on form submit successes + _onSubmitSuccess: function(oData, sFormPath) { // TODO // if(oData.form.updated_fields !== undefined) @@ -198,13 +331,13 @@ $(function() // this.element.find('[data-form-path="' + sFormPath + '"]').trigger('update_form', {updated_fields: oData.form.updated_fields}); // } }, - // - Called on form update failures - _onUpdateFailure: function(oData, sFormPath) + // - Called on form submit failures + _onSubmitFailure: function(oData, sFormPath) { // TODO }, - // - Called after form updates - _onUpdateAlways: function(oData, sFormPath) + // - Called after form submits + _onSubmitAlways: function(oData, sFormPath) { // TODO // // Check all touched AFTER ajax is complete, otherwise the renderer will redraw the field in the mean time. @@ -213,7 +346,7 @@ $(function() }, - // Helpers + // Global helpers // - Show loader _disableFormBeforeLoading: function() { @@ -227,6 +360,18 @@ $(function() // Debug helpers + // - Converts a snake_case string to CamelCase + _toCamelCase: function(sString) + { + var aParts = sString.split('_'); + + for(var i in aParts) + { + aParts[i] = aParts[i].charAt(0).toUpperCase() + aParts[i].substr(1); + } + + return aParts.join(''); + }, // - Show a trace in the javascript console _trace: function(sMessage, oData) { @@ -245,7 +390,7 @@ $(function() // - Show current options showOptions: function() { - this._trace('Options', this.options, this.toto); + this._trace('Options', this.options); } }); });