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');
7 dojo.declare('openils.widget.AutoFieldWidget', null, {
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
25 constructor : function(args) {
29 // find the field description in the IDL if not provided
31 this.fmClass = this.fmObject.classname;
32 this.fmIDL = fieldmapper.IDL.fmclasses[this.fmClass];
35 this.fmIDL = fieldmapper.IDL.fmclasses[this.fmClass];
36 var fields = this.fmIDL.fields;
38 if(fields[f].name == this.fmField)
39 this.idlField = fields[f];
43 throw new Error("AutoFieldWidget could not determine which field to render. We need more information.");
47 * Turn the widget-stored value into a value oils understands
49 getFormattedValue : function() {
50 var value = this.baseWidgetValue();
51 switch(this.idlField.datatype) {
53 return (value) ? 't' : 'f'
55 return dojo.date.stamp.toISOString(value);
58 if(isNaN(value)) value = 0;
60 return (value === '') ? null : value;
64 baseWidgetValue : function(value) {
65 var attr = (this.readOnly) ? 'content' : 'value';
66 if(arguments.length) this.widget.attr(attr, value);
67 return this.widget.attr(attr);
71 * Turn the widget-stored value into something visually suitable
73 getDisplayString : function() {
74 var value = this.widgetValue;
75 switch(this.idlField.datatype) {
77 return (value) ? 'True' : 'False'; // XXX i18n!
79 dojo.require('dojo.date.locale');
80 dojo.require('dojo.date.stamp');
81 var date = dojo.date.stamp.fromISOString(value);
82 return dojo.date.locale.format(date, {formatLength:'short'});
84 if(value === null || value === undefined) return '';
85 return fieldmapper.aou.findOrgUnit(value).shortname();
88 if(isNaN(value)) value = 0;
90 if(value === undefined || value === null)
96 build : function(onload) {
99 // core widget provided for us, attach and move on
100 if(this.parentNode) // may already be in the "right" place
101 this.parentNode.appendChild(this.widget.domNode);
105 this.onload = onload;
106 if(this.widgetValue == null)
107 this.widgetValue = (this.fmObject) ? this.fmObject[this.idlField.name]() : null;
110 dojo.require('dijit.layout.ContentPane');
111 this.widget = new dijit.layout.ContentPane(this.dijitArgs, this.parentNode);
113 } else if(this.widgetClass) {
114 dojo.require(this.widgetClass);
115 eval('this.widget = new ' + this.widgetClass + '(this.dijitArgs, this.parentNode);');
119 switch(this.idlField.datatype) {
122 dojo.require('dijit.form.TextBox');
123 this.widget = new dijit.form.TextBox(this.dijitArgs, this.parentNode);
124 this.widget.attr('disabled', true); // never allow editing of IDs
128 this._buildOrgSelector();
132 dojo.require('dijit.form.CurrencyTextBox');
133 this.widget = new dijit.form.CurrencyTextBox(this.dijitArgs, this.parentNode);
137 dojo.require('dijit.form.NumberTextBox');
138 this.dijitArgs = dojo.mixin(this.dijitArgs || {}, {constraints:{places:0}});
139 this.widget = new dijit.form.NumberTextBox(this.dijitArgs, this.parentNode);
143 dojo.require('dijit.form.NumberTextBox');
144 this.widget = new dijit.form.NumberTextBox(this.dijitArgs, this.parentNode);
148 dojo.require('dijit.form.DateTextBox');
149 dojo.require('dojo.date.stamp');
150 this.widget = new dijit.form.DateTextBox(this.dijitArgs, this.parentNode);
151 if(this.widgetValue != null)
152 this.widgetValue = dojo.date.stamp.fromISOString(this.widgetValue);
156 dojo.require('dijit.form.CheckBox');
157 this.widget = new dijit.form.CheckBox(this.dijitArgs, this.parentNode);
158 this.widgetValue = openils.Util.isTrue(this.widgetValue);
162 if(this._buildLinkSelector()) break;
165 dojo.require('dijit.form.TextBox');
166 this.widget = new dijit.form.TextBox(this.dijitArgs, this.parentNode);
170 if(!this.async) this._widgetLoaded();
174 _buildLinkSelector : function() {
176 /* verify we can and should grab the related class */
177 var linkClass = this.idlField['class'];
178 if(this.idlField.reltype != 'has_a') return false;
179 if(!fieldmapper.IDL.fmclasses[linkClass].permacrud) return false;
180 if(!fieldmapper.IDL.fmclasses[linkClass].permacrud.retrieve) return false;
182 dojo.require('openils.PermaCrud');
183 dojo.require('dojo.data.ItemFileReadStore');
184 dojo.require('dijit.form.FilteringSelect');
188 var rclassIdl = fieldmapper.IDL.fmclasses[linkClass];
190 if(linkClass == 'pgt')
191 return self._buildPermGrpSelector();
194 this.widget = new dijit.form.FilteringSelect(this.dijitArgs, this.parentNode);
196 for(var f in rclassIdl.fields) {
197 if(self.idlField.key == rclassIdl.fields[f].name) {
198 vfield = rclassIdl.fields[f];
204 throw new Error("'" + linkClass + "' has no '" + self.idlField.key + "' field!");
206 this.widget.searchAttr = this.widget.labelAttr = vfield.selector || vfield.name;
207 this.widget.valueAttr = vfield.name;
209 var oncomplete = function(list) {
212 new dojo.data.ItemFileReadStore({data:fieldmapper[linkClass].toStoreData(list)});
213 self.cache[linkClass] = list;
215 self.widget.startup();
216 self._widgetLoaded();
219 if(this.cache[linkClass]) {
220 oncomplete(this.cache[linkClass]);
223 new openils.PermaCrud().retrieveAll(linkClass, {
225 oncomplete : function(r) {
226 var list = openils.Util.readResponse(r, false, true);
236 * For widgets that run asynchronously, provide a callback for finishing up
238 _widgetLoaded : function(value) {
240 this.baseWidgetValue(this.getDisplayString());
242 this.baseWidgetValue(this.widgetValue);
243 if(this.idlField.name == this.fmIDL.pkey && this.fmIDL.pkey_sequence)
244 this.widget.attr('disabled', true);
247 this.onload(this.widget, self);
250 _buildOrgSelector : function() {
251 dojo.require('fieldmapper.OrgUtils');
252 dojo.require('openils.widget.FilteringTreeSelect');
253 this.widget = new openils.widget.FilteringTreeSelect(this.dijitArgs, this.parentNode);
254 this.widget.searchAttr = 'shortname';
255 this.widget.labelAttr = 'shortname';
256 this.widget.parentField = 'parent_ou';
257 var user = new openils.User();
258 if(this.widgetValue == null)
259 this.widgetValue = user.user.ws_ou();
261 // if we have a limit perm, find the relevent orgs (async)
262 if(this.orgLimitPerms && this.orgLimitPerms.length > 0) {
265 user.getPermOrgList(this.orgLimitPerms,
267 self.widget.tree = orgList;
268 self.widget.startup();
269 self._widgetLoaded();
274 this.widget.tree = fieldmapper.aou.globalOrgTree;
275 this.widget.startup();
279 _buildPermGrpSelector : function() {
280 dojo.require('openils.widget.FilteringTreeSelect');
281 this.widget = new openils.widget.FilteringTreeSelect(this.dijitArgs, this.parentNode);
282 this.widget.searchAttr = 'name';
284 if(this.cache.permGrpTree) {
285 this.widget.tree = this.cache.permGrpTree;
286 this.widget.startup();
292 new openils.PermaCrud().retrieveAll('pgt', {
294 oncomplete : function(r) {
295 var list = openils.Util.readResponse(r, false, true);
300 map[list[l].id()] = list[l];
303 var pnode = map[node.parent()];
304 if(!pnode) {root = node; continue;}
305 if(!pnode.children()) pnode.children([]);
306 pnode.children().push(node);
308 self.widget.tree = self.cache.permGrpTree = root;
309 self.widget.startup();
310 self._widgetLoaded();