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) {
7 this.seedValue = args.value;
8 this.inputWidget = new args.inputWidget(args);
9 this.readonly = Boolean(args.readonly);
10 this.asyncInput = args.async;
11 this.dest = elem('select',
12 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
13 this.dest.disabled = this.readonly;
16 oilsRptSetWidget.prototype.draw = function() {
18 this.addButton = elem('input',{type:'submit',value:"Add"})
19 this.delButton = elem('input',{type:'submit',value:"Del"})
20 this.addButton.disabled = this.readonly;
21 this.delButton.disabled = this.readonly;
24 this.addButton.onclick = function() {
25 obj.addDisplayItems(obj.inputWidget.getDisplayValue());
28 this.delButton.onclick = function(){obj.removeSelected()};
30 removeChildren(this.node);
33 var post_draw = function() {
34 // propagate the values from the input widget into the our display.
35 if (this_.inputWidget.seedValue)
36 this_.addButton.onclick();
39 this.inputWidget.draw(null, post_draw);
40 this.node.appendChild(elem('br'))
41 this.node.appendChild(this.addButton);
42 this.node.appendChild(this.delButton);
43 this.node.appendChild(elem('br'))
44 this.node.appendChild(this.dest);
46 if (!this.asyncInput) post_draw();
50 oilsRptSetWidget.prototype.addDisplayItems = function(list) {
51 if( list.constructor != Array ) list = [list];
52 for(var i = 0; i < list.length; i++) {
57 iterate(this.dest.options,
58 function(o){if(o.getAttribute('value') == item.value) {exists = true; return;}});
61 _debug('Inserting SetWidget values ' + js2JSON(item));
62 insertSelectorVal(this.dest, -1, item.label, this.objToStr(item.value));
66 oilsRptSetWidget.prototype.removeSelected = function() {
67 oilsDelSelectedItems(this.dest);
70 oilsRptSetWidget.prototype.getValue = function() {
73 iterate(this.dest, function(i){vals.push(obj.strToObj(i.getAttribute('value')))});
77 oilsRptSetWidget.prototype.objToStr = function(obj) {
78 if( typeof obj == 'string' ) return obj;
79 //return ':'+obj.transform+':'+obj.params[0];
80 var str = ':'+obj.transform;
81 for( var i = 0; i < obj.params.length; i++ )
82 str += ':' + obj.params[i];
83 _debug("objToStr(): built string " + str);
88 oilsRptSetWidget.prototype.strToObj = function(str) {
89 if( str.match(/^:.*/) ) {
90 var parts = str.split(/:/);
91 _debug("strToObj(): " + str + ' : ' + parts);
93 var tform = parts.shift();
94 //var tform = str.replace(/^:(.*):.*/,'$1');
95 //var param = str.replace(/^:.*:(.*)/,'$1');
96 return { transform : tform, params : parts };
102 /* ---------------------------------------------------------------------
103 represents a widget that has start and end values. start and end
104 are gathered from start/end widgets
105 --------------------------------------------------------------------- */
106 function oilsRptBetweenWidget(args) {
107 this.node = args.node;
108 var seedValue = args.value;
109 if (seedValue) args.value = seedValue[0];
110 this.startWidget = new args.startWidget(args);
111 if (seedValue) args.value = seedValue[1];
112 this.endWidget = new args.endWidget(args);
114 oilsRptBetweenWidget.prototype.draw = function() {
115 removeChildren(this.node);
116 this.startWidget.draw();
117 this.node.appendChild(elem('hr'));
118 this.node.appendChild(elem('div',
119 {style:'text-align:center;width:100%;font-weight:bold'},' - And - '));
120 this.node.appendChild(elem('hr'));
121 this.endWidget.draw();
123 oilsRptBetweenWidget.prototype.getValue = function() {
125 this.startWidget.getValue(),
126 this.endWidget.getValue()
133 /* ---------------------------------------------------------------------
135 --------------------------------------------------------------------- */
138 /* ---------------------------------------------------------------------
139 Atomic text input widget
140 --------------------------------------------------------------------- */
141 function oilsRptTextWidget(args) {
142 this.node = args.node;
143 this.seedValue = args.value;
144 this.dest = elem('input',{type:'text',size:12});
145 this.dest.disabled = Boolean(args.readonly);
146 oilsRptMonitorWidget(this.dest);
148 oilsRptTextWidget.prototype.draw = function() {
149 this.node.appendChild(this.dest);
150 if (this.seedValue) {
151 this.dest.value = this.seedValue;
152 this.dest.onchange(); // validation
156 /* returns the "real" value for the widget */
157 oilsRptTextWidget.prototype.getValue = function() {
158 return this.dest.value;
161 /* returns the label and "real" value for the widget */
162 oilsRptTextWidget.prototype.getDisplayValue = function() {
163 return { label : this.getValue(), value : this.getValue() };
168 /* ---------------------------------------------------------------------
169 Atomic bool input widget
170 --------------------------------------------------------------------- */
171 function oilsRptBoolWidget(args) {
172 this.node = args.node;
173 this.seedValue = args.value;
174 this.selector = elem('select');
175 insertSelectorVal(this.selector, -1,'True','t');
176 insertSelectorVal(this.selector, -1,'False','f');
177 this.selector.disabled = Boolean(args.readonly);
180 oilsRptBoolWidget.prototype.draw = function() {
181 this.node.appendChild(this.selector);
183 setSelector(this.selector, this.seedValue);
186 /* returns the "real" value for the widget */
187 oilsRptBoolWidget.prototype.getValue = function() {
188 return getSelectorVal(this.selector);
191 /* returns the label and "real" value for the widget */
192 oilsRptBoolWidget.prototype.getDisplayValue = function() {
193 var val = getSelectorVal(this.selector);
195 if (val == 'f') labal = 'False';
196 return { label : label, value : val };
200 /* If you monitor a text widget with this function, it
201 will style the input differently to indicate the
202 field needs data. If a regex is provided, it will
203 style the field differently until the data matches
204 the regex. The style comes from OILS_RPT_INVALID_DATA. */
205 function oilsRptMonitorWidget(input, regex) {
206 addCSSClass(input, OILS_RPT_INVALID_DATA);
207 var func = function() {
208 var val = input.value;
210 addCSSClass(input, OILS_RPT_INVALID_DATA);
213 if( val && val.match(regex) )
214 removeCSSClass(input, OILS_RPT_INVALID_DATA);
216 addCSSClass(input, OILS_RPT_INVALID_DATA);
218 removeCSSClass(input, OILS_RPT_INVALID_DATA);
223 input.onkeyup = func;
224 input.onchange = func;
230 /* ---------------------------------------------------------------------
231 Atomic calendar widget
232 --------------------------------------------------------------------- */
233 function oilsRptCalWidget(args) {
234 this.node = args.node;
235 this.calFormat = args.calFormat;
236 this.input = elem('input',{type:'text',size:12});
237 this.seedValue = args.value;
238 this.input.disabled = Boolean(args.readonly);
240 oilsRptMonitorWidget(this.input, args.regex);
242 if( args.inputSize ) {
243 this.input.setAttribute('size',args.inputSize);
244 this.input.setAttribute('maxlength',args.inputSize);
248 oilsRptCalWidget.prototype.draw = function() {
249 this.button = DOM.generic_calendar_button.cloneNode(true);
250 this.button.id = oilsNextId();
251 this.input.id = oilsNextId();
253 this.node.appendChild(this.button);
254 this.node.appendChild(this.input);
255 unHideMe(this.button);
257 _debug('making calendar widget with format ' + this.calFormat);
260 inputField : this.input.id,
261 ifFormat : this.calFormat,
262 button : this.button.id,
267 if (this.seedValue) {
268 this.input.value = this.seedValue;
269 this.input.onchange(); // validation
273 oilsRptCalWidget.prototype.getValue = function() {
274 return this.input.value;
277 oilsRptCalWidget.prototype.getDisplayValue = function() {
278 return { label : this.getValue(), value : this.getValue() };
282 /* ---------------------------------------------------------------------
284 --------------------------------------------------------------------- */
285 function oilsRptOrgSelector(args) {
286 this.node = args.node;
287 this.seedValue = args.value;
288 this.selector = elem('select',
289 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
290 this.selector.disabled = Boolean(args.readonly);
293 oilsRptOrgSelector.prototype.draw = function(org) {
294 if(!org) org = globalOrgTree;
295 var opt = insertSelectorVal( this.selector, -1,
296 org.shortname(), org.id(), null, findOrgDepth(org) );
297 if( org.id() == oilsRptCurrentOrg && !this.seedValue)
300 /* sometimes we need these choices
301 if( !isTrue(findOrgType(org.ou_type()).can_have_vols()) )
305 if( org.children() ) {
306 for( var c = 0; c < org.children().length; c++ )
307 this.draw(org.children()[c]);
309 this.node.appendChild(this.selector);
311 if (this.seedValue) {
312 if (dojo.isArray(this.seedValue)) {
313 for (var i = 0; i < this.selector.options.length; i++) {
314 var opt = this.selector.options[i];
315 if (this.seedValue.indexOf(opt.value) > -1)
319 setSelector(this.selector, this.seedValue);
324 oilsRptOrgSelector.prototype.getValue = function() {
326 iterate(this.selector, /* XXX this.selector.options?? */
329 vals.push(o.getAttribute('value'))
335 oilsRptOrgSelector.prototype.getDisplayValue = function() {
337 iterate(this.selector,
340 vals.push({ label : o.innerHTML, value : o.getAttribute('value')});
347 /* ---------------------------------------------------------------------
349 --------------------------------------------------------------------- */
350 function oilsRptAgeWidget(args) {
351 this.node = args.node;
352 this.seedValue = args.value;
353 this.count = elem('select');
354 this.type = elem('select');
355 this.count.disabled = Boolean(args.readonly);
356 this.type.disabled = Boolean(args.readonly);
359 oilsRptAgeWidget.prototype.draw = function() {
361 //insertSelectorVal(this.count, -1, ' -- Select One -- ', '');
362 for( var i = 1; i < 25; i++ )
363 insertSelectorVal(this.count, -1, i, i);
365 //insertSelectorVal(this.type, -1, ' -- Select One -- ', '');
366 insertSelectorVal(this.type, -1, rpt_strings.WIDGET_DAYS, 'days');
367 insertSelectorVal(this.type, -1, rpt_strings.WIDGET_MONTHS, 'months');
368 insertSelectorVal(this.type, -1, rpt_strings.WIDGET_YEARS, 'years');
369 this.node.appendChild(this.count);
370 this.node.appendChild(this.type);
372 if (this.seedValue) {
374 var count = this.seedValue.match(/(\d+)([^\d]+)/)[1];
375 var type = this.seedValue.match(/(\d+)([^\d]+)/)[2];
376 setSelector(this.count, count);
377 setSelector(this.type, type);
381 oilsRptAgeWidget.prototype.getValue = function() {
382 var count = getSelectorVal(this.count);
383 var type = getSelectorVal(this.type);
384 return count+''+type;
387 oilsRptAgeWidget.prototype.getDisplayValue = function() {
388 var val = { value : this.getValue() };
389 var label = getSelectorVal(this.count) + ' ';
390 for( var i = 0; i < this.type.options.length; i++ ) {
391 var opt = this.type.options[i];
393 label += opt.innerHTML;
401 /* ---------------------------------------------------------------------
402 Atomic substring picker
403 --------------------------------------------------------------------- */
404 function oilsRptSubstrWidget(args) {
405 this.node = args.node
406 this.seedValue = args.value;
407 this.data = elem('input',{type:'text',size:12})
408 this.offset = elem('input',{type:'text',size:5})
409 this.length = elem('input',{type:'text',size:5})
410 this.offset.disabled = Boolean(args.readonly);
411 this.length.disabled = Boolean(args.readonly);
414 oilsRptSubstrWidget.prototype.draw = function() {
415 this.node.appendChild(text('string: '))
416 this.node.appendChild(this.data);
417 this.node.appendChild(elem('br'));
418 this.node.appendChild(text('offset: '))
419 this.node.appendChild(this.offset);
420 this.node.appendChild(elem('br'));
421 this.node.appendChild(text('length: '))
422 this.node.appendChild(this.length);
424 if (this.seedValue) {
425 // TODO: unested; substring currently not supported.
426 this.data.value = this.seedValue[0];
427 this.offset.value = this.seedValue[1];
428 this.length.value = this.seedValue[2];
432 oilsRptSubstrWidget.prototype.getValue = function() {
434 transform : 'substring',
435 params : [ this.data.value, this.offset.value, this.length.value ]
439 oilsRptSubstrWidget.prototype.getDisplayValue = function() {
441 label : this.data.value + ' : ' + this.offset.value + ' : ' + this.length.value,
442 value : this.getValue()
447 /* ---------------------------------------------------------------------
449 --------------------------------------------------------------------- */
450 function oilsRptNumberWidget(args) {
451 this.node = args.node;
452 this.seedValue = args.value;
453 this.size = args.size || 32;
454 this.start = args.start;
455 this.selector = elem('select');
456 this.selector.disabled = Boolean(args.readonly);
458 oilsRptNumberWidget.prototype.draw = function() {
459 //insertSelectorVal(this.selector, -1, ' -- Select One -- ', '');
460 for( var i = this.start; i < (this.size + this.start); i++ )
461 insertSelectorVal(this.selector, -1, i, i);
462 this.node.appendChild(this.selector);
466 setSelector(this.selector, this.seedValue);
469 oilsRptNumberWidget.prototype.getValue = function() {
470 return getSelectorVal(this.selector);
473 oilsRptNumberWidget.prototype.getDisplayValue = function() {
474 return { label : this.getValue(), value : this.getValue() };
477 function oilsRptNullWidget(args) {
478 this.node = args.node;
479 this.type = args.type;
481 oilsRptNullWidget.prototype.draw = function() {}
482 oilsRptNullWidget.prototype.getValue = function() {
486 function oilsRptTemplateWidget(args) {
487 this.node = args.node;
488 this.value = args.value;
490 oilsRptTemplateWidget.prototype.draw = function() {
491 this.node.appendChild(text(''+this.value));
494 /* ---------------------------------------------------------------------
495 Relative dates widget
496 -------------------------------------------------------------------- */
497 function oilsRptTruncPicker(args) {
498 this.node = args.node;
499 this.type = args.type;
500 this.seedValue = args.value;
501 this.realSpan = elem('span');
502 this.relSpan = elem('span');
503 hideMe(this.relSpan);
504 args.node = this.realSpan;
505 this.calWidget = new oilsRptCalWidget(args);
506 args.node = this.node;
508 this.selector = elem('select');
509 insertSelectorVal(this.selector,-1,rpt_strings.WIDGET_REAL_DATE,1);
510 insertSelectorVal(this.selector,-1,rpt_strings.WIDGET_RELATIVE_DATE,2);
511 this.selector.disabled = Boolean(args.readonly);
514 new oilsRptNumberWidget(
515 {node:this.relSpan,size:90,start:1,readonly:args.readonly});
517 this.label = 'Day(s)';
518 if(this.type == 'month') this.label = rpt_strings.WIDGET_MONTHS;
519 if(this.type == 'quarter') this.label = rpt_strings.WIDGET_QUARTERS;
520 if(this.type == 'year') this.label = rpt_strings.WIDGET_YEARS;
521 if(this.type == 'date') this.label = rpt_strings.WIDGET_DAYS;
524 oilsRptTruncPicker.prototype.draw = function() {
525 this.node.appendChild(this.selector);
526 this.node.appendChild(this.realSpan);
527 this.node.appendChild(this.relSpan);
528 this.calWidget.draw();
529 this.numberPicker.draw();
530 this.relSpan.appendChild(text(this.label+' ago'));
533 this.selector.onchange = function() {
534 if( getSelectorVal(obj.selector) == 1 ) {
535 unHideMe(obj.realSpan);
538 unHideMe(obj.relSpan);
539 hideMe(obj.realSpan);
543 if (seed = this.seedValue) {
544 if (typeof seed == 'string') {
545 this.calWidget.value = seed;
547 // relative date transform
548 if (seed.transform.match(/relative/)) {
549 setSelector(this.selector, 2)
550 setSelector(this.numberPicker.selector,
551 Math.abs(seed.params[0]));
552 unHideMe(this.relSpan);
553 hideMe(this.realSpan);
559 oilsRptTruncPicker.prototype.getValue = function() {
560 if( getSelectorVal(this.selector) == 2) {
561 var val = this.numberPicker.getValue();
562 var tform = 'relative_' + this.type;
563 return { transform : tform, params : ['-'+val] };
565 return this.calWidget.getValue();
568 oilsRptTruncPicker.prototype.getDisplayValue = function() {
569 if( getSelectorVal(this.selector) == 2) {
570 var num = this.numberPicker.getValue();
571 return { label : num +' '+this.label+' ago', value : this.getValue() };
573 return this.calWidget.getDisplayValue();
577 /* ---------------------------------------------------------------------
578 Atomic remote object picker
579 --------------------------------------------------------------------- */
581 function oilsRptRemoteWidget(args) {
582 this.node = args.node;
583 this.class = args.class;
584 this.field = args.field;
585 this.column = args.column;
586 this.seedValue = args.value;
587 this.source = elem('select',
588 {multiple:'multiple','class':'oils_rpt_small_info_selector'});
589 this.source.disabled = Boolean(args.readonly);
592 // selected is unused
593 oilsRptRemoteWidget.prototype.draw = function(selected, callback) {
595 iterate(oilsIDL[this.class].fields,
597 if(i.type == 'link' && i.class == 'aou')
602 if(orgcol) _debug("found org column for remote widget: " + orgcol);
605 iterate(oilsRptMyOrgs,function(i){orgs.push(i.id());});
606 var req = new Request(OILS_RPT_MAGIC_FETCH, SESSION, {
613 this.node.appendChild(this.source);
614 req.callback(function(r){
615 // render selects values from seed data if necessary
616 obj.render(r.getResultObject());
618 // presence of a callback suggests there is a container widget
619 // (e.g. SetWidget) for tracking our values. Callback lets
620 // the container extract the selected values, then we deselect
621 // in the input widget (us) since it's redundant.
623 dojo.forEach(obj.source.options, function(o) {
631 oilsRptRemoteWidget.prototype.render = function(objs) {
632 var selector = this.field.selector;
635 if (a[selector]() > b[selector]())
640 for( var i = 0; i < objs.length; i++ ) {
642 var label = obj[this.field.selector]();
643 var value = obj[this.column]();
644 _debug("inserted remote object "+label + ' : ' + value);
645 var opt = insertSelectorVal(this.source, -1, label, value);
646 if (this.seedValue && (
647 this.seedValue.indexOf(Number(value)) > -1
648 || this.seedValue.indexOf(''+value) > -1
655 oilsRptRemoteWidget.prototype.getDisplayValue = function() {
660 vals.push({ label : o.innerHTML, value : o.getAttribute('value')});
666 oilsRptRemoteWidget.prototype.getValue = function() {
671 vals.push(o.getAttribute('value'))
680 /* ---------------------------------------------------------------------
682 --------------------------------------------------------------------- */
684 /* ---------------------------------------------------------------------
685 custom my-orgs picker
686 --------------------------------------------------------------------- */
687 function oilsRptMyOrgsWidget(node, orgid, maxorg) {
688 _debug('fetching my orgs with max org of ' + maxorg);
691 this.maxorg = maxorg || 1;
694 this.node.disabled = true;
699 oilsRptMyOrgsWidget.prototype.draw = function() {
701 var req = new Request(OILS_RPT_FETCH_ORG_FULL_PATH, this.orgid);
704 function(r) { obj.drawWidget(r.getResultObject()); }
708 this.drawWidget(oilsRptMyOrgs);
712 oilsRptMyOrgsWidget.prototype.drawWidget = function(orglist) {
715 oilsRptMyOrgs = orglist;
716 for( var i = 0; i < orglist.length; i++ ) {
717 var org = orglist[i];
718 var opt = insertSelectorVal( this.node, -1,
719 org.name(), org.id(), null, findOrgDepth(org) );
720 if( org.id() == this.orgid )
723 if( org.id() == this.maxorg )
725 else opt.disabled = true;
730 oilsRptMyOrgsWidget.prototype.getValue = function() {
731 return getSelectorVal(this.node);