1 /** initializes reports, some basid display settings,
2 * grabs and builds the IDL tree
4 function oilsInitReportBuilder() {
6 oilsReportBuilderReset();
7 DOM.oils_rpt_table.onclick =
8 function(){hideMe(DOM.oils_rpt_column_editor)};
9 //oilsRptBuildCalendars();
12 hideMe(DOM.oils_rpt_tree_loading);
13 unHideMe(DOM.oils_rpt_table);
18 function oilsReportBuilderReset() {
19 var n = (oilsRpt) ? oilsRpt.name : "";
20 oilsRpt = new oilsReport();
22 oilsRptDisplaySelector = DOM.oils_rpt_display_selector;
23 oilsRptFilterSelector = DOM.oils_rpt_filter_selector;
24 removeChildren(oilsRptDisplaySelector);
25 removeChildren(oilsRptFilterSelector);
32 function oilsRptBuildCalendars() {
34 inputField : "oils_rpt_filter_tform_timestamp_input", // id of the input field
35 ifFormat : "%Y-%m-%d", // format of the input field
36 button : "oils_rpt_filter_tform_timestamp_cal", // trigger for the calendar (button ID)
37 align : "Tl", // alignment (defaults to "Bl")
41 inputField : "oils_rpt_filter_tform_timestamp_input_2", // id of the input field
42 ifFormat : "%Y-%m-%d", // format of the input field
43 button : "oils_rpt_filter_tform_timestamp_cal2", // trigger for the calendar (button ID)
44 align : "Tl", // alignment (defaults to "Bl")
51 /* creates a label "path" based on the column path */
52 function oilsRptMakeLabel(path) {
53 var parts = path.split(/-/);
55 for( var i = 0; i < parts.length; i++ ) {
58 str += oilsIDL[parts[i]].label;
60 var f = oilsRptFindField(oilsIDL[parts[i-1]], parts[i]);
68 /* adds an item to the display window */
69 function oilsAddRptDisplayItem(path, name, tform, params) {
70 if( ! oilsAddSelectorItem(oilsRptDisplaySelector, path, name) )
73 /* add the selected columns to the report output */
74 name = (name) ? name : oilsRptPathCol(path);
75 var param = oilsRptNextParam();
77 /* add this item to the select blob */
79 relation:oilsRptPathRel(path),
86 params.unshift(oilsRptPathCol(path));
87 sel.column[tform] = params;
89 sel.column[tform] = oilsRptPathCol(path);
91 } else { sel.column = oilsRptPathCol(path); }
93 oilsRpt.def.select.push(sel);
95 mergeObjects( oilsRpt.def.from, oilsRptBuildFromClause(path));
96 oilsRpt.params[param] = name;
100 /* takes a column path and builds a from-clause object for the path */
101 function oilsRptBuildFromClause(path) {
102 var parts = path.split(/-/);
107 for( var i = 0; i < parts.length; i += 2 ) {
109 var col = parts[i+1];
110 var node = oilsIDL[parts[i]];
111 var field = oilsRptFindField(node, col);
112 newpath = (newpath) ? newpath + '-'+ cls : cls;
114 tobj.table = node.table;
115 tobj.alias = newpath;
116 _debug('field type is ' + field.type);
117 if( i == (parts.length - 2) ) break;
123 if( field.type == 'link' )
124 tobj.key = field.key;
126 newpath = newpath + '-'+ col;
129 _debug("built 'from' clause: path="+path+"\n"+formatJSON(js2JSON(obj)));
134 /* removes a specific item from the display window */
135 function oilsDelDisplayItem(val) {
136 oilsDelSelectorItem(oilsRptDisplaySelector, val);
139 /* removes selected items from the display window */
140 function oilsDelSelectedDisplayItems() {
141 var list = oilsDelSelectedItems(oilsRptDisplaySelector);
143 /* remove the de-selected columns from the report output */
144 oilsRpt.def.select = grep( oilsRpt.def.select,
146 for( var j = 0; j < list.length; j++ ) {
150 /* if this columsn has a transform,
151 it will be an object { tform => column } */
152 if( typeof col != 'string' )
153 for( var c in col ) col = col[c];
155 /* if this transform requires params, the column
156 will be the first item in the param set array */
157 if( typeof col != 'string' ) col = col[0];
159 if( oilsRptPathRel(d) == i.relation && oilsRptPathCol(d) == col ) {
160 var param = (i.alias) ? i.alias.match(/::PARAM\d*/) : null;
161 if( param ) delete oilsRpt.params[param];
169 if(!oilsRpt.def.select) {
170 oilsRpt.def.select = [];
171 oilsReportBuilderReset();
174 for( var j = 0; j < list.length; j++ )
175 /* if there are no items left in the "select" clause for the given
176 relation, trim this relation from the "from" clause */
177 if(!grep(oilsRpt.def.select,
178 function(i){ return (i.relation == oilsRptPathRel(list[j])); }))
179 oilsRptPruneFromClause(oilsRptPathRel(list[j]));
185 /* for each item in the path list, remove the associated data
186 from the "from" clause */
188 function oilsRptPruneFromClause(relation, node) {
189 _debug("removing relation from 'from' clause " + relation);
190 if(!node) node = oilsRpt.def.from.join;
191 for( var i in node ) {
192 if( node[i].alias == relation ) {
194 /* if we have subtrees, don't delete our tree node */
202 if( oilsRptPruneFromClause(relation, node[i].join ) ) {
203 if(oilsRptObjectKeys(node[i].join).length == 0) {
205 /* if there are no items in the select clause with a relation matching
206 this nodes alias, we can safely remove this node from the tree */
207 if(!grep(oilsRpt.def.select,function(r){return (r.relation==node[i].alias)}))
218 /* adds an item to the display window */
219 function oilsAddRptFilterItem(val) {
220 oilsAddSelectorItem(oilsRptFilterSelector, val);
223 /* removes a specific item from the display window */
224 function oilsDelFilterItem(val) {
225 oilsDelSelectorItem(oilsRptFilterSelector, val);
228 /* removes selected items from the display window */
229 function oilsDelSelectedFilterItems() {
230 oilsDelSelectedItems(oilsRptFilterSelector);
234 /* adds an item to the display window */
235 function oilsAddSelectorItem(sel, val, name) {
236 name = (name) ? name : oilsRptMakeLabel(val);
237 _debug("adding selector item "+name+' = ' +val);
238 for( var i = 0; i < sel.options.length; i++ ) {
239 var opt = sel.options[i];
240 if( opt.value == val ) return false;
242 insertSelectorVal( sel, -1, name, val );
247 /* removes a specific item from the display window */
248 function oilsDelSelectorItem(sel, val) {
249 _debug("deleting selector item "+val);
250 var opts = sel.options;
251 for( var i = 0; i < opts.length; i++ ) {
253 if( opt.value == val ) {
254 if( i == opts.length - 1 )
256 else opts[i] = opts[i+1];
262 /* removes selected items from the display window */
263 function oilsDelSelectedItems(sel) {
264 var list = getSelectedList(sel);
265 for( var i = 0; i < list.length; i++ )
266 oilsDelSelectorItem(sel, list[i]);
271 /* hides the different field editor tabs */
272 function oilsRptHideEditorDivs() {
273 hideMe(DOM.oils_rpt_tform_div);
274 hideMe(DOM.oils_rpt_filter_div);
275 hideMe(DOM.oils_rpt_agg_filter_div);
280 This draws the 3-tabbed window containing the transform,
281 filter, and aggregate filter picker window
283 function oilsRptDrawDataWindow(path) {
284 var col = oilsRptPathCol(path);
285 var cls = oilsRptPathClass(path);
286 var field = oilsRptFindField(oilsIDL[cls], col);
288 appendClear(DOM.oils_rpt_editor_window_label, text(oilsRptMakeLabel(path)));
289 appendClear(DOM.oils_rpt_editor_window_datatype, text(field.datatype));
291 _debug("setting update data window for column "+col+' on class '+cls);
293 var div = DOM.oils_rpt_column_editor;
294 /* set a preliminary top position so the page won't bounce around */
295 div.setAttribute('style','top:'+oilsMouseX+'px');
297 /* unhide the div so we can determine the dimensions */
300 /* don't let them see the floating div until the position is fully determined */
301 div.style.visibility='hidden';
303 oilsRptDrawTransformWindow(path, col, cls, field);
304 oilsRptDrawFilterWindow(path, col, cls, field);
306 //oilsRptSetFilters(field.datatype);
308 //oilsRptDoFilterWidgets();
310 //DOM.oils_rpt_filter_tform_selector.onchange = oilsRptDoFilterWidgets;
312 buildFloatingDiv(div, 600);
314 /* now let them see it */
315 div.style.visibility='visible';
317 oilsRptSetDataWindowActions(div);
321 function oilsRptSetDataWindowActions(div) {
322 /* give the tab links behavior */
323 DOM.oils_rpt_tform_tab.onclick =
324 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_tform_div)};
325 DOM.oils_rpt_filter_tab.onclick =
326 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_filter_div)};
327 DOM.oils_rpt_agg_filter_tab.onclick =
328 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_agg_filter_div)};
330 DOM.oils_rpt_tform_tab.onclick();
331 DOM.oils_rpt_column_editor_close_button.onclick = function(){hideMe(div);};
335 function oilsRptDrawFilterWindow(path, col, cls, field) {
336 oilsRptCurrentFilterTform = new oilsRptTFormManager(DOM.oils_rpt_filter_tform_table);
337 oilsRptCurrentFilterTform.build(field.datatype, false, true);
338 oilsRptCurrentFilterOpManager = new oilsRptOpManager(DOM.oils_rpt_filter_op_table);
342 /* draws the transform window */
343 function oilsRptDrawTransformWindow(path, col, cls, field) {
344 DOM.oils_rpt_tform_label_input.value = oilsRptMakeLabel(path);
345 var dtype = field.datatype;
347 DOM.oils_rpt_tform_submit.onclick =
350 var tform = oilsRptGetTform(dtype);
351 _debug('found tform: ' + js2JSON(tform));
352 var params = getRptTformParams(dtype, tform);
353 _debug('found tform params: ' + js2JSON(params));
354 tform = (tform == 'raw') ? null : tform;
357 var tform = oilsRptCurrentTform.getCurrentTForm();
358 oilsAddRptDisplayItem(path, DOM.oils_rpt_tform_label_input.value, tform.value, tform.params )
362 DOM.oils_rpt_tform_label_input.focus();
363 DOM.oils_rpt_tform_label_input.select();
365 oilsRptCurrentTform = new oilsRptTFormManager(DOM.oils_rpt_tform_table);
366 oilsRptCurrentTform.build(dtype, true, true);
369 oilsRptHideTformFields();
370 oilsRptUnHideTformFields(dtype);
373 _debug("Building transiform window for datatype "+dtype);
376 unHideMe($('oils_rpt_tform_'+dtype+'_div'));
377 $('oils_rpt_tform_all_raw').checked = true;
382 function oilsRptHideTformFields() {
383 var rows = DOM.oils_rpt_tform_tbody.childNodes;
384 for( var i = 0; i < rows.length; i++ )
385 if( rows[i] && rows[i].nodeType == 1 )
389 function oilsRptUnHideTformFields(dtype) {
390 var rows = DOM.oils_rpt_tform_tbody.childNodes;
391 for( var i = 0; i < rows.length; i++ ) {
393 if( row && row.nodeType == 1 &&
394 (row.getAttribute('datatype')=='all'
395 || row.getAttribute('datatype') == dtype)) {
402 function oilsRptGetTform(datatype) {
403 for( var i in oilsRptTransforms[datatype] )
404 if( $('oils_rpt_tform_'+datatype+'_'+oilsRptTransforms[datatype][i]).checked )
405 return oilsRptTransforms[datatype][i];
406 for( var i in oilsRptTransforms.all )
407 if( $('oils_rpt_tform_all_'+oilsRptTransforms.all[i]).checked )
408 return oilsRptTransforms.all[i];
415 function getRptTformParams(type, tform) {
421 DOM.oils_rpt_tform_string_substring_offset.value,
422 DOM.oils_rpt_tform_string_substring_length.value];
429 /* given a transform selector, this displays the appropriate
430 transforms for the given datatype.
431 if aggregate is true, is displays the aggregate transforms */
433 function oilsRptSetTransforms(sel, dtype, show_agg, show_noagg) {
434 for( var i = 0; i < sel.options.length; i++ ) {
435 var opt = sel.options[i];
436 var t = opt.getAttribute('datatype');
437 if( t && t != dtype ){
440 var ag = opt.getAttribute('aggregate');
443 else if( ag && ! show_agg )
445 else if( !ag && show_noagg )
455 /* displays the correct filter-transforms for the given datatype */
457 function oilsRptSetFilters(dtype) {
459 DOM.oils_rpt_filter_submit.onclick = function() {
460 var data = oilsRptDoFilterWidgets();
461 alert(js2JSON(data));
464 var sel = DOM.oils_rpt_filter_tform_selector;
465 for( var i = 0; i < sel.options.length; i++ ) {
466 var opt = sel.options[i];
467 _debug(opt.getAttribute('op'));
468 var t = opt.getAttribute('datatype');
469 if( t && t != dtype ) hideMe(opt);
475 /* hides all of the filter widgets */
476 function oilsRptHideFilterWidgets(node) {
478 node = DOM.oils_rpt_filter_tform_widget_td;
479 if( node.nodeType != 1 ) return;
480 if( node.getAttribute('widget') ) {
483 var cs = node.childNodes;
484 for( var i = 0; cs && i < cs.length; i++ )
485 oilsRptHideFilterWidgets(cs[i]);
489 /* what does this need to do? */
490 function oilsRptSetFilterOpActions() {
495 /* hides/unhides the appropriate widgets and returns the parameter
496 array appropriate for the selected widget */
497 function oilsRptDoFilterWidgets() {
498 filter = getSelectorVal(DOM.oils_rpt_filter_tform_selector);
499 oilsRptHideFilterWidgets();
506 /* generic transforms */
508 if(!op) op = 'equals';
512 if(!op) op = 'ilike';
524 if(!op) op = 'not in';
526 if(!op) op = 'between';
528 if(!op) op = 'not between';
529 unHideMe(DOM.oils_rpt_filter_tform_input);
530 params = [DOM.oils_rpt_filter_tform_input.value];
533 /* timestamp transforms */
535 if(!op) op = 'between';
536 case 'date_not_between':
537 if(!op) op = 'not between';
540 unHideMe(DOM.oils_rpt_filter_tform_date_1);
541 unHideMe(DOM.oils_rpt_filter_tform_date_2);
542 unHideMe(DOM.oils_rpt_filter_tform_date_hint);
543 DOM.oils_rpt_filter_tform_date_1.value = mkYearMonDay();
544 DOM.oils_rpt_filter_tform_date_2.value = mkYearMonDay();
546 DOM.oils_rpt_filter_tform_date_1.value,
547 DOM.oils_rpt_filter_tform_date_2.value
553 if(!tform) tform = 'dow';
554 case 'dow_not_between':
555 if(!op) op = 'not between';
556 if(!tform) tform = 'dow';
561 if(!tform) tform = 'dom';
562 case 'dom_not_between':
563 if(!op) op = 'not between';
564 if(!tform) tform = 'dom';
567 case 'month_between':
569 if(!tform) tform = 'moy';
570 case 'month_not_between':
571 if(!op) op = 'not between';
572 if(!tform) tform = 'moy';
575 case 'quarter_between':
577 if(!tform) tform = 'qoy';
578 case 'quarter_not_between':
579 if(!op) op = 'not between';
580 if(!tform) tform = 'qoy';
584 if(!op) op = 'between';
585 if(!tform) tform = 'year_trunc';
586 case 'year_not_between':
587 if(!op) op = 'not between';
588 if(!tform) tform = 'year_trunc';
592 if(!op) op = 'between';
593 if(!tform) tform = 'age';
594 case 'age_not_between':
595 if(!op) op = 'not between';
596 if(!tform) tform = 'age';
599 /* string transforms */
601 if(!tform) tform = 'substring';
606 if(!tform) tform = 'dow';
610 if(!tform) tform = 'dow';
612 /* numeric transforms */
615 if(!tform) tform = 'dow';
619 if(!tform) tform = 'dow';
622 return { op : op, params : params, tform : tform };