1 if(!dojo._hasResource['openils.widget.EditPane']) {
2 dojo.provide('openils.widget.EditPane');
3 dojo.require('openils.widget.AutoWidget');
4 dojo.require('openils.widget.AutoFieldWidget');
5 dojo.require('fieldmapper.Fieldmapper');
6 dojo.require('dijit.layout.ContentPane');
7 dojo.require('openils.Util');
8 dojo.require('openils.PermaCrud');
9 dojo.require('dijit.form.Button');
10 dojo.requireLocalization('openils.widget', 'AutoFieldWidget');
13 'openils.widget.EditPane',
14 [dijit.layout.ContentPane, openils.widget.AutoWidget],
17 onPostSubmit : null, // apply callback
18 onCancel : null, // cancel callback
19 hideActionButtons : false,
22 suppressFields : null,
23 requiredFields : null,
24 paneStackCount : 1, // how many fields to add to each row, for compressing display
26 constructor : function(args) {
33 * Builds a basic table of key / value pairs. Keys are IDL display labels.
34 * Values are dijit's, when values set
36 startup : function() {
37 this.inherited(arguments);
40 this.hideSaveButton = true;
42 // grab any field-level docs
44 var pcrud = new openils.PermaCrud();
45 this.fieldDocs = pcrud.search('fdoc', {fm_class:this.fmClass});
48 this.nls = dojo.i18n.getLocalization('openils.widget', 'AutoFieldWidget');
50 var table = this.existingTable;
52 var table = this.table = document.createElement('table');
53 this.domNode.appendChild(table);
55 var tbody = document.createElement('tbody');
56 table.appendChild(tbody);
59 if(this.fmIDL.permacrud && this.fmIDL.permacrud[this.mode])
60 this.limitPerms = this.fmIDL.permacrud[this.mode].perms;
62 if(!this.overrideWidgets)
63 this.overrideWidgets = {};
65 if(!this.overrideWidgetClass)
66 this.overrideWidgetClass = {};
68 if(!this.overrideWidgetArgs)
69 this.overrideWidgetArgs = {};
73 for(var f in this.sortedFieldList) {
74 var field = this.sortedFieldList[f];
75 if(!field || field.virtual || field.nonIdl) continue;
77 if(this.suppressFields && this.suppressFields.indexOf(field.name) > -1)
80 if(field.name == this.fmIDL.pkey && this.mode == 'create' && this.fmIDL.pkey_sequence)
81 continue; /* don't show auto-generated fields on create */
83 if(!this.overrideWidgetArgs[field.name])
84 this.overrideWidgetArgs[field.name] = {};
86 if(this.overrideWidgetArgs[field.name].hrbefore && this.paneStackCount <= 1) {
87 var hrTr = document.createElement('tr');
88 var hrTd = document.createElement('td');
89 var hr = document.createElement('hr');
91 dojo.addClass(hrTd, 'openils-widget-editpane-hr-cell');
93 hrTr.appendChild(hrTd);
94 tbody.appendChild(hrTr);
97 if((idx++ % this.paneStackCount) == 0 || !currentRow) {
98 // time to start a new row
99 currentRow = document.createElement('tr');
100 tbody.appendChild(currentRow);
103 //var docTd = document.createElement('td');
104 var nameTd = document.createElement('td');
105 var valTd = document.createElement('td');
106 var valSpan = document.createElement('span');
107 valTd.appendChild(valSpan);
108 dojo.addClass(nameTd, 'openils-widget-editpane-name-cell');
109 dojo.addClass(valTd, 'openils-widget-editpane-value-cell');
112 if(this.fieldDocs[field]) {
113 var helpLink = dojo.create('a');
114 var helpImg = dojo.create('img', {src:'/opac/images/advancedsearch-icon.png'}); // TODO Config
115 helpLink.appendChild(helpImg);
116 docTd.appendChild(helpLink);
120 nameTd.appendChild(document.createTextNode(field.label));
121 currentRow.setAttribute('fmfield', field.name);
122 //currentRow.appendChild(docTd);
123 currentRow.appendChild(nameTd);
124 currentRow.appendChild(valTd);
125 //dojo.addClass(docTd, 'oils-fm-edit-pane-help');
127 var args = dojo.mixin(
130 fmObject : this.fmObject,
131 fmClass : this.fmClass,
132 parentNode : valSpan,
133 orgLimitPerms : this.limitPerms,
134 readOnly : this.readOnly,
135 widget : this.overrideWidgets[field.name],
136 widgetClass : this.overrideWidgetClass[field.name],
137 disableWidgetTest : this.disableWidgetTest
139 this.overrideWidgetArgs[field.name] // per-field overrides
142 if (this.overrideWidgets[field.name]) {
143 if (this.overrideWidgets[field.name].shove) {
144 args.shove = dojo.mixin(
146 this.overrideWidgets[field.name].shove
152 dojo.addClass(nameTd, 'openils-widget-editpane-ro-name-cell');
153 dojo.addClass(valTd, 'openils-widget-editpane-ro-value-cell');
156 if(this.requiredFields && this.requiredFields.indexOf(field.name) >= 0) {
157 if(!args.dijitArgs) args.dijitArgs = {};
158 args.dijitArgs.required = true;
161 var widget = new openils.widget.AutoFieldWidget(args);
164 this.fieldList.push({name:field.name, widget:widget});
166 if(!this.hideActionButtons)
167 this.buildActionButtons(tbody);
169 openils.Util.addCSSClass(table, 'oils-fm-edit-pane');
172 applySaveOnEnter : function(widget) {
174 dojo.connect(this, 'onKeyDown',
176 if(e.keyCode == dojo.keys.ENTER)
177 self.performAutoEditAction();
182 buildActionButtons : function(tbody) {
183 var row = document.createElement('tr');
184 var cancelTd = document.createElement('td');
185 var applyTd = document.createElement('td');
186 var cancelSpan = document.createElement('span');
187 var applySpan = document.createElement('span');
188 row.appendChild(cancelTd);
189 row.appendChild(applyTd);
190 cancelTd.appendChild(cancelSpan);
191 applyTd.appendChild(applySpan);
192 tbody.appendChild(row);
195 new dijit.form.Button({
196 label: this.nls.CANCEL,
197 onClick : this.onCancel
200 if(this.hideSaveButton) return;
202 new dijit.form.Button({
204 onClick: function() {self.performAutoEditAction();}
208 getFields : function() {
209 return this.fieldList.map(function(a) { return a.name });
212 // Apply a function for the name and formatted value of each field
213 // in this edit pane. If any required value is null, then return
215 mapValues: function (fn) {
216 var e = 0, msg = '', lbl = this.fmIDL.label;
217 dojo.forEach(this.fieldList, function (f) {
219 if ((v = w.getFormattedValue()) === null && w.isRequired()) { e++; }
223 return new Error(dojo.string.substitute(this.nls.REQ_FIELDS_EMPTY, [lbl, e]));
227 getFieldValue : function(field, checkRequired) {
228 for(var i in this.fieldList) {
229 if(field == this.fieldList[i].name) {
230 var val = this.fieldList[i].widget.getFormattedValue();
232 val == null && /* XXX stricter check needed? */
233 this.fieldList[i].widget.isRequired()) {
234 throw new Error("req");
242 getFieldWidget : function(field) {
243 for (var i in this.fieldList)
244 if (field == this.fieldList[i].name)
245 return this.fieldList[i].widget;
248 setFieldValue : function(field, val) {
249 for(var i in this.fieldList) {
250 if(field == this.fieldList[i].name) {
251 this.fieldList[i].widget.widget.attr('value', val);
257 performAutoEditAction : function() {
259 self.performEditAction({
260 oncomplete:function(req, cudResults) {
261 if(self.onPostSubmit)
262 self.onPostSubmit(req, cudResults);
267 performEditAction : function(opts) {
269 var fields = this.getFields();
270 if(this.mode == 'create')
271 this.fmObject = new fieldmapper[this.fmClass]();
273 for(var idx in fields) {
274 this.fmObject[fields[idx]](
275 this.getFieldValue(fields[idx], true)
279 if (E.message == "req") /* req'd field set to null. bail. */
281 else /* something else went wrong? */
284 if(this.mode == 'create' && this.fmIDL.pkey_sequence)
285 this.fmObject[this.fmIDL.pkey](null);
286 if (typeof(this.onSubmit) == "function") {
287 this.onSubmit(this.fmObject, opts, self);
289 (new openils.PermaCrud())[this.mode](this.fmObject, opts);