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