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() {
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") {
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();
};
this.field_selector = new dijit.form.FilteringSelect(
{
"labelAttr": "label",
+ "searchAttr": "label",
"scrollOnFocus": false,
"onChange": function(value) {
self.update_selected_field(value);
);
};
- 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() {
};
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);
};
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
+ };
}
)
}