]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/widget/AutoFieldWidget.js
added int/float widgets
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / widget / AutoFieldWidget.js
1 if(!dojo._hasResource['openils.widget.AutoFieldWidget']) {
2     dojo.provide('openils.widget.AutoFieldWidget');
3     dojo.require('openils.Util');
4     dojo.require('openils.User');
5     dojo.require('fieldmapper.IDL');
6
7     dojo.declare('openils.widget.AutoFieldWidget', null, {
8
9         async : false,
10         cache : {},
11
12         /**
13          * args:
14          *  idlField -- Field description object from fieldmapper.IDL.fmclasses
15          *  fmObject -- If available, the object being edited.  This will be used 
16          *      to set the value of the widget.
17          *  fmClass -- Class name (not required if idlField or fmObject is set)
18          *  fmField -- Field name (not required if idlField)
19          *  parentNode -- If defined, the widget will be appended to this DOM node
20          *  dijitArgs -- Optional parameters object, passed directly to the dojo widget
21          *  orgLimitPerms -- If this field defines a set of org units and an orgLimitPerms 
22          *      is defined, the code will limit the org units in the set to those
23          *      allowed by the permission
24          */
25         constructor : function(args) {
26             for(var k in args)
27                 this[k] = args[k];
28
29             // find the field description in the IDL if not provided
30             if(this.fmObject) 
31                 this.fmClass = this.fmObject.classname;
32             this.fmIDL = fieldmapper.IDL.fmclasses[this.fmClass];
33
34             if(!this.idlField) {
35                 this.fmIDL = fieldmapper.IDL.fmclasses[this.fmClass];
36                 var fields = this.fmIDL.fields;
37                 for(var f in fields) 
38                     if(fields[f].name == this.fmField)
39                         this.idlField = fields[f];
40             }
41         },
42
43         /**
44          * Turn the widget-stored value into a value oils understands
45          */
46         getFormattedValue : function() {
47             var value = this.baseWidgetValue();
48
49             /* text widgets default to "" when no data is entered */
50             if(value == '') return null; 
51
52             switch(this.idlField.datatype) {
53                 case 'bool':
54                     return (value) ? 't' : 'f'
55                 case 'timestamp':
56                     return dojo.date.stamp.toISOString(value);
57                 default:
58                     return value;
59             }
60         },
61
62         baseWidgetValue : function(value) {
63             var attr = (this.readOnly) ? 'content' : 'value';
64             if(arguments.length) this.widget.attr(attr, value);
65             return this.widget.attr(attr);
66         },
67         
68         /**
69          * Turn the widget-stored value into something visually suitable
70          */
71         getDisplayString : function() {
72             var value = this.widgetValue;
73             switch(this.idlField.datatype) {
74                 case 'bool':
75                     return (value) ? 'True' : 'False'; // XXX i18n!
76                 case 'timestamp':
77                     dojo.require('dojo.date.locale');
78                     dojo.require('dojo.date.stamp');
79                     var date = dojo.date.stamp.fromISOString(value);
80                     return dojo.date.locale.format(date, {formatLength:'short'});
81                 case 'org_unit':
82                     return fieldmapper.aou.findOrgUnit(value).shortname();
83                 default:
84                     return value+'';
85             }
86         },
87
88         build : function(onload) {
89
90             if(this.widget) {
91                 // core widget provided for us, attach and move on
92                 if(this.parentNode) // may already be in the "right" place
93                     this.parentNode.appendChild(this.widget.domNode);
94                 return;
95             }
96
97             this.onload = onload;
98             if(this.widgetValue == null)
99                 this.widgetValue = (this.fmObject) ? this.fmObject[this.idlField.name]() : null;
100
101             if(this.readOnly) {
102                 dojo.require('dijit.layout.ContentPane');
103                 this.widget = new dijit.layout.ContentPane(this.dijitArgs, this.parentNode);
104
105             } else if(this.widgetClass) {
106                 dojo.require(this.widgetClass);
107                 eval('this.widget = new ' + this.widgetClass + '(this.dijitArgs, this.parentNode);');
108
109             } else {
110
111                 switch(this.idlField.datatype) {
112                     
113                     case 'id':
114                         dojo.require('dijit.form.TextBox');
115                         this.widget = new dijit.form.TextBox(this.dijitArgs, this.parentNode);
116                         this.widget.attr('disabled', true); // never allow editing of IDs
117                         break;
118
119                     case 'org_unit':
120                         this._buildOrgSelector();
121                         break;
122
123                     case 'money':
124                         dojo.require('dijit.form.CurrencyTextBox');
125                         this.widget = new dijit.form.CurrencyTextBox(this.dijitArgs, this.parentNode);
126                         break;
127
128                     case 'int':
129                         dojo.require('dijit.form.NumberTextBox');
130                         this.dijitArgs = dojo.mixin(this.dijitArgs || {}, {constraints:{places:0}});
131                         this.widget = new dijit.form.NumberTextBox(this.dijitArgs, this.parentNode);
132                         break;
133
134                     case 'float':
135                         dojo.require('dijit.form.NumberTextBox');
136                         this.widget = new dijit.form.NumberTextBox(this.dijitArgs, this.parentNode);
137                         break;
138
139                     case 'timestamp':
140                         dojo.require('dijit.form.DateTextBox');
141                         dojo.require('dojo.date.stamp');
142                         this.widget = new dijit.form.DateTextBox(this.dijitArgs, this.parentNode);
143                         if(this.widgetValue != null) 
144                             this.widgetValue = dojo.date.stamp.fromISOString(this.widgetValue);
145                         break;
146
147                     case 'bool':
148                         dojo.require('dijit.form.CheckBox');
149                         this.widget = new dijit.form.CheckBox(this.dijitArgs, this.parentNode);
150                         this.widgetValue = openils.Util.isTrue(this.widgetValue);
151                         break;
152
153                     case 'link':
154                         if(this._buildLinkSelector()) break;
155
156                     default:
157                         dojo.require('dijit.form.TextBox');
158                         this.widget = new dijit.form.TextBox(this.dijitArgs, this.parentNode);
159                 }
160             }
161
162             if(!this.async) this._widgetLoaded();
163             return this.widget;
164         },
165
166         _buildLinkSelector : function() {
167
168             /* verify we can and should grab the related class */
169             var linkClass = this.idlField['class'];
170             if(this.idlField.reltype != 'has_a')  return false;
171             if(!fieldmapper.IDL.fmclasses[linkClass].permacrud) return false;
172             if(!fieldmapper.IDL.fmclasses[linkClass].permacrud.retrieve) return false;
173
174             dojo.require('openils.PermaCrud');
175             dojo.require('dojo.data.ItemFileReadStore');
176             dojo.require('dijit.form.FilteringSelect');
177
178             var self = this;
179             var vfield;
180             var rclassIdl = fieldmapper.IDL.fmclasses[linkClass];
181
182             if(linkClass == 'pgt')
183                 return self._buildPermGrpSelector();
184
185             this.async = true;
186             this.widget = new dijit.form.FilteringSelect(this.dijitArgs, this.parentNode);
187
188             for(var f in rclassIdl.fields) {
189                 if(self.idlField.key == rclassIdl.fields[f].name) {
190                     vfield = rclassIdl.fields[f];
191                     break;
192                 }
193             }
194
195             this.widget.searchAttr = this.widget.labelAttr = vfield.selector || vfield.name;
196             this.widget.valueAttr = vfield.name;
197
198             new openils.PermaCrud().retrieveAll(linkClass, {   
199                 async : true,
200                 oncomplete : function(r) {
201                     var list = openils.Util.readResponse(r, false, true);
202                     if(list) {
203                         self.widget.store = 
204                             new dojo.data.ItemFileReadStore({data:fieldmapper[linkClass].toStoreData(list)});
205                     }
206                     self.widget.startup();
207                     self._widgetLoaded();
208                 }
209             });
210
211             return true;
212         },
213
214         /**
215          * For widgets that run asynchronously, provide a callback for finishing up
216          */
217         _widgetLoaded : function(value) {
218             if(this.readOnly) {
219                 this.baseWidgetValue(this.getDisplayString());
220             } else {
221                 this.baseWidgetValue(this.widgetValue);
222                 if(this.idlField.name == this.fmIDL.pkey && this.fmIDL.pkey_sequence)
223                     this.widget.attr('disabled', true); 
224             }
225             if(this.onload)
226                 this.onload(this.widget, self);
227         },
228
229         _buildOrgSelector : function() {
230             dojo.require('fieldmapper.OrgUtils');
231             dojo.require('openils.widget.FilteringTreeSelect');
232             this.widget = new openils.widget.FilteringTreeSelect(this.dijitArgs, this.parentNode);
233             this.widget.searchAttr = 'shortname';
234             this.widget.labelAttr = 'shortname';
235             this.widget.parentField = 'parent_ou';
236             
237             // if we have a limit perm, find the relevent orgs (async)
238             if(this.orgLimitPerms && this.orgLimitPerms.length > 0) {
239                 this.async = true;
240                 var user = new openils.User();
241                 var self = this;
242                 user.getPermOrgList(this.orgLimitPerms, 
243                     function(orgList) {
244                         self.widget.tree = orgList;
245                         self.widget.startup();
246                         self._widgetLoaded();
247                     }
248                 );
249
250             } else {
251                 this.widget.tree = fieldmapper.aou.globalOrgTree;
252                 this.widget.startup();
253             }
254         },
255
256         _buildPermGrpSelector : function() {
257             dojo.require('openils.widget.FilteringTreeSelect');
258             this.widget = new openils.widget.FilteringTreeSelect(this.dijitArgs, this.parentNode);
259             this.widget.searchAttr = 'name';
260
261             if(this.cache.permGrpTree) {
262                 this.widget.tree = this.cache.permGrpTree;
263                 this.widget.startup();
264                 return;
265             } 
266
267             var self = this;
268             this.async = true;
269             new openils.PermaCrud().retrieveAll('pgt', {
270                 async : true,
271                 oncomplete : function(r) {
272                     var list = openils.Util.readResponse(r, false, true);
273                     if(!list) return;
274                     var map = {};
275                     var root = null;
276                     for(var l in list)
277                         map[list[l].id()] = list[l];
278                     for(var l in list) {
279                         var node = list[l];
280                         var pnode = map[node.parent()];
281                         if(!pnode) {root = node; continue;}
282                         if(!pnode.children()) pnode.children([]);
283                         pnode.children().push(node);
284                     }
285                     self.widget.tree = self.cache.permGrpTree = root;
286                     self.widget.startup();
287                     self._widgetLoaded();
288                 }
289             });
290
291             return true;
292         }
293     });
294 }
295