From: Lebbeous Fogle-Weekley Date: Sat, 7 Jan 2012 20:28:59 +0000 (-0500) Subject: pcrudfilterdialog: selectable operators, including [not] between! X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=5d9c7b24ecb570092ac3a49dace39fbcf5e883c8;p=working%2FEvergreen.git pcrudfilterdialog: selectable operators, including [not] between! Signed-off-by: Lebbeous Fogle-Weekley --- diff --git a/Open-ILS/web/js/dojo/openils/widget/PCrudFilterDialog.js b/Open-ILS/web/js/dojo/openils/widget/PCrudFilterDialog.js index bb6b7ea0e8..04f3e984aa 100644 --- a/Open-ILS/web/js/dojo/openils/widget/PCrudFilterDialog.js +++ b/Open-ILS/web/js/dojo/openils/widget/PCrudFilterDialog.js @@ -7,6 +7,110 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { dojo.require('dijit.Dialog'); dojo.require('openils.Util'); + var _minimal_operators = [ + { + "name": "=", + "label": "is", + "param_count": 1 + }, { + "name": "!=", + "label": "is not", + "param_count": 1 + }, { + "name": "null", + "label": "is null", + "param_count": 0 + }, { + "name": "not null", + "label": "is not null", + "param_count": 0 + } + ]; + + var _strict_operators = [ + { + "name": ">", + "label": "is greater than", + "param_count": 1 + }, { + "name": "<", + "label": "is less than", + "param_count": 1 + }, { + "name": ">=", + "label": "is greater than or equal to", + "param_count": 1 + }, { + "name": "<=", + "label": "is less than or equal to", + "param_count": 1 + }, { + "name": "between", + "label": "is between", + "param_count": 2 + }, { + "name": "not between", + "label": "is not between", + "param_count": 2 + } + ]; + + var _fuzzy_operators = [ + { + "name": "like", + "label": "is like", + "param_count": 1 + }, { + "name": "not like", + "label": "is not like", + "param_count": 1 + } + ]; + + var _minimal_operator_store = new dojo.data.ItemFileReadStore( + { + "data": { + "identifier": "name", + "items": _minimal_operators + } + } + ); + + var _most_operator_store = new dojo.data.ItemFileReadStore( + { + "data": { + "identifier": "name", + "items": _minimal_operators.concat(_strict_operators) + } + } + ); + + var _all_operator_store = new dojo.data.ItemFileReadStore( + { + "data": { + "identifier": "name", + "items": _minimal_operators. + concat(_strict_operators). + concat(_fuzzy_operators) + } + } + ); + + var _operator_stores = {}; + ["bool", "link", "org_unit"].forEach( + function(type) { + _operator_stores[type] = _minimal_operator_store; + } + ); + + ["float", "id", "int", "interval", "money", "number", "timestamp"].forEach( + function(type) { + _operator_stores[type] = _most_operator_store; + } + ); + + _operator_stores.text = _all_operator_store; + /* This is not the dijit per se. Search further in this file for * "dojo.declare" for the beginning of the dijit. */ function PCrudFilterRowManager() { @@ -118,7 +222,7 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { for (var row_id in this.rows) { var row = this.rows[row_id]; var value = row.compile(); - var field = row.get_selected_field(); + var field = row.selected_field; if (typeof(value) != "undefined" && typeof(field) != "undefined") { @@ -156,7 +260,9 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { this.tr = dojo.create("tr", {}, this.filter_row_manager.table); this._create_field_selector(); - this._create_operator_selector(); + + this.operator_slot = dojo.create("td", {}, this.tr); + this._create_value_slot(); this._create_remover(); }; @@ -166,6 +272,7 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { this.field_selector = new dijit.form.FilteringSelect( { "labelAttr": "label", + "searchAttr": "label", "scrollOnFocus": false, "onChange": function(value) { self.update_selected_field(value); @@ -175,7 +282,46 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { ); }; - this._create_operator_selector = function() { + this._remove_operator_selector = function() { + if (this.operator_selector) { + var old_value = this.operator_selector.attr("value"); + this.operator_selector.destroy(); + dojo.empty(this.operator_slot); + return old_value; + } + + return undefined; + }; + + this._replace_operator_selector = function() { + var old_operator = this._remove_operator_selector(); + + var _operator_store = _operator_stores[this.selected_field_type]; + var operator_selector_args = { + "labelAttr": "label", + "searchAttr": "label", + "scrollOnFocus": false, + "onChange": function(value) { + self.update_selected_operator(value); + }, + "store": _operator_store + }; + + this.operator_selector = new dijit.form.FilteringSelect( + operator_selector_args, + dojo.create("span", {}, this.operator_slot) + ); + + if (old_operator) { + _operator_store.fetchItemByIdentity( + { + "identity": old_operator, + "onItem": function(item) { + self.operator_selector.attr("value", old_operator); + } + } + ); + } }; this._create_value_slot = function() { @@ -197,42 +343,110 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { }; this._clear_value_slot = function() { - if (this.value_widget) - this.value_widget.widget.destroy(); + if (this.value_widgets) { + this.value_widgets.forEach( + function(autowidg) { autowidg.widget.destroy(); } + ); + delete this.value_widgets; + } dojo.empty(this.value_slot); }; - this.update_selected_field = function(value) { - /* This is called when the field selector is changed, - * and is responsible for changing the widget(s) in the value slot. - */ + this._rebuild_value_widgets = function() { + if (!this.selected_operator || !this.selected_field) + return; this._clear_value_slot(); - this.value_widget = new openils.widget.AutoFieldWidget({ - "fmClass": this.filter_row_manager.fm_class, - "fmField": value, - "parentNode": dojo.create("div", {}, this.value_slot), - "dijitArgs": {"scrollOnFocus": false} - }); + var _operator_store = _operator_stores[this.selected_field_type]; + + _operator_store.fetchItemByIdentity( + { + "identity": this.selected_operator, + "onItem": function(item) { + self._rebuild_value_widgets_impl(item.param_count); + } + } + ); + }; + + this._rebuild_value_widgets_impl = function(param_count) { + this.value_widgets = []; + + for (var i = 0; i < param_count; i++) { + var widg = new openils.widget.AutoFieldWidget({ + "fmClass": this.filter_row_manager.fm_class, + "fmField": this.selected_field, + "parentNode": dojo.create("span", {}, this.value_slot), + "dijitArgs": {"scrollOnFocus": false} + }); + + widg.build(); + this.value_widgets.push(widg); + } + }; + + this._null_clause = function() { + /* ugly special cases */ + if (this.selected_operator == "not null") + return {"!=": null}; + else if (this.selected_operator == "null") + return null; + else + return undefined; + }; - this.value_widget.build(); + this.update_selected_operator = function(value) { + this.selected_operator = value; + this._rebuild_value_widgets(); }; - this.get_selected_field = function() { - return this.field_selector.attr("value"); + this.update_selected_field = function(value) { + this.filter_row_manager.field_store.fetchItemByIdentity( + { + "identity": value, + "onItem": function(item) { + self._update_selected_field_impl(value, item.type); + } + } + ); + }; + + this._update_selected_field_impl = function(value, type) { + this.selected_field = value; + this.selected_field_type = type; + this._replace_operator_selector(); + this._rebuild_value_widgets(); }; this.compile = function() { - if (this.value_widget) - return this.value_widget.getFormattedValue(); - return undefined; + if (this.value_widgets) { + var values = this.value_widgets.map( + function(widg) { return widg.getFormattedValue(); } + ); + + if (!values.length) { + return this._null_clause(); /* null/not null */ + } else if (values.length == 1) { + var clause = {}; + clause[self.selected_operator] = values.pop(); + return clause; + } else { + var clause = {}; + clause[self.selected_operator] = values; + return clause; + } + } else { + return undefined; + } }; this.destroy = function() { this._clear_value_slot(); this.field_selector.destroy(); + if (this.operator_selector) + this.operator_selector.destroy(); dojo.destroy(this.tr); }; @@ -269,12 +483,16 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { var realFieldList = this.sortedFieldList.filter( function(item) { return !(item.virtual || item.nonIdl); }); this.fieldStore = new dojo.data.ItemFileReadStore({ - data : { - identifier : 'name', - name : 'label', - items : realFieldList.map( + "data": { + "identifier": "name", + "name": "label", + "items": realFieldList.map( function(item) { - return {label:item.label, name:item.name}; + return { + "label": item.label, + "name": item.name, + "type": item.datatype + }; } ) }