]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/widget/AutoGrid.js
when non-IDL fields are added to the grid and a field order is defined, plop the...
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / widget / AutoGrid.js
1 if(!dojo._hasResource['openils.widget.AutoGrid']) {
2     dojo.provide('openils.widget.AutoGrid');
3     dojo.require('dojox.grid.DataGrid');
4     dojo.require('openils.widget.AutoWidget');
5     dojo.require('openils.widget.AutoFieldWidget');
6     dojo.require('openils.widget.EditPane');
7     dojo.require('openils.widget.EditDialog');
8     dojo.require('openils.Util');
9
10     dojo.declare(
11         'openils.widget.AutoGrid',
12         [dojox.grid.DataGrid, openils.widget.AutoWidget],
13         {
14
15             /* if true, pop up an edit dialog when user hits Enter on a give row */
16             editOnEnter : false, 
17             defaultCellWidth : null,
18             editStyle : 'dialog',
19             suppressFields : null,
20
21             /* by default, don't show auto-generated (sequence) fields */
22             showSequenceFields : false, 
23
24             startup : function() {
25                 this.selectionMode = 'single';
26                 this.inherited(arguments);
27                 this.initAutoEnv();
28                 this.setStructure(this._compileStructure());
29                 this.setStore(this.buildAutoStore());
30                 this.overrideEditWidgets = {};
31                 this.overrideEditWidgetClass = {};
32                 if(this.editOnEnter) 
33                     this._applyEditOnEnter();
34                 else if(this.singleEditStyle) 
35                     this._applySingleEditStyle();
36             },
37
38             _compileStructure : function() {
39                 var existing = (this.structure && this.structure[0].cells[0]) ? 
40                     this.structure[0].cells[0] : [];
41                 var fields = [];
42
43                 var self = this;
44                 function pushEntry(entry) {
45                     if(self.suppressFields) {
46                         if(dojo.indexOf(self.suppressFields, entry.field) != -1)
47                             return;
48                     }
49                     if(!entry.get) 
50                         entry.get = openils.widget.AutoGrid.defaultGetter
51                     if(!entry.width && self.defaultCellWidth)
52                         entry.width = self.defaultCellWidth;
53                     fields.push(entry);
54                 }
55
56                 if(!this.fieldOrder) {
57                     /* no order defined, start with any explicit grid fields */
58                     for(var e in existing) {
59                         var entry = existing[e];
60                         var field = this.fmIDL.fields.filter(
61                             function(i){return (i.name == entry.field)})[0];
62                         if(field) entry.name = entry.name || field.label;
63                         pushEntry(entry);
64                     }
65                 }
66
67                 for(var f in this.sortedFieldList) {
68                     var field = this.sortedFieldList[f];
69                     if(!field || field.virtual) continue;
70                     
71                     // field was already added above
72                     if(fields.filter(function(i){return (i.field == field.name)})[0]) 
73                         continue;
74
75                     if(!this.showSequenceFields && field.name == this.fmIDL.pkey && this.fmIDL.pkey_sequence)
76                         continue; 
77                     var entry = existing.filter(function(i){return (i.field == field.name)})[0];
78                     if(entry) entry.name = field.label;
79                     else entry = {field:field.name, name:field.label};
80                     pushEntry(entry);
81                 }
82
83                 if(this.fieldOrder) {
84                     /* append any explicit non-IDL grid fields to the end */
85                     for(var e in existing) {
86                         var entry = existing[e];
87                         var field = fields.filter(
88                             function(i){return (i.field == entry.field)})[0];
89                         if(field) continue; // don't duplicate
90                         pushEntry(entry);
91                     }
92                 }
93
94
95                 return [{cells: [fields]}];
96             },
97
98             _applySingleEditStyle : function() {
99                 this.onMouseOverRow = function(e) {};
100                 this.onMouseOutRow = function(e) {};
101                 this.onCellFocus = function(cell, rowIndex) { 
102                     this.selection.deselectAll();
103                     this.selection.select(this.focus.rowIndex);
104                 };
105             },
106
107             /* capture keydown and launch edit dialog on enter */
108             _applyEditOnEnter : function() {
109                 this._applySingleEditStyle();
110
111                 dojo.connect(this, 'onRowDblClick',
112                     function(e) {
113                         if(this.editStyle == 'pane')
114                             this._drawEditPane(this.selection.getFirstSelected(), this.focus.rowIndex);
115                         else
116                             this._drawEditDialog(this.selection.getFirstSelected(), this.focus.rowIndex);
117                     }
118                 );
119
120                 dojo.connect(this, 'onKeyDown',
121                     function(e) {
122                         if(e.keyCode == dojo.keys.ENTER) {
123                             this.selection.deselectAll();
124                             this.selection.select(this.focus.rowIndex);
125                             if(this.editStyle == 'pane')
126                                 this._drawEditPane(this.selection.getFirstSelected(), this.focus.rowIndex);
127                             else
128                                 this._drawEditDialog(this.selection.getFirstSelected(), this.focus.rowIndex);
129                         }
130                     }
131                 );
132             },
133
134             _makeEditPane : function(storeItem, rowIndex, onPostSubmit, onCancel) {
135                 var grid = this;
136                 var fmObject = new fieldmapper[this.fmClass]().fromStoreItem(storeItem);
137                 var idents = grid.store.getIdentityAttributes();
138
139                 var pane = new openils.widget.EditPane({
140                     fmObject:fmObject,
141                     overrideWidgets : this.overrideEditWidgets,
142                     overrideWidgetClass : this.overrideEditWidgetClass,
143                     onPostSubmit : function() {
144                         for(var i in fmObject._fields) {
145                             var field = fmObject._fields[i];
146                             if(idents.filter(function(j){return (j == field)})[0])
147                                 continue; // don't try to edit an identifier field
148                             grid.store.setValue(storeItem, field, fmObject[field]());
149                         }
150                         if(self.onPostUpdate)
151                             self.onPostUpdate(storeItem, rowIndex);
152                         setTimeout(
153                             function(){
154                                 try { 
155                                     grid.views.views[0].getCellNode(rowIndex, 0).focus(); 
156                                 } catch (E) {}
157                             },200
158                         );
159                         if(onPostSubmit) onPostSubmit();
160                     },
161                     onCancel : function() {
162                         setTimeout(function(){
163                             grid.views.views[0].getCellNode(rowIndex, 0).focus();},200);
164                         if(onCancel) onCancel();
165                     }
166                 });
167
168                 pane.fieldOrder = this.fieldOrder;
169                 pane.mode = 'update';
170                 return pane;
171             },
172
173             _makeCreatePane : function(onPostSubmit, onCancel) {
174                 var grid = this;
175                 var pane = new openils.widget.EditPane({
176                     fmClass : this.fmClass,
177                     overrideWidgets : this.overrideEditWidgets,
178                     overrideWidgetClass : this.overrideEditWidgetClass,
179                     onPostSubmit : function(r) {
180                         var fmObject = openils.Util.readResponse(r);
181                         if(fmObject) 
182                             grid.store.newItem(fmObject.toStoreItem());
183                         if(grid.onPostCreate)
184                             grid.onPostCreate(fmObject);
185                         setTimeout(function(){
186                             try {
187                                 grid.selection.select(grid.rowCount-1);
188                                 grid.views.views[0].getCellNode(grid.rowCount-1, 1).focus();
189                             } catch (E) {}
190                         },200);
191                         if(onPostSubmit)
192                             onPostSubmit();
193                     },
194                     onCancel : function() {
195                         if(onCancel) onCancel();
196                     }
197                 });
198                 pane.fieldOrder = this.fieldOrder;
199                 pane.mode = 'create';
200                 return pane;
201             },
202
203             // .startup() is called within
204             _makeClonePane : function(storeItem, rowIndex, onPostSubmit, onCancel) {
205                 var clonePane = this._makeCreatePane(onPostSubmit, onCancel);
206                 var origPane = this._makeEditPane(this.selection.getFirstSelected(), this.focus.rowIndex);
207                 clonePane.startup();
208                 origPane.startup();
209                 dojo.forEach(origPane.fieldList,
210                     function(field) {
211                         if(field.widget.widget.attr('disabled')) return;
212                         var w = clonePane.fieldList.filter(
213                             function(i) { return (i.name == field.name) })[0];
214                         w.widget.baseWidgetValue(field.widget.widgetValue); // sync widgets
215                         w.widget.onload = function(){w.widget.baseWidgetValue(field.widget.widgetValue)}; // async widgets
216                     }
217                 );
218                 origPane.destroy();
219                 return clonePane;
220             },
221
222
223             _drawEditDialog : function(storeItem, rowIndex) {
224                 var self = this;
225                 var done = function() { self.hideDialog(); };
226                 var pane = this._makeEditPane(storeItem, rowIndex, done, done);
227                 this.editDialog = new openils.widget.EditDialog({editPane:pane});
228                 this.editDialog.startup();
229                 this.editDialog.show();
230             },
231
232             showCreateDialog : function() {
233                 var self = this;
234                 var done = function() { self.hideDialog(); };
235                 var pane = this._makeCreatePane(done, done);
236                 this.editDialog = new openils.widget.EditDialog({editPane:pane});
237                 this.editDialog.startup();
238                 this.editDialog.show();
239             },
240
241             _drawEditPane : function(storeItem, rowIndex) {
242                 var self = this;
243                 var done = function() { self.hidePane(); };
244                 dojo.style(this.domNode, 'display', 'none');
245                 this.editPane = this._makeEditPane(storeItem, rowIndex, done, done);
246                 this.editPane.startup();
247                 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
248             },
249
250             showClonePane : function(storeItem, rowIndex) {
251                 var self = this;
252                 var done = function() { self.hidePane(); };
253                 dojo.style(this.domNode, 'display', 'none');
254                 this.editPane = this._makeClonePane(storeItem, rowIndex, done, done);
255                 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
256             },
257
258             showCreatePane : function() {
259                 var self = this;
260                 var done = function() { self.hidePane(); };
261                 dojo.style(this.domNode, 'display', 'none');
262                 this.editPane = this._makeCreatePane(done, done);
263                 this.editPane.startup();
264                 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
265             },
266
267             hideDialog : function() {
268                 this.editDialog.hide(); 
269                 this.editDialog.destroy(); 
270                 delete this.editDialog;
271             },
272
273             hidePane : function() {
274                 this.domNode.parentNode.removeChild(this.editPane.domNode);
275                 this.editPane.destroy();
276                 delete this.editPane;
277                 dojo.style(this.domNode, 'display', 'block');
278                 this.update();
279             },
280             
281             resetStore : function() {
282                 this.setStore(this.buildAutoStore());
283             },
284
285             loadAll : function(opts, search) {
286                 dojo.require('openils.PermaCrud');
287                 if(!opts) opts = {};
288                 var self = this;
289                 opts = dojo.mixin(opts, {
290                     async : true,
291                     streaming : true,
292                     onresponse : function(r) {
293                         var item = openils.Util.readResponse(r);
294                         self.store.newItem(item.toStoreItem());
295                     }
296                 });
297                 if(search)
298                     new openils.PermaCrud().search(this.fmClass, search, opts);
299                 else
300                     new openils.PermaCrud().retrieveAll(this.fmClass, opts);
301             }
302         } 
303     );
304     openils.widget.AutoGrid.markupFactory = dojox.grid.DataGrid.markupFactory;
305
306     openils.widget.AutoGrid.defaultGetter = function(rowIndex, item) {
307         if(!item) return '';
308         var val = this.grid.store.getValue(item, this.field);
309         var autoWidget = new openils.widget.AutoFieldWidget({
310             fmClass: this.grid.fmClass,
311             fmField: this.field,
312             widgetValue : val,
313         });
314         return autoWidget.getDisplayString();
315     }
316 }
317