]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/reports/oils_rpt_widget.js
changed relative date number picker from 24 to 90
[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         
251         /* sometimes we need these choices 
252         if( !isTrue(findOrgType(org.ou_type()).can_have_vols()) )
253                 opt.disabled = true;
254                 */
255
256         if( org.children() ) {
257                 for( var c = 0; c < org.children().length; c++ )
258                         this.draw(org.children()[c]);
259         }
260         this.node.appendChild(this.selector);
261 }
262
263 oilsRptOrgSelector.prototype.getValue = function() {
264         var vals = [];
265         iterate(this.selector, /* XXX this.selector.options?? */
266                 function(o){
267                         if( o.selected )
268                                 vals.push(o.getAttribute('value'))
269                 }
270         );
271         return vals;
272 }
273
274 oilsRptOrgSelector.prototype.getDisplayValue = function() {
275         var vals = [];
276         iterate(this.selector,
277                 function(o){
278                         if( o.selected )
279                                 vals.push({ label : o.innerHTML, value : o.getAttribute('value')});
280                 }
281         );
282         return vals;
283 }
284
285
286 /* --------------------------------------------------------------------- 
287         Atomic age widget
288         --------------------------------------------------------------------- */
289 function oilsRptAgeWidget(args) {
290         this.node = args.node;
291         this.count = elem('select');
292         this.type = elem('select');
293 }
294
295 oilsRptAgeWidget.prototype.draw = function() {
296
297         //insertSelectorVal(this.count, -1, ' -- Select One -- ', '');
298         for( var i = 1; i < 25; i++ )
299                 insertSelectorVal(this.count, -1, i, i);
300
301         //insertSelectorVal(this.type, -1, ' -- Select One -- ', '');
302         insertSelectorVal(this.type, -1, 'Day(s)', 'days');
303         insertSelectorVal(this.type, -1, 'Month(s)', 'months');
304         insertSelectorVal(this.type, -1, 'Year(s)', 'years');
305         this.node.appendChild(this.count);
306         this.node.appendChild(this.type);
307 }
308
309 oilsRptAgeWidget.prototype.getValue = function() {
310         var count = getSelectorVal(this.count);
311         var type = getSelectorVal(this.type);
312         return count+''+type;
313 }
314
315 oilsRptAgeWidget.prototype.getDisplayValue = function() {
316         var val = { value : this.getValue() };
317         var label = getSelectorVal(this.count) + ' ';
318         for( var i = 0; i < this.type.options.length; i++ ) {
319                 var opt = this.type.options[i];
320                 if( opt.selected )
321                         label += opt.innerHTML;
322         }
323         val.label = label;
324         return val;
325 }
326
327
328
329 /* --------------------------------------------------------------------- 
330         Atomic number picker
331         --------------------------------------------------------------------- */
332 function oilsRptNumberWidget(args) {
333         this.node = args.node;
334         this.size = args.size || 32;
335         this.start = args.start;
336         this.selector = elem('select');
337 }
338 oilsRptNumberWidget.prototype.draw = function() {
339         //insertSelectorVal(this.selector, -1, ' -- Select One -- ', '');
340         for( var i = this.start; i < (this.size + this.start); i++ )
341                 insertSelectorVal(this.selector, -1, i, i);
342         this.node.appendChild(this.selector);
343         var obj = this;
344 }
345
346 oilsRptNumberWidget.prototype.getValue = function() {
347         return getSelectorVal(this.selector);
348 }
349
350 oilsRptNumberWidget.prototype.getDisplayValue = function() {
351         return { label : this.getValue(), value : this.getValue() };
352 }
353
354
355 /* --------------------------------------------------------------------- 
356         Relative dates widget
357         --------------------------------------------------------------------- */
358 function oilsRptTruncPicker(args) {
359         this.node = args.node;
360         this.type = args.type;
361         this.realSpan = elem('span');
362         this.relSpan = elem('span');
363         hideMe(this.relSpan);
364         args.node = this.realSpan;
365         this.calWidget = new oilsRptCalWidget(args);
366         args.node = this.node;
367
368         this.selector = elem('select');
369         insertSelectorVal(this.selector,-1,'Real Date',1);
370         insertSelectorVal(this.selector,-1,'Relative Date',2);
371
372         this.numberPicker = 
373                 new oilsRptNumberWidget({node:this.relSpan,size:90,start:1});
374
375         this.label = 'Day(s)';
376         if(this.type == 'month') this.label = 'Month(s)';
377         if(this.type == 'quarter') this.label = 'Quarter(s)';
378         if(this.type == 'year') this.label = 'Year(s)';
379         if(this.type == 'date') this.label = 'Day(s)';
380 }
381
382 oilsRptTruncPicker.prototype.draw = function() {
383         this.node.appendChild(this.selector);
384         this.node.appendChild(this.realSpan);
385         this.node.appendChild(this.relSpan);
386         this.calWidget.draw();
387         this.numberPicker.draw();
388         this.relSpan.appendChild(text(this.label+' ago'));
389
390         var obj = this;
391         this.selector.onchange = function() {
392                 if( getSelectorVal(obj.selector) == 1 ) {
393                         unHideMe(obj.realSpan);
394                         hideMe(obj.relSpan);
395                 } else {
396                         unHideMe(obj.relSpan);
397                         hideMe(obj.realSpan);
398                 }
399         }
400 }
401
402 oilsRptTruncPicker.prototype.getValue = function() {
403         if( getSelectorVal(this.selector) == 2) {
404                 var val = this.numberPicker.getValue();
405                 var tform = 'relative_' + this.type;
406                 return { transform : tform, params : ['-'+val] };
407         }
408         return this.calWidget.getValue();
409 }
410
411 oilsRptTruncPicker.prototype.getDisplayValue = function() {
412         if( getSelectorVal(this.selector) == 2) {
413                 var num = this.numberPicker.getValue();
414                 return { label : num +' '+this.label+' ago', value : this.getValue() };
415         }
416         return this.calWidget.getDisplayValue();
417 }
418
419
420 /* --------------------------------------------------------------------- 
421         Atomic remote object picker
422         --------------------------------------------------------------------- */
423
424 function oilsRptRemoteWidget(args) {
425         this.node       = args.node;
426         this.class      = args.class;
427         this.field      = args.field;
428         this.column = args.column;
429         this.source = elem('select',
430                 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
431 }
432
433 oilsRptRemoteWidget.prototype.draw = function() {
434         var orgcol;
435         iterate(oilsIDL[this.class].fields,
436                 function(i) {
437                         if(i.type == 'link' && i.class == 'aou') 
438                                 orgcol = i.name;
439                 }
440         );
441
442         if(orgcol) _debug("found org column for remote widget: " + orgcol);
443
444         var orgs = [];
445         iterate(oilsRptMyOrgs,function(i){orgs.push(i.id());});
446         var req = new Request(OILS_RPT_MAGIC_FETCH, SESSION, {
447                 hint:this.class,
448                 org_column : orgcol,
449                 org : orgs
450         }); 
451
452         var obj = this;
453         this.node.appendChild(this.source);
454         req.callback(function(r){obj.render(r.getResultObject())});
455         req.send();
456 }
457
458 oilsRptRemoteWidget.prototype.render = function(objs) {
459         for( var i = 0; i < objs.length; i++ ) {
460                 var obj = objs[i];
461                 var label = obj[this.field.selector]();
462                 var value = obj[this.column]();
463                 _debug("inserted remote object "+label + ' : ' + value);
464                 insertSelectorVal(this.source, -1, label, value);
465         }
466 }
467
468 oilsRptRemoteWidget.prototype.getDisplayValue = function() {
469         var vals = [];
470         iterate(this.source,
471                 function(o){
472                         if( o.selected )
473                                 vals.push({ label : o.innerHTML, value : o.getAttribute('value')});
474                 }
475         );
476         return vals;
477 }
478
479 oilsRptRemoteWidget.prototype.getValue = function() {
480         var vals = [];
481         iterate(this.source,
482                 function(o){
483                         if( o.selected )
484                                 vals.push(o.getAttribute('value'))
485                 }
486         );
487         return vals;
488 }
489
490
491
492
493 /* --------------------------------------------------------------------- 
494         CUSTOM WIDGETS
495         --------------------------------------------------------------------- */
496
497 /* --------------------------------------------------------------------- 
498         custom my-orgs picker 
499         --------------------------------------------------------------------- */
500 function oilsRptMyOrgsWidget(node, orgid, maxorg) {
501         _debug('fetching my orgs with max org of ' + maxorg);
502         this.node = node;
503         this.orgid = orgid;
504         this.maxorg = maxorg || 1;
505         this.active = true;
506         if( maxorg < 1 ) {
507                 this.node.disabled = true;
508                 this.active = false;
509         }
510 }
511
512 oilsRptMyOrgsWidget.prototype.draw = function() {
513         if(!oilsRptMyOrgs) {
514                 var req = new Request(OILS_RPT_FETCH_ORG_FULL_PATH, this.orgid);
515                 var obj = this;
516                 req.callback(
517                         function(r) { obj.drawWidget(r.getResultObject()); }
518                 );
519                 req.send();
520         } else {
521                 this.drawWidget(oilsRptMyOrgs);
522         }
523 }
524
525 oilsRptMyOrgsWidget.prototype.drawWidget = function(orglist) {
526         var sel = this.node;
527         var started = false;
528         oilsRptMyOrgs = orglist;
529         for( var i = 0; i < orglist.length; i++ ) {
530                 var org = orglist[i];
531                 var opt = insertSelectorVal( this.node, -1, 
532                         org.name(), org.id(), null, findOrgDepth(org) );
533                 if( org.id() == this.orgid )
534                         opt.selected = true;
535                 if(!started) {
536                         if( org.id() == this.maxorg ) 
537                                 started = true;
538                         else opt.disabled = true;
539                 }
540         }
541 }
542
543 oilsRptMyOrgsWidget.prototype.getValue = function() {
544         return getSelectorVal(this.node);
545 }
546
547