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');
11 'openils.widget.AutoGrid',
12 [dojox.grid.DataGrid, openils.widget.AutoWidget],
15 /* if true, pop up an edit dialog when user hits Enter on a give row */
17 defaultCellWidth : null,
19 suppressFields : null,
21 selectorWidth : '1.5',
23 /* by default, don't show auto-generated (sequence) fields */
24 showSequenceFields : false,
26 startup : function() {
27 this.selectionMode = 'single';
28 this.sequence = openils.widget.AutoGrid.sequence++;
29 openils.widget.AutoGrid.gridCache[this.sequence] = this;
30 this.inherited(arguments);
32 this.attr('structure', this._compileStructure());
33 this.setStore(this.buildAutoStore());
34 this.overrideEditWidgets = {};
35 this.overrideEditWidgetClass = {};
37 this._applyEditOnEnter();
38 else if(this.singleEditStyle)
39 this._applySingleEditStyle();
41 if(!this.hideSelector) {
42 var header = this.layout.cells[0].view.getHeaderCellNode(0);
44 header.onclick = function() { self.toggleSelectAll(); }
48 /* Don't allow sorting on the selector column */
49 canSort : function(rowIdx) {
50 if(rowIdx == 1 && !this.hideSelector)
55 _compileStructure : function() {
56 var existing = (this.structure && this.structure[0].cells[0]) ?
57 this.structure[0].cells[0] : [];
61 function pushEntry(entry) {
62 if(self.suppressFields) {
63 if(dojo.indexOf(self.suppressFields, entry.field) != -1)
67 entry.get = openils.widget.AutoGrid.defaultGetter
68 if(!entry.width && self.defaultCellWidth)
69 entry.width = self.defaultCellWidth;
73 if(!this.hideSelector) {
74 // insert the selector column
77 formatter : function(rowIdx) { return self._formatRowSelectInput(rowIdx); },
78 get : function(rowIdx, item) { if(item) return rowIdx; },
79 width : this.selectorWidth,
85 if(!this.fieldOrder) {
86 /* no order defined, start with any explicit grid fields */
87 for(var e in existing) {
88 var entry = existing[e];
89 var field = this.fmIDL.fields.filter(
90 function(i){return (i.name == entry.field)})[0];
91 if(field) entry.name = entry.name || field.label;
96 for(var f in this.sortedFieldList) {
97 var field = this.sortedFieldList[f];
98 if(!field || field.virtual) continue;
100 // field was already added above
101 if(fields.filter(function(i){return (i.field == field.name)})[0])
104 var entry = existing.filter(function(i){return (i.field == field.name)})[0];
106 entry.name = field.label;
108 // unless specifically requested, hide sequence fields
109 if(!this.showSequenceFields && field.name == this.fmIDL.pkey && this.fmIDL.pkey_sequence)
112 entry = {field:field.name, name:field.label};
117 if(this.fieldOrder) {
118 /* append any explicit non-IDL grid fields to the end */
119 for(var e in existing) {
120 var entry = existing[e];
121 var field = fields.filter(
122 function(i){return (i.field == entry.field)})[0];
123 if(field) continue; // don't duplicate
128 return [{cells: [fields]}];
131 toggleSelectAll : function() {
132 var selected = this.getSelectedRows();
133 for(var i = 0; i < this.rowCount; i++) {
141 getSelectedRows : function() {
144 dojo.query('[name=autogrid.selector]', this.domNode),
147 rows.push(input.getAttribute('row'));
153 getFirstSelectedRow : function() {
154 return this.getSelectedRows()[0];
157 getSelectedItems : function() {
160 dojo.forEach(this.getSelectedRows(), function(idx) { items.push(self.getItem(idx)); });
164 selectRow : function(rowIdx) {
165 var inputs = dojo.query('[name=autogrid.selector]', this.domNode);
166 for(var i = 0; i < inputs.length; i++) {
167 if(inputs[i].getAttribute('row') == rowIdx) {
168 inputs[i].checked = true;
174 deSelectRow : function(rowIdx) {
175 var inputs = dojo.query('[name=autogrid.selector]', this.domNode);
176 for(var i = 0; i < inputs.length; i++) {
177 if(inputs[i].getAttribute('row') == rowIdx) {
178 inputs[i].checked = false;
184 deleteSelected : function() {
185 var items = this.getSelectedItems();
186 var total = items.length;
188 dojo.require('openils.PermaCrud');
189 var pcrud = new openils.PermaCrud();
192 var fmObject = new fieldmapper[self.fmClass]().fromStoreItem(item);
193 pcrud['delete'](fmObject, {oncomplete : function(r) { self.store.deleteItem(item) }});
198 _formatRowSelectInput : function(rowIdx) {
199 if(rowIdx === null || rowIdx === undefined) return '';
200 console.log("<input type='checkbox' name='autogrid.selector' row='" + rowIdx + "'/>");
201 return "<input type='checkbox' name='autogrid.selector' row='" + rowIdx + "'/>";
204 _applySingleEditStyle : function() {
205 this.onMouseOverRow = function(e) {};
206 this.onMouseOutRow = function(e) {};
207 this.onCellFocus = function(cell, rowIndex) {
208 this.selection.deselectAll();
209 this.selection.select(this.focus.rowIndex);
213 /* capture keydown and launch edit dialog on enter */
214 _applyEditOnEnter : function() {
215 this._applySingleEditStyle();
217 dojo.connect(this, 'onRowDblClick',
219 if(this.editStyle == 'pane')
220 this._drawEditPane(this.selection.getFirstSelected(), this.focus.rowIndex);
222 this._drawEditDialog(this.selection.getFirstSelected(), this.focus.rowIndex);
226 dojo.connect(this, 'onKeyDown',
228 if(e.keyCode == dojo.keys.ENTER) {
229 this.selection.deselectAll();
230 this.selection.select(this.focus.rowIndex);
231 if(this.editStyle == 'pane')
232 this._drawEditPane(this.selection.getFirstSelected(), this.focus.rowIndex);
234 this._drawEditDialog(this.selection.getFirstSelected(), this.focus.rowIndex);
240 _makeEditPane : function(storeItem, rowIndex, onPostSubmit, onCancel) {
242 var fmObject = new fieldmapper[this.fmClass]().fromStoreItem(storeItem);
243 var idents = grid.store.getIdentityAttributes();
245 var pane = new openils.widget.EditPane({
247 overrideWidgets : this.overrideEditWidgets,
248 overrideWidgetClass : this.overrideEditWidgetClass,
249 disableWidgetTest : this.disableWidgetTest,
250 onPostSubmit : function() {
251 for(var i in fmObject._fields) {
252 var field = fmObject._fields[i];
253 if(idents.filter(function(j){return (j == field)})[0])
254 continue; // don't try to edit an identifier field
255 grid.store.setValue(storeItem, field, fmObject[field]());
257 if(self.onPostUpdate)
258 self.onPostUpdate(storeItem, rowIndex);
262 grid.views.views[0].getCellNode(rowIndex, 0).focus();
266 if(onPostSubmit) onPostSubmit();
268 onCancel : function() {
269 setTimeout(function(){
270 grid.views.views[0].getCellNode(rowIndex, 0).focus();},200);
271 if(onCancel) onCancel();
275 pane.fieldOrder = this.fieldOrder;
276 pane.mode = 'update';
280 _makeCreatePane : function(onPostSubmit, onCancel) {
282 var pane = new openils.widget.EditPane({
283 fmClass : this.fmClass,
284 overrideWidgets : this.overrideEditWidgets,
285 overrideWidgetClass : this.overrideEditWidgetClass,
286 disableWidgetTest : this.disableWidgetTest,
287 onPostSubmit : function(r) {
288 var fmObject = openils.Util.readResponse(r);
290 grid.store.newItem(fmObject.toStoreItem());
291 if(grid.onPostCreate)
292 grid.onPostCreate(fmObject);
293 setTimeout(function(){
295 grid.selection.select(grid.rowCount-1);
296 grid.views.views[0].getCellNode(grid.rowCount-1, 1).focus();
302 onCancel : function() {
303 if(onCancel) onCancel();
306 pane.fieldOrder = this.fieldOrder;
307 pane.mode = 'create';
311 // .startup() is called within
312 _makeClonePane : function(storeItem, rowIndex, onPostSubmit, onCancel) {
313 var clonePane = this._makeCreatePane(onPostSubmit, onCancel);
314 var origPane = this._makeEditPane(storeItem, rowIndex);
317 dojo.forEach(origPane.fieldList,
319 if(field.widget.widget.attr('disabled')) return;
320 var w = clonePane.fieldList.filter(
321 function(i) { return (i.name == field.name) })[0];
322 w.widget.baseWidgetValue(field.widget.widgetValue); // sync widgets
323 w.widget.onload = function(){w.widget.baseWidgetValue(field.widget.widgetValue)}; // async widgets
331 _drawEditDialog : function(storeItem, rowIndex) {
333 var done = function() { self.hideDialog(); };
334 var pane = this._makeEditPane(storeItem, rowIndex, done, done);
335 this.editDialog = new openils.widget.EditDialog({editPane:pane});
336 this.editDialog.startup();
337 this.editDialog.show();
340 showCreateDialog : function() {
342 var done = function() { self.hideDialog(); };
343 var pane = this._makeCreatePane(done, done);
344 this.editDialog = new openils.widget.EditDialog({editPane:pane});
345 this.editDialog.startup();
346 this.editDialog.show();
349 _drawEditPane : function(storeItem, rowIndex) {
351 var done = function() { self.hidePane(); };
352 dojo.style(this.domNode, 'display', 'none');
353 this.editPane = this._makeEditPane(storeItem, rowIndex, done, done);
354 this.editPane.startup();
355 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
358 showClonePane : function() {
360 var done = function() { self.hidePane(); };
361 var row = this.getFirstSelectedRow();
363 dojo.style(this.domNode, 'display', 'none');
364 this.editPane = this._makeClonePane(this.getItem(row), row, done, done);
365 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
368 showCreatePane : function() {
370 var done = function() { self.hidePane(); };
371 dojo.style(this.domNode, 'display', 'none');
372 this.editPane = this._makeCreatePane(done, done);
373 this.editPane.startup();
374 this.domNode.parentNode.insertBefore(this.editPane.domNode, this.domNode);
377 hideDialog : function() {
378 this.editDialog.hide();
379 this.editDialog.destroy();
380 delete this.editDialog;
384 hidePane : function() {
385 this.domNode.parentNode.removeChild(this.editPane.domNode);
386 this.editPane.destroy();
387 delete this.editPane;
388 dojo.style(this.domNode, 'display', 'block');
392 resetStore : function() {
393 this.setStore(this.buildAutoStore());
396 loadAll : function(opts, search) {
397 dojo.require('openils.PermaCrud');
400 opts = dojo.mixin(opts, {
403 onresponse : function(r) {
404 var item = openils.Util.readResponse(r);
405 self.store.newItem(item.toStoreItem());
409 new openils.PermaCrud().search(this.fmClass, search, opts);
411 new openils.PermaCrud().retrieveAll(this.fmClass, opts);
416 // static ID generater seed
417 openils.widget.AutoGrid.sequence = 0;
418 openils.widget.AutoGrid.gridCache = {};
420 openils.widget.AutoGrid.markupFactory = dojox.grid.DataGrid.markupFactory;
422 openils.widget.AutoGrid.defaultGetter = function(rowIndex, item) {
424 var val = this.grid.store.getValue(item, this.field);
425 var autoWidget = new openils.widget.AutoFieldWidget({
426 fmClass: this.grid.fmClass,
432 //autoWidget.build();
433 return autoWidget.getDisplayString();