]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/reports/oils_rpt_widget.js
added relative time handler for "date" transform
[Evergreen.git] / Open-ILS / web / reports / oils_rpt_widget.js
1 /*
2 oilsRptSetSubClass('oilsRptWidget', 'oilsRptObject');
3 oilsRptWidget.OILS_RPT_TRANSFORM_WIDGET = 0;
4 oilsRptWidget.OILS_RPT_OPERATION_WIDGET = 1;
5
6 function oilsRptWidget(args) {
7         this.initWidget(args);
8         this.dest = elem('input',{type:'text'});
9 }
10
11 oilsRptWidget.prototype.initWidget = function(args) {
12         if(!args) return;
13         this.init();
14         this.node       = args.node;
15         this.type       = args.type;
16         this.action = args.action;
17         this.column     = args.column;
18 }
19
20 oilsRptWidget.prototype.getValue = function() {
21         return this.dest.value ;
22 }
23
24 oilsRptWidget.prototype.draw = function() {
25         appendClear(this.node, this.dest);
26 }
27
28 oilsRptSetSubClass('oilsRptMultiInputWidget', 'oilsRptWidget');
29 function oilsRptMultiInputWidget(args) {
30         this.initInputWidget(args);
31 }
32
33 oilsRptMultiInputWidget.prototype.initInputWidget = function(args) {
34         if(!args) return;
35         this.initWidget(args);
36         this.count = (args.count) ? args.count : 2;
37         this.dest = [];
38         for( var i = 0; i < this.count; i++ )
39                 this.dest.push(elem('input',{type:'text',size:10}));
40 }
41
42 oilsRptMultiInputWidget.prototype.getValue = function() {
43         var vals = [];
44         for( var i = 0; i < this.dest.length; i++ )
45                 vals.push(this.dest[i].value);
46         return vals;
47 }
48
49 oilsRptMultiInputWidget.prototype.draw = function() {
50         removeChildren(this.node);
51         for( var i = 0; i < this.dest.length; i++ ) {
52                 if( this.label )
53                         this.node.appendChild(this.label[i]);
54                 this.node.appendChild(this.dest[i]);
55         }
56 }
57
58 oilsRptMultiInputWidget.prototype.setLabels = function(labels) {
59         this.labels = labels;   
60 }
61
62
63
64
65 oilsRptSetSubClass('oilsRptMultiWidget', 'oilsRptWidget');
66 function oilsRptMultiWidget(args) {
67         this.initMultiWidget(args);
68 }
69
70 oilsRptMultiWidget.prototype.initMultiWidget = function(args) {
71         if(!args) return;
72         this.initWidget(args);
73         this.dest = elem('select',
74                 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
75
76         var obj = this;
77
78         this.addButton = elem('input',{type:'submit',value:"Add"})
79         this.addButton.onclick = this.getSourceCollector();
80         this.delButton = elem('input',{type:'submit',value:"Del"})
81         this.delButton.onclick = function(){obj.removeSelected()};
82 }
83
84 oilsRptMultiWidget.prototype.getValue = function() {
85         var vals = [];
86         for( var i = 0; i < this.dest.options.length; i++ )
87                 vals.push(this.dest.options[i].value);
88         return vals;
89 }
90
91 oilsRptMultiWidget.prototype.removeSelected = function() {
92         oilsDelSelectedItems(this.dest);
93 }
94
95 oilsRptMultiWidget.prototype.addItem = function(name, val) {
96         for( var i = 0; i < this.dest.options.length; i++ ) {
97                 if( this.dest.options[i].value == val ) 
98                         return;
99         }
100         insertSelectorVal(this.dest, -1, name, val);
101 }
102
103 oilsRptMultiWidget.prototype.setSource = function(src) {
104         this.source = src;
105 }
106
107 oilsRptMultiWidget.prototype.drawMultiWidget = function() {
108         appendClear(this.node, this.source);
109         this.node.appendChild(elem('br'))
110         this.node.appendChild(this.addButton);
111         this.node.appendChild(this.delButton);
112         this.node.appendChild(elem('br'))
113         this.node.appendChild(this.dest);
114 }
115
116 oilsRptSetSubClass('oilsRptInputMultiWidget', 'oilsRptMultiWidget');
117 function oilsRptInputMultiWidget(args) {
118         this.initInputMultiWidget(args);
119 }
120 oilsRptInputMultiWidget.prototype.initInputMultiWidget = function(args) {
121         if(!args) return;
122         this.initMultiWidget(args);
123         this.setSource(elem('input',{type:'text'}));
124 }
125
126 oilsRptInputMultiWidget.prototype.draw = function() {
127         this.drawMultiWidget();
128 }
129
130 oilsRptInputMultiWidget.prototype.getSourceCollector = function() {
131         var obj = this;
132         return function() {
133                 obj.addItem(obj.source.value, obj.source.value);
134         }
135 }
136
137
138
139 oilsRptSetSubClass('oilsRptSelectorMultiWidget', 'oilsRptMultiWidget');
140 function oilsRptSelectorMultiWidget(args) {
141         this.initSelectorMultiWidget(args);
142 }
143 oilsRptSelectorMultiWidget.prototype.initSelectorMultiWidget = function(args) {
144         if(!args) return;
145         this.initMultiWidget(args);
146         this.setSource(
147                 elem('select',{multiple:'multiple', 'class':'oils_rpt_small_info_selector'}));
148 }
149
150 oilsRptSelectorMultiWidget.prototype.getSourceCollector = function() {
151         var obj = this;
152         return function() {
153                 for( var i = 0; i < obj.source.options.length; i++ ) {
154                         if( obj.source.options[i].selected )
155                                 obj.addItem(obj.source.options[i].innerHTML, 
156                                         obj.source.options[i].value);
157                 }
158         }
159 }
160 */
161
162 /* ----------------------------------------------------------- */
163
164 /*
165 oilsRptSetSubClass('oilsRptRemoteWidget', 'oilsRptSelectorMultiWidget');
166 function oilsRptRemoteWidget(args) {
167         this.initRemoteWidget(args);
168 }
169 oilsRptRemoteWidget.prototype.initRemoteWidget = function(args) {
170         if(!args) return;
171         this.initSelectorMultiWidget(args);
172         this.selector = args.selector;
173 }
174
175 oilsRptRemoteWidget.prototype.draw = function() {
176         this.fetch();
177         //this.draw();
178 }
179
180 oilsRptRemoteWidget.prototype.setFetch = function(func) {
181         this.fetch = func;
182 }
183 */
184
185
186
187
188 /* --------------------------------------------------------------------- */
189 /*
190 oilsRptSetSubClass('oilsRptOrgMultiSelect','oilsRptSelectorMultiWidget');
191 function oilsRptOrgMultiSelect(args) {
192         this.initSelectorMultiWidget(args);
193 }
194 oilsRptOrgMultiSelect.prototype.draw = function(org) {
195         if(!org) org = globalOrgTree;
196         var opt = insertSelectorVal( this.source, -1, 
197                 org.shortname(), org.id(), null, findOrgDepth(org) );
198         if( org.id() == oilsRptCurrentOrg )
199                 opt.selected = true;
200         if( org.children() ) {
201                 for( var c = 0; c < org.children().length; c++ )
202                         this.draw(org.children()[c]);
203         }
204         this.drawMultiWidget();
205 }
206 */
207
208
209
210 /* --------------------------------------------------------------------- */
211 /*
212 function oilsRptRelDatePicker(args) {
213         this.node = args.node;
214         this.relative = args.relative;
215         this.div = DOM.oils_rpt_relative_date_picker.cloneNode(true);
216 }
217
218 oilsRptRelDatePicker.prototype.draw = function() {
219         this.node.appendChild(this.div);
220         unHideMe(this.div);
221 }
222
223 oilsRptRelDatePicker.prototype.getValue = function() {
224         var str = 
225                 getSelectorVal($n(this.div, 'count')) + 
226                 getSelectorVal($n(this.div,'type'));
227         if( this.relative ) str = '-'+str;
228         return str;
229 }
230 */
231 /* --------------------------------------------------------------------- */
232
233
234
235
236
237
238
239
240 /* --------------------------------------------------------------------- */
241 /* --------------------------------------------------------------------- */
242
243
244
245
246 /* --------------------------------------------------------------------- 
247         Represents a set of value, an inputWidget collects data and a 
248         multi-select displays the data and allows the user to remove items
249         --------------------------------------------------------------------- */
250 function oilsRptSetWidget(args) {
251         this.node = args.node;
252         this.inputWidget = new args.inputWidget(args);
253         this.dest = elem('select',
254                 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
255 }
256
257 oilsRptSetWidget.prototype.draw = function() {
258
259         this.addButton = elem('input',{type:'submit',value:"Add"})
260         this.delButton = elem('input',{type:'submit',value:"Del"})
261
262         var obj = this;
263         this.addButton.onclick = function() {
264                 obj.addDisplayItems(obj.inputWidget.getDisplayValue());
265         }
266
267         this.delButton.onclick = function(){obj.removeSelected()};
268
269         removeChildren(this.node);
270         this.inputWidget.draw();
271         this.node.appendChild(elem('br'))
272         this.node.appendChild(this.addButton);
273         this.node.appendChild(this.delButton);
274         this.node.appendChild(elem('br'))
275         this.node.appendChild(this.dest);
276 }
277
278 oilsRptSetWidget.prototype.addDisplayItems = function(list) {
279         if( list.constructor != Array ) list = [list];
280         for(var i = 0; i < list.length; i++) {
281                 var item = list[i];
282
283                 /* no dupes */
284                 var exists = false;
285                 iterate(this.dest.options, 
286                         function(o){if(o.getAttribute('value') == item.value) {exists = true; return;}});
287                 if(exists) continue;
288
289                 _debug('Inserting SetWidget values ' + js2JSON(item));
290                 insertSelectorVal(this.dest, -1, item.label, this.objToStr(item.value));
291         }
292 }
293
294 oilsRptSetWidget.prototype.removeSelected = function() {
295         oilsDelSelectedItems(this.dest);
296 }
297
298 oilsRptSetWidget.prototype.getValue = function() {
299         var vals = [];
300         var obj = this;
301         iterate(this.dest, function(i){vals.push(obj.strToObj(i.getAttribute('value')))});
302         return vals;
303 }
304
305 oilsRptSetWidget.prototype.objToStr = function(obj) {
306         if( typeof obj == 'string' ) return obj;
307         return ':'+obj.transform+':'+obj.params[0];
308 }
309
310 oilsRptSetWidget.prototype.strToObj = function(str) {
311         if( str.match(/^:.*/) ) {
312                 var tform = str.replace(/^:(.*):.*/,'$1');
313                 var param = str.replace(/^:.*:(.*)/,'$1');
314                 return { transform : tform, params : [param] };
315         }
316         return str;
317 }
318
319
320 /* --------------------------------------------------------------------- 
321         represents a widget that has start and end values.  start and end
322         are gather from start/end widgets
323         --------------------------------------------------------------------- */
324 function oilsRptBetweenWidget(args) {
325         this.node = args.node;
326         this.startWidget = new args.startWidget(args);
327         this.endWidget = new args.endWidget(args);
328 }
329 oilsRptBetweenWidget.prototype.draw = function() {
330         removeChildren(this.node);
331         this.startWidget.draw();
332         this.node.appendChild(elem('hr'));
333         this.node.appendChild(elem('div',
334                 {style:'text-align:center;width:100%;font-weight:bold'},' - And - '));
335         this.node.appendChild(elem('hr'));
336         this.endWidget.draw();
337 }
338 oilsRptBetweenWidget.prototype.getValue = function() {
339         return [
340                 this.startWidget.getValue(),
341                 this.endWidget.getValue()
342         ];
343 }
344
345
346
347
348 /* --------------------------------------------------------------------- 
349         ATOMIC WIDGETS
350         --------------------------------------------------------------------- */
351
352
353 /* --------------------------------------------------------------------- 
354         Atomic text input widget
355         --------------------------------------------------------------------- */
356 function oilsRptTextWidget(args) {
357         this.node = args.node;
358         this.dest = elem('input',{type:'text',size:12});
359 }
360 oilsRptTextWidget.prototype.draw = function() {
361         this.node.appendChild(this.dest);
362 }
363
364 /* returns the "real" value for the widget */
365 oilsRptTextWidget.prototype.getValue = function() {
366         return this.dest.value;
367 }
368
369 /* returns the label and "real" value for the widget */
370 oilsRptTextWidget.prototype.getDisplayValue = function() {
371         return { label : this.getValue(), value : this.getValue() };
372 }
373
374
375
376 /* --------------------------------------------------------------------- 
377         Atomic calendar widget
378         --------------------------------------------------------------------- */
379 function oilsRptCalWidget(args) {
380         this.node = args.node;
381         this.calFormat = args.calFormat;
382         this.input = elem('input',{type:'text',size:12});
383
384         if( args.inputSize ) {
385                 this.input.setAttribute('size',args.inputSize);
386                 this.input.setAttribute('maxlength',args.inputSize);
387         }
388 }
389
390 oilsRptCalWidget.prototype.draw = function() {
391         this.button = DOM.generic_calendar_button.cloneNode(true);
392         this.button.id = oilsNextId();
393         this.input.id = oilsNextId();
394
395         this.node.appendChild(this.button);
396         this.node.appendChild(this.input);
397         unHideMe(this.button);
398
399         _debug('making calendar widget with format ' + this.calFormat);
400
401         Calendar.setup({
402                 inputField      : this.input.id,
403                 ifFormat                : this.calFormat,
404                 button          : this.button.id,
405                 align                   : "Tl", 
406                 singleClick     : true
407         });
408 }
409
410 oilsRptCalWidget.prototype.getValue = function() {
411         return this.input.value;
412 }
413
414 oilsRptCalWidget.prototype.getDisplayValue = function() {
415         return { label : this.getValue(), value : this.getValue() };
416 }
417
418
419 /* --------------------------------------------------------------------- 
420         Atomic org widget
421         --------------------------------------------------------------------- */
422 function oilsRptOrgSelector(args) {
423         this.node = args.node;
424         this.selector = elem('select',
425                 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
426 }
427
428 oilsRptOrgSelector.prototype.draw = function(org) {
429         if(!org) org = globalOrgTree;
430         var opt = insertSelectorVal( this.selector, -1, 
431                 org.shortname(), org.id(), null, findOrgDepth(org) );
432         if( org.id() == oilsRptCurrentOrg )
433                 opt.selected = true;
434         if( org.children() ) {
435                 for( var c = 0; c < org.children().length; c++ )
436                         this.draw(org.children()[c]);
437         }
438         this.node.appendChild(this.selector);
439 }
440
441 oilsRptOrgSelector.prototype.getValue = function() {
442         var vals = [];
443         iterate(this.selector,
444                 function(o){
445                         if( o.selected )
446                                 vals.push(o.getAttribute('value'))
447                 }
448         );
449         return vals;
450 }
451
452 oilsRptOrgSelector.prototype.getDisplayValue = function() {
453         var vals = [];
454         iterate(this.selector,
455                 function(o){
456                         if( o.selected )
457                                 vals.push({ label : o.innerHTML, value : o.getAttribute('value')});
458                 }
459         );
460         return vals;
461 }
462
463
464 /* --------------------------------------------------------------------- 
465         Atomic age widget
466         --------------------------------------------------------------------- */
467 function oilsRptAgeWidget(args) {
468         this.node = args.node;
469         this.count = elem('select');
470         this.type = elem('select');
471 }
472
473 oilsRptAgeWidget.prototype.draw = function() {
474         for( var i = 1; i < 25; i++ )
475                 insertSelectorVal(this.count, -1, i, i);
476         insertSelectorVal(this.type, -1, 'Day(s)', 'days');
477         insertSelectorVal(this.type, -1, 'Month(s)', 'months');
478         insertSelectorVal(this.type, -1, 'Year(s)', 'years');
479         this.node.appendChild(this.count);
480         this.node.appendChild(this.type);
481 }
482
483 oilsRptAgeWidget.prototype.getValue = function() {
484         var count = getSelectorVal(this.count);
485         var type = getSelectorVal(this.type);
486         return count+''+type;
487 }
488
489 oilsRptAgeWidget.prototype.getDisplayValue = function() {
490         var val = { value : this.getValue() };
491         var label = getSelectorVal(this.count) + ' ';
492         for( var i = 0; i < this.type.options.length; i++ ) {
493                 var opt = this.type.options[i];
494                 if( opt.selected )
495                         label += opt.innerHTML;
496         }
497         val.label = label;
498         return val;
499 }
500
501
502
503 /* --------------------------------------------------------------------- 
504         Atomic number picker
505         --------------------------------------------------------------------- */
506 function oilsRptNumberWidget(args) {
507         this.node = args.node;
508         this.size = args.size || 24;
509         this.start = args.start;
510         /*
511         var len = new String(this.size).length;
512         _debug('length = ' + len);
513         this.input = elem('input',{type:'text',size: len});
514         */
515         this.selector = elem('select');
516 }
517 oilsRptNumberWidget.prototype.draw = function() {
518         for( var i = this.start; i < (this.size + this.start); i++ )
519                 insertSelectorVal(this.selector, -1, i, i);
520         this.node.appendChild(this.selector);
521         //this.node.appendChild(this.input);
522         var obj = this;
523         /*
524         this.selector.onchange = function() {
525                 obj.input.value = getSelectorVal(obj.selector);
526         }
527         this.input.value = getSelectorVal(this.selector);
528         */
529 }
530
531 oilsRptNumberWidget.prototype.getValue = function() {
532         //return this.input.value;
533         return getSelectorVal(this.selector);
534 }
535
536 oilsRptNumberWidget.prototype.getDisplayValue = function() {
537         return { label : this.getValue(), value : this.getValue() };
538 }
539
540
541 /* --------------------------------------------------------------------- 
542         Relative dates widget
543         --------------------------------------------------------------------- */
544 function oilsRptTruncPicker(args) {
545         this.node = args.node;
546         this.type = args.type;
547         this.realSpan = elem('span');
548         this.relSpan = elem('span');
549         hideMe(this.relSpan);
550         args.node = this.realSpan;
551         this.calWidget = new oilsRptCalWidget(args);
552         args.node = this.node;
553
554         this.selector = elem('select');
555         insertSelectorVal(this.selector,-1,'Real Date',1);
556         insertSelectorVal(this.selector,-1,'Relative Date',2);
557
558         this.numberPicker = 
559                 new oilsRptNumberWidget({node:this.relSpan,size:24,start:1});
560
561         this.label = 'Day(s)';
562         if(this.type == 'month') this.label = 'Month(s)';
563         if(this.type == 'quarter') this.label = 'Quarter(s)';
564         if(this.type == 'year') this.label = 'Year(s)';
565         if(this.type == 'date') this.label = 'Day(s)';
566 }
567
568 oilsRptTruncPicker.prototype.draw = function() {
569         this.node.appendChild(this.selector);
570         this.node.appendChild(this.realSpan);
571         this.node.appendChild(this.relSpan);
572         this.calWidget.draw();
573         this.numberPicker.draw();
574         this.relSpan.appendChild(text(this.label+' ago'));
575
576         var obj = this;
577         this.selector.onchange = function() {
578                 if( getSelectorVal(obj.selector) == 1 ) {
579                         unHideMe(obj.realSpan);
580                         hideMe(obj.relSpan);
581                 } else {
582                         unHideMe(obj.relSpan);
583                         hideMe(obj.realSpan);
584                 }
585         }
586 }
587
588 oilsRptTruncPicker.prototype.getValue = function() {
589         if( getSelectorVal(this.selector) == 2) {
590                 var val = this.numberPicker.getValue();
591                 var tform = 'relative_' + this.type;
592                 return { transform : tform, params : ['-'+val] };
593         }
594         return this.calWidget.getValue();
595 }
596
597 oilsRptTruncPicker.prototype.getDisplayValue = function() {
598         if( getSelectorVal(this.selector) == 2) {
599                 var num = this.numberPicker.getValue();
600                 return { label : num +' '+this.label+' ago', value : this.getValue() };
601         }
602         return this.calWidget.getDisplayValue();
603 }
604
605
606 /* --------------------------------------------------------------------- 
607         Atomic remote object picker
608         --------------------------------------------------------------------- */
609
610 function oilsRptRemoteWidget(args) {
611         this.node       = args.node;
612         this.class      = args.class;
613         this.field      = args.field;
614         this.column = args.column;
615         this.source = elem('select',
616                 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
617 }
618
619 oilsRptRemoteWidget.prototype.draw = function() {
620         var orgcol;
621         iterate(oilsIDL[this.class].fields,
622                 function(i) {
623                         if(i.type == 'link' && i.class == 'aou') 
624                                 orgcol = i.name;
625                 }
626         );
627
628         if(orgcol) _debug("found org column for remote widget: " + orgcol);
629
630         var orgs = [];
631         iterate(oilsRptMyOrgs,function(i){orgs.push(i.id());});
632         var req = new Request(OILS_RPT_MAGIC_FETCH, SESSION, {
633                 hint:this.class,
634                 org_column : orgcol,
635                 org : orgs
636         }); 
637
638         var obj = this;
639         this.node.appendChild(this.source);
640         req.callback(function(r){obj.render(r.getResultObject())});
641         req.send();
642 }
643
644 oilsRptRemoteWidget.prototype.render = function(objs) {
645         for( var i = 0; i < objs.length; i++ ) {
646                 var obj = objs[i];
647                 var label = obj[this.field.selector]();
648                 var value = obj[this.column]();
649                 _debug("inserted remote object "+label + ' : ' + value);
650                 insertSelectorVal(this.source, -1, label, value);
651         }
652 }
653
654 oilsRptRemoteWidget.prototype.getDisplayValue = function() {
655         var vals = [];
656         iterate(this.source,
657                 function(o){
658                         if( o.selected )
659                                 vals.push({ label : o.innerHTML, value : o.getAttribute('value')});
660                 }
661         );
662         return vals;
663 }
664
665 oilsRptRemoteWidget.prototype.getValue = function() {
666         var vals = [];
667         iterate(this.source,
668                 function(o){
669                         if( o.selected )
670                                 vals.push(o.getAttribute('value'))
671                 }
672         );
673         return vals;
674 }
675
676
677
678
679 /* --------------------------------------------------------------------- 
680         CUSTOM WIDGETS
681         --------------------------------------------------------------------- */
682
683 /* --------------------------------------------------------------------- 
684         custom my-orgs picker 
685         --------------------------------------------------------------------- */
686 function oilsRptMyOrgsWidget(node, orgid, maxorg) {
687         _debug('fetching my orgs with max org of ' + maxorg);
688         this.node = node;
689         this.orgid = orgid;
690         this.maxorg = maxorg || 1;
691         this.active = true;
692         if( maxorg < 1 ) {
693                 this.node.disabled = true;
694                 this.active = false;
695         }
696 }
697
698 oilsRptMyOrgsWidget.prototype.draw = function() {
699         if(!oilsRptMyOrgs) {
700                 var req = new Request(OILS_RPT_FETCH_ORG_FULL_PATH, this.orgid);
701                 var obj = this;
702                 req.callback(
703                         function(r) { obj.drawWidget(r.getResultObject()); }
704                 );
705                 req.send();
706         } else {
707                 this.drawWidget(oilsRptMyOrgs);
708         }
709 }
710
711 oilsRptMyOrgsWidget.prototype.drawWidget = function(orglist) {
712         var sel = this.node;
713         var started = false;
714         oilsRptMyOrgs = orglist;
715         for( var i = 0; i < orglist.length; i++ ) {
716                 var org = orglist[i];
717                 var opt = insertSelectorVal( this.node, -1, 
718                         org.name(), org.id(), null, findOrgDepth(org) );
719                 if( org.id() == this.orgid )
720                         opt.selected = true;
721                 if(!started) {
722                         if( org.id() == this.maxorg ) 
723                                 started = true;
724                         else opt.disabled = true;
725                 }
726         }
727 }
728
729 oilsRptMyOrgsWidget.prototype.getValue = function() {
730         return getSelectorVal(this.node);
731 }
732
733