"param_count": 1,
"strict": true
}, {
+ "name": "in",
+ "label": pcFilterLocaleStrings.OPERATOR_IN,
+ "param_count": null, /* arbitrary number, special */
+ "strict": true,
+ "minimal": true
+ }, {
+ "name": "not in",
+ "label": pcFilterLocaleStrings.OPERATOR_NOT_IN,
+ "param_count": null, /* arbitrary number, special */
+ "strict": true,
+ "minimal": true
+ }, {
"name": "between",
"label": pcFilterLocaleStrings.OPERATOR_BETWEEN,
"param_count": 2,
var ops = openils.Util.objectProperties(clause);
var op = ops.pop();
- var matches = op.match(/^not (\w+)$/);
+ var matches = op.match(/^not [lb].+$/); /* "not in" needs no change */
if (matches) {
clause[matches[1]] = clause[op];
delete clause[op];
return false;
}
+ /* Given a value, add it to selector options if it's not already there,
+ * and select it. */
+ function _add_or_at_least_select(value, selector) {
+ var found = false;
+
+ for (var i = 0; i < selector.options.length; i++) {
+ var option = selector.options[i];
+ if (option.value == value) {
+ found = true;
+ option.selected = true;
+ }
+ }
+
+ if (!found) {
+ dojo.create(
+ "option", {
+ "innerHTML": value,
+ "value": value,
+ "selected": "selected"
+ }, selector
+ );
+ }
+ }
+
/* This is not the dijit per se. Search further in this file for
* "dojo.declare" for the beginning of the dijit.
*
};
this._create_value_slot = function(use_element) {
+ var how = {"innerHTML": "-"};
+
if (use_element)
- this.value_slot = dojo.create(
- "span", {"innerHTML": "-"}, use_element
- );
+ this.value_slot = dojo.create("span", how, use_element);
else
- this.value_slot = dojo.create("td",{"innerHTML":"-"},this.tr);
+ this.value_slot = dojo.create("td", how, this.tr);
};
this._create_remover = function(use_element) {
this._clear_value_slot = function() {
if (this.value_widgets) {
this.value_widgets.forEach(
- function(autowidg) { autowidg.widget.destroy(); }
+ function(autowidg) {
+ if (autowidg.widget)
+ autowidg.widget.destroy();
+ }
);
delete this.value_widgets;
}
this.value_widgets = [];
- var param_count = this.operator_selector.item.param_count;
-
- /* This is where find and deploy custom widget builders. */
+ /* This is where find custom widget builders to deploy shortly. */
var widget_builder_key = this.selected_field_fm_class + ":" +
this.selected_field_fm_field;
var constr =
this.filter_row_manager.widget_builders[widget_builder_key] ||
openils.widget.AutoFieldWidget;
- for (var i = 0; i < param_count; i++) {
- var widg = new constr({
- "fmClass": this.selected_field_fm_class,
- "fmField": this.selected_field_fm_field,
- "noDisablePkey": true,
- "parentNode": dojo.create("span", {}, this.value_slot),
- "dijitArgs": {"scrollOnFocus": false}
- });
+ /* How many value widgets do we need for this operator? */
+ var param_count =
+ this.operator_selector.store.getValue(
+ this.operator_selector.item, "param_count"
+ );
- widg.build();
- this.value_widgets.push(widg);
+ if (param_count === null) {
+ /* When param_count is null, we invoke the special case of
+ * preparing widgets for building a dynamic set of values.
+ * All other cases are handled by the else branch. */
+ this._build_set_value_widgets(constr);
+ } else {
+ for (var i = 0; i < param_count; i++) {
+ this.value_widgets.push(
+ this._build_one_value_widget(constr)
+ );
+ }
}
};
+ this._build_set_value_widgets = function(constr) {
+ var value_widget = dojo.create(
+ "select", {
+ "multiple": "multiple",
+ "size": 4,
+ "style": {
+ "width": "6em",
+ "verticalAlign": "middle",
+ "margin": "0 0.75em"
+ }
+ },
+ this.value_slot
+ );
+ var entry_widget = this._build_one_value_widget(constr);
+ var adder = dojo.create(
+ "a", {
+ "href": "javascript:void(0);",
+ "style": {"verticalAlign": "middle", "margin": "0 0.75em"},
+ "innerHTML": "[+]", /* XXX i18n? */
+ "onclick": dojo.hitch(this, function() {
+ _add_or_at_least_select(
+ this._value_of_widget(entry_widget),
+ value_widget
+ );
+ entry_widget.widget.attr("value", ""); /* clear */
+ })
+ }, this.value_slot
+ );
+ this.value_widgets.push(value_widget);
+ };
+
+
+ /* Create just one value widget (used by higher-level functions
+ * that worry about how many are needed). */
+ this._build_one_value_widget = function(constr) {
+ var widg = new constr({
+ "fmClass": this.selected_field_fm_class,
+ "fmField": this.selected_field_fm_field,
+ "noDisablePkey": true,
+ "parentNode": dojo.create(
+ "span", {
+ "style": {"verticalAlign": "middle"}
+ }, this.value_slot
+ ),
+ "dijitArgs": {"scrollOnFocus": false}
+ });
+
+ widg.build();
+ return widg;
+ };
+
+ this._value_of_widget = function(widg) {
+ if (!widg.widget) /* widg is <select> */
+ return dojo.filter(
+ widg.options,
+ function(o) { return o.selected; }
+ ).map(
+ function(o) { return o.value; }
+ );
+ else if (widg.useCorrectly)
+ return widg.widget.attr("value");
+ else if (this.selected_field_is_indirect)
+ return widg.widget.attr("displayedValue");
+ else
+ return widg.getFormattedValue();
+ }
+
/* for ugly special cases in compilation */
this._null_clause = function() {
var opname = this.get_selected_operator_name();
};
this.get_selected_operator_name = function() {
- var op = this.get_selected_operator();
- return op ?
- (dojo.isArray(op.name) ? op.name.shift() : op.name) :
- null;
+ var item = this.get_selected_operator();
+ if (item)
+ return this.operator_selector.store.getValue(item, "name")
+ else
+ console.warn(
+ "Could not determine selected operator. " +
+ "Something is about to break."
+ );
};
this.update_selected_operator = function(value) {
this.compile = function() {
if (this.value_widgets) {
var values = this.value_widgets.map(
- function(widg) {
- if (widg.useCorrectly)
- return widg.widget.attr("value");
- else if (self.selected_field_is_indirect)
- return widg.widget.attr("displayedValue");
- else
- return widg.getFormattedValue();
- }
+ dojo.hitch(this, this._value_of_widget)
);
if (!values.length) {
var clause = {};
var op = this.get_selected_operator_name();
- var prep_function = function(o) { return o; /* no-op */ };
+ var prep_function = function(o) {
+ if (dojo.isArray(o) && !o.length)
+ throw new Error(pcFilterLocaleStrings.EMPTY_LIST);
+
+ return o;
+ };
+
if (String(op).match(/like/))
prep_function = this._add_like_wildcards;