]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/widget/AutoGrid.js
allow the caller to define a function that tells the autofield widget to disable...
[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                     disableWidgetTest : this.disableWidgetTest,
144                     onPostSubmit : function() {
145                         for(var i in fmObject._fields) {
146                             var field = fmObject._fields[i];
147                             if(idents.filter(function(j){return (j == field)})[0])
148                                 continue; // don't try to edit an identifier field
149                             grid.store.setValue(storeItem, field, fmObject[field]());
150                         }
151                         if(self.onPostUpdate)
152                             self.onPostUpdate(storeItem, rowIndex);
153                         setTimeout(
154                             function(){
155                                 try { 
156                                     grid.views.views[0].getCellNode(rowIndex, 0).focus(); 
157                                 } catch (E) {}
158                             },200
159                         );
160                         if(onPostSubmit) onPostSubmit();
161                     },
162                     onCancel : function() {
163                         setTimeout(function(){
164                             grid.views.views[0].getCellNode(rowIndex, 0).focus();},200);
165                         if(onCancel) onCancel();
166                     }
167                 });
168
169                 pane.fieldOrder = this.fieldOrder;
170                 pane.mode = 'update';
171                 return pane;
172             },
173
174             _makeCreatePane : function(onPostSubmit, onCancel) {
175                 var grid = this;
176                 var pane = new openils.widget.EditPane({
177                     fmClass : this.fmClass,
178                     overrideWidgets : this.overrideEditWidgets,
179                     overrideWidgetClass : this.overrideEditWidgetClass,
180                     disableWidgetTest : this.disableWidgetTest,
181                     onPostSubmit : function(r) {
182                         var fmObject = openils.Util.readResponse(r);
183                         if(fmObject) 
184                             grid.store.newItem(fmObject.toStoreItem());
185                         if(grid.onPostCreate)
186                             grid.onPostCreate(fmObject);
187                         setTimeout(function(){
188                             try {
189                                 grid.selection.select(grid.rowCount-1);
190                                 grid.views.views[0].getCellNode(grid.rowCount-1, 1).focus();
191                             } catch (E) {}
192                         },200);
193                         if(onPostSubmit)
194                             onPostSubmit();
195                     },
196                     onCancel : function() {
197                         if(onCancel) onCancel();
198                     }
199                 });
200                 pane.fieldOrder = this.fieldOrder;
201                 pane.mode = 'create';
202                 return pane;
203             },
204
205             // .startup() is called within
206             _makeClonePane : function(storeItem, rowIndex, onPostSubmit, onCancel) {
207                 var clonePane = this._makeCreatePane(onPostSubmit, onCancel);
208                 var origPane = this._makeEditPane(this.selection.getFirstSelected(), this.focus.rowIndex);
209                 clonePane.startup();
210                 origPane.startup();
211                 dojo.forEach(origPane.fieldList,
212                     function(field) {
213                         if(field.widget.widget.attr('disabled')) return;
214                         var w = clonePane.fieldList.filter(
215                             function(i) { return (i.name == field.name) })[0];
216                         w.widget.baseWidgetValue(field.widget.widgetValue); // sync widgets
217                         w.widget.onload = function(){w.widget.baseWidgetValue(field.widget.widgetValue)}; // async widgets
218                     }
219                 );
220                 origPane.destroy();
221                 return clonePane;
222             },
223
224
225             _drawEditDialog : function(storeItem, rowIndex) {
226                 var self = this;
227                 var done = function() { self.hideDialog(); };
228                 var pane = this._makeEditPane(storeItem, rowIndex, done, done);
229                 this.editDialog = new openils.widget.EditDialog({editPane:pane});
230                 this.editDialog.startup();
231                 this.editDialog.show();
232             },
233
234             showCreateDialog : function() {
235                 var self = this;
236                 var done = function() { self.hideDialog(); };
237                 var pane = this._makeCreatePane(done, done);
238                 this.editDialog = new openils.widget.EditDialog({editPane:pane});
239                 this.editDialog.startup();
240                 this.editDialog.show();
241             },
242
243             _drawEditPane : function(storeItem, rowIndex) {
244                 var self = this;
245                 var done = function() { self.hidePane(); };
246                 dojo.style(this.domNode, 'display', 'none');
247                 this.editPane = this._makeEditPane(storeItem, rowIndex, done, done);
248                 this.editPane.startup();
249                 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
250             },
251
252             showClonePane : function(storeItem, rowIndex) {
253                 var self = this;
254                 var done = function() { self.hidePane(); };
255                 dojo.style(this.domNode, 'display', 'none');
256                 this.editPane = this._makeClonePane(storeItem, rowIndex, done, done);
257                 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
258             },
259
260             showCreatePane : function() {
261                 var self = this;
262                 var done = function() { self.hidePane(); };
263                 dojo.style(this.domNode, 'display', 'none');
264                 this.editPane = this._makeCreatePane(done, done);
265                 this.editPane.startup();
266                 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
267             },
268
269             hideDialog : function() {
270                 this.editDialog.hide(); 
271                 this.editDialog.destroy(); 
272                 delete this.editDialog;
273             },
274
275             hidePane : function() {
276                 this.domNode.parentNode.removeChild(this.editPane.domNode);
277                 this.editPane.destroy();
278                 delete this.editPane;
279                 dojo.style(this.domNode, 'display', 'block');
280                 this.update();
281             },
282             
283             resetStore : function() {
284                 this.setStore(this.buildAutoStore());
285             },
286
287             loadAll : function(opts, search) {
288                 dojo.require('openils.PermaCrud');
289                 if(!opts) opts = {};
290                 var self = this;
291                 opts = dojo.mixin(opts, {
292                     async : true,
293                     streaming : true,
294                     onresponse : function(r) {
295                         var item = openils.Util.readResponse(r);
296                         self.store.newItem(item.toStoreItem());
297                     }
298                 });
299                 if(search)
300                     new openils.PermaCrud().search(this.fmClass, search, opts);
301                 else
302                     new openils.PermaCrud().retrieveAll(this.fmClass, opts);
303             }
304         } 
305     );
306     openils.widget.AutoGrid.markupFactory = dojox.grid.DataGrid.markupFactory;
307
308     openils.widget.AutoGrid.defaultGetter = function(rowIndex, item) {
309         if(!item) return '';
310         var val = this.grid.store.getValue(item, this.field);
311         var autoWidget = new openils.widget.AutoFieldWidget({
312             fmClass: this.grid.fmClass,
313             fmField: this.field,
314             widgetValue : val,
315         });
316         return autoWidget.getDisplayString();
317     }
318 }
319