]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/reports/oils_rpt_widget.js
Implemented template cloning
[working/Evergreen.git] / Open-ILS / web / reports / oils_rpt_widget.js
1 /* --------------------------------------------------------------------- 
2         Represents a set of values, an inputWidget collects data and a 
3         multi-select displays the data and allows the user to remove items
4         --------------------------------------------------------------------- */
5 function oilsRptSetWidget(args) {
6         this.node = args.node;
7         this.inputWidget = new args.inputWidget(args);
8         this.dest = elem('select',
9                 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
10 }
11
12 oilsRptSetWidget.prototype.draw = function() {
13
14         this.addButton = elem('input',{type:'submit',value:"Add"})
15         this.delButton = elem('input',{type:'submit',value:"Del"})
16
17         var obj = this;
18         this.addButton.onclick = function() {
19                 obj.addDisplayItems(obj.inputWidget.getDisplayValue());
20         }
21
22         this.delButton.onclick = function(){obj.removeSelected()};
23
24         removeChildren(this.node);
25         this.inputWidget.draw();
26         this.node.appendChild(elem('br'))
27         this.node.appendChild(this.addButton);
28         this.node.appendChild(this.delButton);
29         this.node.appendChild(elem('br'))
30         this.node.appendChild(this.dest);
31 }
32
33 oilsRptSetWidget.prototype.addDisplayItems = function(list) {
34         if( list.constructor != Array ) list = [list];
35         for(var i = 0; i < list.length; i++) {
36                 var item = list[i];
37
38                 /* no dupes */
39                 var exists = false;
40                 iterate(this.dest.options, 
41                         function(o){if(o.getAttribute('value') == item.value) {exists = true; return;}});
42                 if(exists) continue;
43
44                 _debug('Inserting SetWidget values ' + js2JSON(item));
45                 insertSelectorVal(this.dest, -1, item.label, this.objToStr(item.value));
46         }
47 }
48
49 oilsRptSetWidget.prototype.removeSelected = function() {
50         oilsDelSelectedItems(this.dest);
51 }
52
53 oilsRptSetWidget.prototype.getValue = function() {
54         var vals = [];
55         var obj = this;
56         iterate(this.dest, function(i){vals.push(obj.strToObj(i.getAttribute('value')))});
57         return vals;
58 }
59
60 oilsRptSetWidget.prototype.objToStr = function(obj) {
61         if( typeof obj == 'string' ) return obj;
62         return ':'+obj.transform+':'+obj.params[0];
63 }
64
65 oilsRptSetWidget.prototype.strToObj = function(str) {
66         if( str.match(/^:.*/) ) {
67                 var tform = str.replace(/^:(.*):.*/,'$1');
68                 var param = str.replace(/^:.*:(.*)/,'$1');
69                 return { transform : tform, params : [param] };
70         }
71         return str;
72 }
73
74
75 /* --------------------------------------------------------------------- 
76         represents a widget that has start and end values.  start and end
77         are gathered from start/end widgets
78         --------------------------------------------------------------------- */
79 function oilsRptBetweenWidget(args) {
80         this.node = args.node;
81         this.startWidget = new args.startWidget(args);
82         this.endWidget = new args.endWidget(args);
83 }
84 oilsRptBetweenWidget.prototype.draw = function() {
85         removeChildren(this.node);
86         this.startWidget.draw();
87         this.node.appendChild(elem('hr'));
88         this.node.appendChild(elem('div',
89                 {style:'text-align:center;width:100%;font-weight:bold'},' - And - '));
90         this.node.appendChild(elem('hr'));
91         this.endWidget.draw();
92 }
93 oilsRptBetweenWidget.prototype.getValue = function() {
94         return [
95                 this.startWidget.getValue(),
96                 this.endWidget.getValue()
97         ];
98 }
99
100
101
102
103 /* --------------------------------------------------------------------- 
104         ATOMIC WIDGETS
105         --------------------------------------------------------------------- */
106
107
108 /* --------------------------------------------------------------------- 
109         Atomic text input widget
110         --------------------------------------------------------------------- */
111 function oilsRptTextWidget(args) {
112         this.node = args.node;
113         this.dest = elem('input',{type:'text',size:12});
114         oilsRptMonitorWidget(this.dest);
115 }
116 oilsRptTextWidget.prototype.draw = function() {
117         this.node.appendChild(this.dest);
118 }
119
120 /* returns the "real" value for the widget */
121 oilsRptTextWidget.prototype.getValue = function() {
122         return this.dest.value;
123 }
124
125 /* returns the label and "real" value for the widget */
126 oilsRptTextWidget.prototype.getDisplayValue = function() {
127         return { label : this.getValue(), value : this.getValue() };
128 }
129
130
131
132 /* --------------------------------------------------------------------- 
133         Atomic bool input widget
134         --------------------------------------------------------------------- */
135 function oilsRptBoolWidget(args) {
136         this.node = args.node;
137         this.selector = elem('select');
138         insertSelectorVal(this.selector, -1,'True','t');
139         insertSelectorVal(this.selector, -1,'False','f');
140 }
141
142 oilsRptBoolWidget.prototype.draw = function() {
143         this.node.appendChild(this.selector);
144 }
145
146 /* returns the "real" value for the widget */
147 oilsRptBoolWidget.prototype.getValue = function() {
148         return getSelectorVal(this.selector);
149 }
150
151 /* returns the label and "real" value for the widget */
152 oilsRptBoolWidget.prototype.getDisplayValue = function() {
153         var val = getSelectorVal(this.selector);
154         var label = 'True';
155         if (val == 'f') labal = 'False';
156         return { label : label, value : val };
157 }
158
159
160 /* If you monitor a text widget with this function, it 
161         will style the input differently to indicate the
162         field needs data.  If a regex is provided, it will
163         style the field differently until the data matches 
164         the regex.  The style comes from OILS_RPT_INVALID_DATA. */
165 function oilsRptMonitorWidget(input, regex) {
166         addCSSClass(input, OILS_RPT_INVALID_DATA);
167         var func = function() {
168                 var val = input.value;
169                 if(!val) {
170                         addCSSClass(input, OILS_RPT_INVALID_DATA);
171                 } else {
172                         if( regex ) {
173                                 if( val && val.match(regex) ) 
174                                         removeCSSClass(input, OILS_RPT_INVALID_DATA);
175                                 else
176                                         addCSSClass(input, OILS_RPT_INVALID_DATA);
177                         } else {
178                                 removeCSSClass(input, OILS_RPT_INVALID_DATA);
179                         }
180                 }
181         }
182
183         input.onkeyup = func;
184         input.onchange = func;
185 }
186
187
188
189
190 /* --------------------------------------------------------------------- 
191         Atomic calendar widget
192         --------------------------------------------------------------------- */
193 function oilsRptCalWidget(args) {
194         this.node = args.node;
195         this.calFormat = args.calFormat;
196         this.input = elem('input',{type:'text',size:12});
197
198         oilsRptMonitorWidget(this.input, args.regex);
199
200         if( args.inputSize ) {
201                 this.input.setAttribute('size',args.inputSize);
202                 this.input.setAttribute('maxlength',args.inputSize);
203         }
204 }
205
206 oilsRptCalWidget.prototype.draw = function() {
207         this.button = DOM.generic_calendar_button.cloneNode(true);
208         this.button.id = oilsNextId();
209         this.input.id = oilsNextId();
210
211         this.node.appendChild(this.button);
212         this.node.appendChild(this.input);
213         unHideMe(this.button);
214
215         _debug('making calendar widget with format ' + this.calFormat);
216
217         Calendar.setup({
218                 inputField      : this.input.id,
219                 ifFormat                : this.calFormat,
220                 button          : this.button.id,
221                 align                   : "Tl", 
222                 singleClick     : true
223         });
224 }
225
226 oilsRptCalWidget.prototype.getValue = function() {
227         return this.input.value;
228 }
229
230 oilsRptCalWidget.prototype.getDisplayValue = function() {
231         return { label : this.getValue(), value : this.getValue() };
232 }
233
234
235 /* --------------------------------------------------------------------- 
236         Atomic org widget
237         --------------------------------------------------------------------- */
238 function oilsRptOrgSelector(args) {
239         this.node = args.node;
240         this.selector = elem('select',
241                 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
242 }
243
244 oilsRptOrgSelector.prototype.draw = function(org) {
245         if(!org) org = globalOrgTree;
246         var opt = insertSelectorVal( this.selector, -1, 
247                 org.shortname(), org.id(), null, findOrgDepth(org) );
248         if( org.id() == oilsRptCurrentOrg )
249                 opt.selected = true;
250         if( org.children() ) {
251                 for( var c = 0; c < org.children().length; c++ )
252                         this.draw(org.children()[c]);
253         }
254         this.node.appendChild(this.selector);
255 }
256
257 oilsRptOrgSelector.prototype.getValue = function() {
258         var vals = [];
259         iterate(this.selector, /* XXX this.selector.options?? */
260                 function(o){
261                         if( o.selected )
262                                 vals.push(o.getAttribute('value'))
263                 }
264         );
265         return vals;
266 }
267
268 oilsRptOrgSelector.prototype.getDisplayValue = function() {
269         var vals = [];
270         iterate(this.selector,
271                 function(o){
272                         if( o.selected )
273                                 vals.push({ label : o.innerHTML, value : o.getAttribute('value')});
274                 }
275         );
276         return vals;
277 }
278
279
280 /* --------------------------------------------------------------------- 
281         Atomic age widget
282         --------------------------------------------------------------------- */
283 function oilsRptAgeWidget(args) {
284         this.node = args.node;
285         this.count = elem('select');
286         this.type = elem('select');
287 }
288
289 oilsRptAgeWidget.prototype.draw = function() {
290
291         //insertSelectorVal(this.count, -1, ' -- Select One -- ', '');
292         for( var i = 1; i < 25; i++ )
293                 insertSelectorVal(this.count, -1, i, i);
294
295         //insertSelectorVal(this.type, -1, ' -- Select One -- ', '');
296         insertSelectorVal(this.type, -1, 'Day(s)', 'days');
297         insertSelectorVal(this.type, -1, 'Month(s)', 'months');
298         insertSelectorVal(this.type, -1, 'Year(s)', 'years');
299         this.node.appendChild(this.count);
300         this.node.appendChild(this.type);
301 }
302
303 oilsRptAgeWidget.prototype.getValue = function() {
304         var count = getSelectorVal(this.count);
305         var type = getSelectorVal(this.type);
306         return count+''+type;
307 }
308
309 oilsRptAgeWidget.prototype.getDisplayValue = function() {
310         var val = { value : this.getValue() };
311         var label = getSelectorVal(this.count) + ' ';
312         for( var i = 0; i < this.type.options.length; i++ ) {
313                 var opt = this.type.options[i];
314                 if( opt.selected )
315                         label += opt.innerHTML;
316         }
317         val.label = label;
318         return val;
319 }
320
321
322
323 /* --------------------------------------------------------------------- 
324         Atomic number picker
325         --------------------------------------------------------------------- */
326 function oilsRptNumberWidget(args) {
327         this.node = args.node;
328         this.size = args.size || 32;
329         this.start = args.start;
330         this.selector = elem('select');
331 }
332 oilsRptNumberWidget.prototype.draw = function() {
333         //insertSelectorVal(this.selector, -1, ' -- Select One -- ', '');
334         for( var i = this.start; i < (this.size + this.start); i++ )
335                 insertSelectorVal(this.selector, -1, i, i);
336         this.node.appendChild(this.selector);
337         var obj = this;
338 }
339
340 oilsRptNumberWidget.prototype.getValue = function() {
341         return getSelectorVal(this.selector);
342 }
343
344 oilsRptNumberWidget.prototype.getDisplayValue = function() {
345         return { label : this.getValue(), value : this.getValue() };
346 }
347
348
349 /* --------------------------------------------------------------------- 
350         Relative dates widget
351         --------------------------------------------------------------------- */
352 function oilsRptTruncPicker(args) {
353         this.node = args.node;
354         this.type = args.type;
355         this.realSpan = elem('span');
356         this.relSpan = elem('span');
357         hideMe(this.relSpan);
358         args.node = this.realSpan;
359         this.calWidget = new oilsRptCalWidget(args);
360         args.node = this.node;
361
362         this.selector = elem('select');
363         insertSelectorVal(this.selector,-1,'Real Date',1);
364         insertSelectorVal(this.selector,-1,'Relative Date',2);
365
366         this.numberPicker = 
367                 new oilsRptNumberWidget({node:this.relSpan,size:24,start:1});
368
369         this.label = 'Day(s)';
370         if(this.type == 'month') this.label = 'Month(s)';
371         if(this.type == 'quarter') this.label = 'Quarter(s)';
372         if(this.type == 'year') this.label = 'Year(s)';
373         if(this.type == 'date') this.label = 'Day(s)';
374 }
375
376 oilsRptTruncPicker.prototype.draw = function() {
377         this.node.appendChild(this.selector);
378         this.node.appendChild(this.realSpan);
379         this.node.appendChild(this.relSpan);
380         this.calWidget.draw();
381         this.numberPicker.draw();
382         this.relSpan.appendChild(text(this.label+' ago'));
383
384         var obj = this;
385         this.selector.onchange = function() {
386                 if( getSelectorVal(obj.selector) == 1 ) {
387                         unHideMe(obj.realSpan);
388                         hideMe(obj.relSpan);
389                 } else {
390                         unHideMe(obj.relSpan);
391                         hideMe(obj.realSpan);
392                 }
393         }
394 }
395
396 oilsRptTruncPicker.prototype.getValue = function() {
397         if( getSelectorVal(this.selector) == 2) {
398                 var val = this.numberPicker.getValue();
399                 var tform = 'relative_' + this.type;
400                 return { transform : tform, params : ['-'+val] };
401         }
402         return this.calWidget.getValue();
403 }
404
405 oilsRptTruncPicker.prototype.getDisplayValue = function() {
406         if( getSelectorVal(this.selector) == 2) {
407                 var num = this.numberPicker.getValue();
408                 return { label : num +' '+this.label+' ago', value : this.getValue() };
409         }
410         return this.calWidget.getDisplayValue();
411 }
412
413
414 /* --------------------------------------------------------------------- 
415         Atomic remote object picker
416         --------------------------------------------------------------------- */
417
418 function oilsRptRemoteWidget(args) {
419         this.node       = args.node;
420         this.class      = args.class;
421         this.field      = args.field;
422         this.column = args.column;
423         this.source = elem('select',
424                 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
425 }
426
427 oilsRptRemoteWidget.prototype.draw = function() {
428         var orgcol;
429         iterate(oilsIDL[this.class].fields,
430                 function(i) {
431                         if(i.type == 'link' && i.class == 'aou') 
432                                 orgcol = i.name;
433                 }
434         );
435
436         if(orgcol) _debug("found org column for remote widget: " + orgcol);
437
438         var orgs = [];
439         iterate(oilsRptMyOrgs,function(i){orgs.push(i.id());});
440         var req = new Request(OILS_RPT_MAGIC_FETCH, SESSION, {
441                 hint:this.class,
442                 org_column : orgcol,
443                 org : orgs
444         }); 
445
446         var obj = this;
447         this.node.appendChild(this.source);
448         req.callback(function(r){obj.render(r.getResultObject())});
449         req.send();
450 }
451
452 oilsRptRemoteWidget.prototype.render = function(objs) {
453         for( var i = 0; i < objs.length; i++ ) {
454                 var obj = objs[i];
455                 var label = obj[this.field.selector]();
456                 var value = obj[this.column]();
457                 _debug("inserted remote object "+label + ' : ' + value);
458                 insertSelectorVal(this.source, -1, label, value);
459         }
460 }
461
462 oilsRptRemoteWidget.prototype.getDisplayValue = function() {
463         var vals = [];
464         iterate(this.source,
465                 function(o){
466                         if( o.selected )
467                                 vals.push({ label : o.innerHTML, value : o.getAttribute('value')});
468                 }
469         );
470         return vals;
471 }
472
473 oilsRptRemoteWidget.prototype.getValue = function() {
474         var vals = [];
475         iterate(this.source,
476                 function(o){
477                         if( o.selected )
478                                 vals.push(o.getAttribute('value'))
479                 }
480         );
481         return vals;
482 }
483
484
485
486
487 /* --------------------------------------------------------------------- 
488         CUSTOM WIDGETS
489         --------------------------------------------------------------------- */
490
491 /* --------------------------------------------------------------------- 
492         custom my-orgs picker 
493         --------------------------------------------------------------------- */
494 function oilsRptMyOrgsWidget(node, orgid, maxorg) {
495         _debug('fetching my orgs with max org of ' + maxorg);
496         this.node = node;
497         this.orgid = orgid;
498         this.maxorg = maxorg || 1;
499         this.active = true;
500         if( maxorg < 1 ) {
501                 this.node.disabled = true;
502                 this.active = false;
503         }
504 }
505
506 oilsRptMyOrgsWidget.prototype.draw = function() {
507         if(!oilsRptMyOrgs) {
508                 var req = new Request(OILS_RPT_FETCH_ORG_FULL_PATH, this.orgid);
509                 var obj = this;
510                 req.callback(
511                         function(r) { obj.drawWidget(r.getResultObject()); }
512                 );
513                 req.send();
514         } else {
515                 this.drawWidget(oilsRptMyOrgs);
516         }
517 }
518
519 oilsRptMyOrgsWidget.prototype.drawWidget = function(orglist) {
520         var sel = this.node;
521         var started = false;
522         oilsRptMyOrgs = orglist;
523         for( var i = 0; i < orglist.length; i++ ) {
524                 var org = orglist[i];
525                 var opt = insertSelectorVal( this.node, -1, 
526                         org.name(), org.id(), null, findOrgDepth(org) );
527                 if( org.id() == this.orgid )
528                         opt.selected = true;
529                 if(!started) {
530                         if( org.id() == this.maxorg ) 
531                                 started = true;
532                         else opt.disabled = true;
533                 }
534         }
535 }
536
537 oilsRptMyOrgsWidget.prototype.getValue = function() {
538         return getSelectorVal(this.node);
539 }
540
541