From ac8a686b907aa6822d1ec0c95f9a26d78684daed Mon Sep 17 00:00:00 2001 From: Lebbeous Fogle-Weekley Date: Fri, 6 Jan 2012 15:11:32 -0500 Subject: [PATCH] Much progress on refactoring/extending PCrudFilterDialog.js Todo: - better display for no filter rows empty case - dupe fields: prevent or "or" them together? - operators - preserve rows of filters across dialog show/hide Signed-off-by: Lebbeous Fogle-Weekley --- Open-ILS/web/css/skin/default.css | 7 + .../js/dojo/openils/widget/PCrudFilterDialog.js | 264 +++++++++++++++------ 2 files changed, 200 insertions(+), 71 deletions(-) diff --git a/Open-ILS/web/css/skin/default.css b/Open-ILS/web/css/skin/default.css index 4fa7215174..1973b4987b 100644 --- a/Open-ILS/web/css/skin/default.css +++ b/Open-ILS/web/css/skin/default.css @@ -87,6 +87,13 @@ table { border-collapse: collapse; } vertical-align:middle; } .oils-fm-edit-dialog td { border:1px solid #999;} +.oils-pcrudfilterdialog-table tr td { padding: 0.75ex 0.5em; } +.oils-pcrudfilterdialog-remover { + background-color: #ccc; color: #f00; + padding: 0.25em; border: 1px outset #000; + text-decoration: none; +} +.oils-pcrudfilterdialog-buttonholder > * { padding: 0 2em; } .oils-header-panel { width: 100%; margin-top:20px; diff --git a/Open-ILS/web/js/dojo/openils/widget/PCrudFilterDialog.js b/Open-ILS/web/js/dojo/openils/widget/PCrudFilterDialog.js index 5d9fb0c9a5..90d7449062 100644 --- a/Open-ILS/web/js/dojo/openils/widget/PCrudFilterDialog.js +++ b/Open-ILS/web/js/dojo/openils/widget/PCrudFilterDialog.js @@ -1,4 +1,3 @@ - if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { dojo.provide('openils.widget.PCrudFilterDialog'); dojo.require('openils.widget.AutoFieldWidget'); @@ -8,6 +7,163 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { dojo.require('dijit.Dialog'); dojo.require('openils.Util'); + /* This is not the dijit per se. Search further in this file for + * "dojo.declare" for the dijit. */ + function PCrudFilterRowTable() { + var self = this; + + this._init = function(container, field_store, fm_class) { + this.container = container; + this.field_store = field_store; + this.fm_class = fm_class; + + this.rows = {}; + this.row_index = 0; + + this._build_table(); + }; + + this._build_table = function() { + this.table = dojo.create( + "table", { + "className": "oils-pcrudfilterdialog-table" + }, this.container + ); + + this.add_row(); + }; + + this.add_row = function() { + var row_id = this.row_index++; + this.rows[row_id] = new PCrudFilterRow(this, row_id); + }; + + this.remove_row = function(row_id) { + this.rows[row_id].destroy(); + delete this.rows[row_id]; + }; + + this.compile = function() { + var filter = {}; + for (var row_id in this.rows) { + var row = this.rows[row_id]; + var value = row.compile(); + var field = row.get_selected_field(); + + if (typeof(value) != "undefined" && + typeof(field) != "undefined") { + filter[field] = value; + } + } + + /* Don't return an empty filter: pcrud can't use that. */ + if (openils.Util.objectProperties(filter).length < 1) + filter[fieldmapper[this.fm_class].Identifier] = {"!=": null}; + + dump(js2JSON(filter) + "\n"); // LFW XXX + return filter; + }; + + this._init.apply(this, arguments); + } + + function PCrudFilterRow() { + var self = this; + + this._init = function(filter_row_table, row_id) { + this.filter_row_table = filter_row_table; + this.row_id = row_id; + + this._build(); + }; + + this._build = function() { + this.tr = dojo.create("tr", {}, this.filter_row_table.table); + + this._create_field_selector(); + this._create_operator_selector(); + this._create_value_slot(); + this._create_remover(); + }; + + this._create_field_selector = function() { + var td = dojo.create("td", {}, this.tr); + this.field_selector = new dijit.form.FilteringSelect( + { + "labelAttr": "label", + "onChange": function(value) { + self.update_selected_field(value); + }, + "store": this.filter_row_table.field_store + }, dojo.create("span", {}, td) + ); + }; + + this._create_operator_selector = function() { + }; + + this._create_value_slot = function() { + this.value_slot = dojo.create("td", {"innerHTML": "-"}, this.tr); + }; + + this._create_remover = function() { + var td = dojo.create("td", {}, this.tr); + var anchor = dojo.create( + "a", { + "className": "oils-pcrudfilterdialog-remover", + "innerHTML": "X", + "href": "#", + "onclick": function() { + self.filter_row_table.remove_row(self.row_id); + } + }, td + ); + }; + + this._clear_value_slot = function() { + if (this.value_widget) + this.value_widget.destroy(); + + 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._clear_value_slot(); + + this.value_widget = new openils.widget.AutoFieldWidget({ + "fmClass": this.filter_row_table.fm_class, + "fmField": value, + "parentNode": dojo.create("div", {}, this.value_slot) + }); + + this.value_widget.build(); + }; + + this.get_selected_field = function() { + return this.field_selector.attr("value"); + }; + + this.compile = function() { + if (this.value_widget) + return this.value_widget.getFormattedValue(); + return undefined; + }; + + this.destroy = function() { + this._clear_value_slot(); + this.field_selector.destroy(); + + dojo.destroy(this.tr); + }; + + this._init.apply(this, arguments); + } + + /** * Given a fieldmapper object, this builds a pop-up dialog used for editing the object */ @@ -20,6 +176,7 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { constructor : function(args) { for(var k in args) this[k] = args[k]; + this.title = this.title || "Filter Rows"; /* XXX i18n */ this.widgetIndex = 0; this.widgetCache = {}; }, @@ -45,84 +202,49 @@ if(!dojo._hasResource['openils.widget.PCrudFilterDialog']) { ) } }); - - // TODO i18n/CSS - dojo.place( - dojo.create( - 'div', - {innerHTML:'Filter Selector', style:'text-align:center;width:100%;padding:10px;'} - ), this.domNode); - - dojo.place( - new dijit.form.Button({ - label:"Apply", - onClick : function() { - if(self.onApply) - self.onApply(self.compileFilter()); - self.hide(); - } - }).domNode, this.domNode); - - dojo.place( - new dijit.form.Button({ - label:"Cancel", - onClick : function() { - if(self.onCancel) - self.onCancel(); - self.hide(); - } - }).domNode, this.domNode); - - this.table = dojo.place(dojo.create('table'), this.domNode); - openils.Util.addCSSClass(this.table, 'oils-fm-edit-dialog'); - this.insertFieldSelector(); - }, - insertFieldSelector : function() { - var selector = new dijit.form.FilteringSelect({labelAttr:'label', store:this.fieldStore}); - var row = dojo.place(dojo.create('tr'), this.table); - var selectorTd = dojo.place(dojo.create('td'), row); - var valueTd = dojo.place(dojo.create('td'), row); - dojo.place(selector.domNode, selectorTd); + this.filter_row_table = new PCrudFilterRowTable( + dojo.create("div", {}, this.domNode), + this.fieldStore, this.fmClass + ); - // dummy text box - dojo.place(new dijit.form.TextBox().domNode, valueTd); + var button_holder = dojo.create( + "div", { + "className": "oils-pcrudfilterdialog-buttonholder" + }, this.domNode + ); - // when a field is selected, update the value widget - var self = this; - dojo.connect(selector, 'onChange', - function(value) { - - if(valueTd.childNodes[0]) - valueTd.removeChild(valueTd.childNodes[0]); - - var widget = new openils.widget.AutoFieldWidget({ - fmClass : self.fmClass, - fmField : value, - parentNode : dojo.place(dojo.create('div'), valueTd) - }); - widget.build(); - - if(self.widgetCache[selector.widgetIndex]) { - self.widgetCache[selector.widgetIndex].widget.destroy(); - delete self.widgetCache[selector.widgetIndex]; + new dijit.form.Button( + { + "label": "Add Row", /* XXX i18n */ + "onClick": function() { + self.filter_row_table.add_row(); } + }, dojo.create("span", {}, button_holder) + ); - selector.widgetIndex = this.widgetIndex; - self.widgetCache[self.widgetIndex++] = widget; - } + new dijit.form.Button( + { + "label": "Apply", /* XXX i18n */ + "onClick": function() { + if (self.onApply) + self.onApply(self.filter_row_table.compile()); + self.hide(); + } + }, dojo.create("span", {}, button_holder) ); - }, - compileFilter : function() { - var filter = {}; - for(var i in this.widgetCache) { - var widget = this.widgetCache[i]; - filter[widget.fmField] = widget.getFormattedValue(); - } - return filter; + new dijit.form.Button( + { + "label": "Cancel", /* XXX i18n */ + "onClick": function() { + if (self.onCancel) + self.onCancel(); + self.hide(); + } + }, dojo.create("span", {}, button_holder) + ); } } ); } - -- 2.11.0