From: Lebbeous Fogle-Weekley Date: Tue, 27 Mar 2012 18:25:33 +0000 (-0400) Subject: Fix a bug in magic scroll; start hooking up Edit{Pane,Dialog} X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=13f53b32543023a92c1c200938d3dcb79fea6b5c;p=evergreen%2Fequinox.git Fix a bug in magic scroll; start hooking up Edit{Pane,Dialog} Signed-off-by: Lebbeous Fogle-Weekley --- diff --git a/Open-ILS/src/templates/conify/flattener_test.tt2 b/Open-ILS/src/templates/conify/flattener_test.tt2 index 8a36ec24b7..0bcad40540 100644 --- a/Open-ILS/src/templates/conify/flattener_test.tt2 +++ b/Open-ILS/src/templates/conify/flattener_test.tt2 @@ -3,36 +3,43 @@ - - - - - - - - - - -
BarcodeCirculation Library NameCirculation LibraryCall NumberShelving Location
+
+
+
Flattener Test
+
+ + +
+
+ + + + + + + + + + + +
BarcodeCirculation Library NameCirculation LibraryCall NumberShelving Location
+
[% END %] diff --git a/Open-ILS/web/js/dojo/openils/FlattenerStore.js b/Open-ILS/web/js/dojo/openils/FlattenerStore.js index f1eaa2fb34..c9ad647b95 100644 --- a/Open-ILS/web/js/dojo/openils/FlattenerStore.js +++ b/Open-ILS/web/js/dojo/openils/FlattenerStore.js @@ -23,7 +23,6 @@ if (!dojo._hasResource["openils.FlattenerStore"]) { } } - dojo.declare( "openils.FlattenerStore", null, { @@ -37,23 +36,27 @@ if (!dojo._hasResource["openils.FlattenerStore"]) { "sloClause": null, "limit": 25, "offset": 0, - + "baseSort": null, + "defaultSort": null, "constructor": function(/* object */ args) { - dojo.mixin(this, args); /* XXX do we actually need this? */ + dojo.mixin(this, args); this._current_items = {}; }, /* turn dojo-style sort into flattener-style sort */ "_prepare_sort": function(dsort) { - if (!dsort) - return []; - return dsort.map( - function(d) { - var o = {}; - o[d.attribute] = d.descending ? "desc" : "asc"; - return o; - } + if (!dsort || !dsort.length) + return this.baseSort || this.defaultSort || []; + + return (this.baseSort || []).concat( + dsort.map( + function(d) { + var o = {}; + o[d.attribute] = d.descending ? "desc" : "asc"; + return o; + } + ) ); }, @@ -163,7 +166,7 @@ if (!dojo._hasResource["openils.FlattenerStore"]) { }, "isItemLoaded": function(/* anything */ something) { - console.warning("[unfinished] isItemLoaded(" + something + ")"); + console.warn("[unfinished] isItemLoaded(" + something + ")"); /* This is assuming items are always loaded, which is probably not right for this particular store.*/ return this.isItem(something); @@ -231,16 +234,23 @@ if (!dojo._hasResource["openils.FlattenerStore"]) { if (when < self._last_fetch) /* Stale response. Discard. */ return; + /* The following is apparently the "right" way to call onBegin, + * and is very necessary (at least in Dojo 1.3.3) to get + * the Grid's fetch-more-when-I-need-it logic to work + * correctly. *grumble* crummy documentation *snarl!* + */ if (typeof req.onBegin == "function") { /* We lie to onBegin like this because we don't know how * many more rows we might be able to fetch if the * user keeps scrolling. Once we get a number of * results that is less than the limit we asked for, - * the grid is smart enough to know we're at the end and - * it does the right thing. */ - var might_be_a_lie = obj.length; + * we stop exaggerating, and the grid is smart enough to + * know we're at the end and it does the right thing. */ + var might_be_a_lie = req.start; if (obj.length >= req.count) - might_be_a_lie += req.count; + might_be_a_lie += obj.length + req.count; + else + might_be_a_lie += obj.length; req.onBegin.call(callback_scope, might_be_a_lie, req); } @@ -302,7 +312,7 @@ if (!dojo._hasResource["openils.FlattenerStore"]) { * doesn't use it (or loadItem)?), and needs to be able to call * fetch() or to talk to the web service directly. */ - console.warning( + console.warn( "[unfinished] fetchItemByIdentity(" + dojo.toJson(keywordArgs) + ")" ); diff --git a/Open-ILS/web/js/dojo/openils/widget/FlattenerGrid.js b/Open-ILS/web/js/dojo/openils/widget/FlattenerGrid.js index 4fd1b9e02e..74e76e3a1c 100644 --- a/Open-ILS/web/js/dojo/openils/widget/FlattenerGrid.js +++ b/Open-ILS/web/js/dojo/openils/widget/FlattenerGrid.js @@ -4,16 +4,33 @@ if (!dojo._hasResource["openils.widget.FlattenerGrid"]) { dojo.require("DojoSRF"); dojo.require("dojox.grid.DataGrid"); dojo.require("openils.FlattenerStore"); + dojo.require("openils.PermaCrud"); dojo.require("openils.widget.GridColumnPicker"); + dojo.require("openils.widget.EditDialog"); /* includes EditPane */ dojo.declare( "openils.widget.FlattenerGrid", [dojox.grid.DataGrid], { + /* These potential constructor arguments are useful to + * lattenerGrid in their own right */ "columnReordering": true, + "columnPickerPrefix": null, + + /* These potential constructor arguments maybe useful to + * FlattenerGrid in their own right, and are passed to + * FlattenerStore. */ "fmClass": null, "fmIdentifier": null, "mapExtras": null, - "columnPickerPrefix": null, + "defaultSort": null, /* whatever the UI says /replaces/ this */ + "baseSort": null, /* whatever the UI says /follows/ this */ + + /* These potential constructor arguments are for functionality + * copied from AutoGrid */ + "editOnEnter": false, /* also implies edit-on-dblclick */ + "editStyle": "dialog", /* "dialog" or "pane" */ + "requiredFields": null, /* affects create/edit dialogs */ + "suppressEditFields": null, /* affects create/edit dialogs */ /* _generate_map() lives to interpret the attributes of the * FlattenerGrid dijit itself plus those definined in @@ -85,6 +102,7 @@ if (!dojo._hasResource["openils.widget.FlattenerGrid"]) { "constructor": function(args) { dojo.mixin(this, args); + this.fmIdentifier = this.fmIdentifier || fieldmapper.IDL.fmclasses[this.fmClass].pkey; }, @@ -94,7 +112,9 @@ if (!dojo._hasResource["openils.widget.FlattenerGrid"]) { this.store = new openils.FlattenerStore({ "fmClass": this.fmClass, "fmIdentifier": this.fmIdentifier, - "mapClause": (this.mapClause || this._generate_map()) + "mapClause": (this.mapClause || this._generate_map()), + "baseSort": this.baseSort, + "defaultSort": this.defaultSort }); } @@ -106,6 +126,309 @@ if (!dojo._hasResource["openils.widget.FlattenerGrid"]) { } this.inherited(arguments); + + this._showing_create_pane = false; + + this.overrideEditWidgets = {}; + this.overrideEditWidgetClass = {}; + this.overrideWidgetArgs = {}; + + if (this.editOnEnter) + this._applyEditOnEnter(); + else if (this.singleEditStyle) + this._applySingleEditStyle(); + }, + + /* ******** below are methods mostly copied but + * slightly changed from AutoGrid ******** */ + + "_applySingleEditStyle": function() { + this.onMouseOverRow = function(e) {}; + this.onMouseOutRow = function(e) {}; + this.onCellFocus = function(cell, rowIndex) { + this.selection.deselectAll(); + this.selection.select(this.focus.rowIndex); + }; + }, + + /* capture keydown and launch edit dialog on enter */ + "_applyEditOnEnter": function() { + this._applySingleEditStyle(); + + dojo.connect( + this, "onRowDblClick", function(e) { + if (this.editStyle == "pane") + this._drawEditPane( + this.selection.getFirstSelected(), + this.focus.rowIndex + ); + else + this._drawEditDialog( + this.selection.getFirstSelected(), + this.focus.rowIndex + ); + } + ); + + dojo.connect( + this, "onKeyDown", function(e) { + if (e.keyCode == dojo.keys.ENTER) { + this.selection.deselectAll(); + this.selection.select(this.focus.rowIndex); + if (this.editStyle == "pane") + this._drawEditPane( + this.selection.getFirstSelected(), + this.focus.rowIndex + ); + else + this._drawEditDialog( + this.selection.getFirstSelected(), + this.focus.rowIndex + ); + } + } + ); + }, + + "_makeEditPane": function(storeItem, rowIndex, onPostSubmit, onCancel) { + var grid = this; + var fmObject = (new openils.PermaCrud()).retrieve( + this.fmClass, + this.store.getIdentity(storeItem) + ); + + var pane = new openils.widget.EditPane({ + "fmObject": fmObject, + "hideSaveButton": this.editReadOnly, + "readOnly": this.editReadOnly, + "overrideWidgets": this.overrideEditWidgets, + "overrideWidgetClass": this.overrideEditWidgetClass, + "overrideWidgetArgs": this.overrideWidgetArgs, + "disableWidgetTest": this.disableWidgetTest, + "requiredFields": this.requiredFields, + "suppressFields": this.suppressEditFields, + "onPostSubmit": function() { + console.info("onPostSubmit"); + console.warn("[unfinished] would update store with fmObject values here"); + // for(var i in fmObject._fields) { + // var field = fmObject._fields[i]; + // if(idents.filter(function(j){return (j == field)})[0]) + // continue; // don't try to edit an identifier field + // grid.store.setValue(storeItem, field, fmObject[field]()); + // } + if (grid.onPostUpdate) + grid.onPostUpdate(storeItem, rowIndex); + setTimeout( + function() { + try { + grid.views.views[0].getCellNode( + rowIndex, 0 + ).focus(); + } catch (E) { } + }, 200 + ); + if (onPostSubmit) + onPostSubmit(); + }, + "onCancel": function() { + console.info("onCancel"); + setTimeout( + function() { + grid.views.views[0].getCellNode( + rowIndex, 0 + ).focus(); + }, 200 + ); + if (onCancel) + onCancel(); + } + }); + + if (typeof this.editPaneOnSubmit == "function") + pane.onSubmit = this.editPaneOnSubmit; + + pane.fieldOrder = this.fieldOrder; + pane.mode = "update"; + return pane; + }, + + "_makeCreatePane": function(onPostSubmit, onCancel) { + var grid = this; + var pane = new openils.widget.EditPane({ + "fmClass": this.fmClass, + "overrideWidgets": this.overrideEditWidgets, + "overrideWidgetClass": this.overrideEditWidgetClass, + "overrideWidgetArgs": this.overrideWidgetArgs, + "disableWidgetTest": this.disableWidgetTest, + "requiredFields": this.requiredFields, + "suppressFields": this.suppressEditFields, + "onPostSubmit": function(req, cudResults) { + var fmObject = cudResults[0]; + if (grid.onPostCreate) + grid.onPostCreate(fmObject); + if (fmObject) { + //grid.store.newItem(fmObject.toStoreItem()); + console.warn("[unfinished] here we have fmObject and must update the grid somehow"); + } + + setTimeout( + function() { + try { + grid.selection.select(grid.rowCount - 1); + grid.views.views[0].getCellNode( + grid.rowCount - 1, 1 + ).focus(); + } catch (E) { } + }, 200 + ); + + if (onPostSubmit) + onPostSubmit(fmObject); + }, + "onCancel": function() { if (onCancel) onCancel(); } + }); + + if (typeof this.createPaneOnSubmit == "function") + pane.onSubmit = this.createPaneOnSubmit; + pane.fieldOrder = this.fieldOrder; + pane.mode = "create"; + return pane; + }, + + /** + * Creates an EditPane with a copy of the data from the provided store + * item for cloning said item + * @param {Object} storeItem Dojo data item + * @param {Number} rowIndex The Grid row index of the item to be cloned + * @param {Function} onPostSubmit Optional callback for post-submit behavior + * @param {Function} onCancel Optional callback for clone cancelation + * @return {Object} The clone EditPane + */ + "_makeClonePane": function(storeItem,rowIndex,onPostSubmit,onCancel) { + var clonePane = this._makeCreatePane(onPostSubmit, onCancel); + var origPane = this._makeEditPane(storeItem, rowIndex); + clonePane.startup(); + origPane.startup(); + dojo.forEach( + origPane.fieldList, function(field) { + if (field.widget.widget.attr('disabled')) + return; + + var w = clonePane.fieldList.filter( + function(i) { return (i.name == field.name) } + )[0]; + + // sync widgets + w.widget.baseWidgetValue(field.widget.widget.attr('value')); + + // async widgets + w.widget.onload = function() { + w.widget.baseWidgetValue( + field.widget.widget.attr('value') + ) + }; + } + ); + origPane.destroy(); + return clonePane; + }, + + + "_drawEditDialog": function(storeItem, rowIndex) { + var done = dojo.hitch(this, function() { this.hideDialog(); }); + var pane = this._makeEditPane(storeItem, rowIndex, done, done); + this.editDialog = new openils.widget.EditDialog({editPane:pane}); + this.editDialog.startup(); + this.editDialog.show(); + }, + + /** + * Generates an EditDialog for object creation and displays it to the user + */ + "showCreateDialog": function() { + var done = dojo.hitch(this, function() { this.hideDialog(); }); + var pane = this._makeCreatePane(done, done); + this.editDialog = new openils.widget.EditDialog({editPane:pane}); + this.editDialog.startup(); + this.editDialog.show(); + }, + + "_drawEditPane": function(storeItem, rowIndex) { + var done = dojo.hitch(this, function() { this.hidePane(); }); + + dojo.style(this.domNode, "display", "none"); + + this.editPane = this._makeEditPane(storeItem, rowIndex, done, done); + this.editPane.startup(); + dojo.place(this.editPane.domNode, this.domNode, "before"); + + if (this.onEditPane) + this.onEditPane(this.editPane); + }, + + "showClonePane": function(onPostSubmit) { + var done = dojo.hitch(this, function() { this.hidePane(); }); + var row = this.getFirstSelectedRow(); + + if (!row) + return; + + if (onPostSubmit) { + postSubmit = dojo.hitch( + this, function(result) { + onPostSubmit(this.getItem(row), result); + this.hidePane(); + } + ); + } else { + postSubmit = done; + } + + dojo.style(this.domNode, "display", "none"); + this.editPane = this._makeClonePane( + this.getItem(row), row, postSubmit, done + ); + dojo.place(this.editPane.domNode, this.domNode, "before"); + if (this.onEditPane) + this.onEditPane(this.editPane); + }, + + "showCreatePane": function() { + if (this._showing_create_pane) + return; + this._showing_create_pane = true; + + var done = dojo.hitch( + this, function() { + this._showing_create_pane = false; + this.hidePane(); + } + ); + + dojo.style(this.domNode, "display", "none"); + + this.editPane = this._makeCreatePane(done, done); + this.editPane.startup(); + + dojo.place(this.editPane.domNode, this.domNode, "before"); + + if (this.onEditPane) + this.onEditPane(this.editPane); + }, + + "hideDialog": function() { + this.editDialog.hide(); + this.editDialog.destroy(); + delete this.editDialog; + this.update(); + }, + + "hidePane": function() { + this.domNode.parentNode.removeChild(this.editPane.domNode); + this.editPane.destroy(); + delete this.editPane; + dojo.style(this.domNode, "display", "block"); + this.update(); } } );