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 /* adds an item to the display window */
52 function oilsAddRptDisplayItem(path, name, tform, params) {
53 if( ! oilsAddSelectorItem(oilsRptDisplaySelector, path, name) )
56 /* add the selected columns to the report output */
57 name = (name) ? name : oilsRptPathCol(path);
58 if( !tform ) tform = 'Bare';
60 /* add this item to the select blob */
62 relation: oilsRptPathRel(path),
64 column: { transform: tform, colname: oilsRptPathCol(path) }
67 if( params ) sel.column.params = params;
68 oilsRpt.def.select.push(sel);
70 mergeObjects( oilsRpt.def.from, oilsRptBuildFromClause(path));
74 /* takes a column path and builds a from-clause object for the path */
75 function oilsRptBuildFromClause(path) {
77 /* the path is the full path (relation) from the source
78 object to the column in question (e.g. au-home_ou-aou-name)*/
79 var parts = path.split(/-/);
81 /* the final from clause */
84 /* reference to the current position in the from clause */
89 /* walk the path, fleshing the from clause as we go */
90 for( var i = 0; i < parts.length; i += 2 ) {
92 var cls = parts[i]; /* class name (id) */
93 var col = parts[i+1]; /* column name */
95 /* a "node" is a class description from the IDL, it
96 contains relevant info, plus a list of "fields",
98 var node = oilsIDL[cls];
99 var pkey = oilsRptFindField(node, node.pkey);
101 /* a "field" is a parsed version of a column from the IDL,
102 contains datatype, column name, etc. */
103 var field = oilsRptFindField(node, col);
105 /* re-construct the path as we go so
106 we know what all we've seen thus far */
107 newpath = (newpath) ? newpath + '-'+ cls : cls;
109 /* extract relevant info */
110 tobj.table = node.table;
111 tobj.alias = newpath;
112 _debug('field type is ' + field.type);
113 if( i == (parts.length - 2) ) break;
115 /* we still have columns left in the path, keep adding join's */
117 if(field.reltype != 'has_a')
118 col = pkey.name + '-' + col;
125 if( field.type == 'link' )
126 tobj.key = field.key;
128 newpath = newpath + '-'+ path_col;
131 _debug("built 'from' clause: path="+path+"\n"+formatJSON(js2JSON(obj)));
136 /* removes a specific item from the display window */
137 function oilsDelDisplayItem(val) {
138 oilsDelSelectorItem(oilsRptDisplaySelector, val);
141 /* removes selected items from the display window */
142 function oilsDelSelectedDisplayItems() {
143 var list = oilsDelSelectedItems(oilsRptDisplaySelector);
145 /* remove the de-selected columns from the report output */
146 oilsRpt.def.select = grep( oilsRpt.def.select,
148 for( var j = 0; j < list.length; j++ ) {
152 /* if this columsn has a transform,
153 it will be an object { tform => column } */
154 if( typeof col != 'string' )
155 for( var c in col ) col = col[c];
157 /* if this transform requires params, the column
158 will be the first item in the param set array */
159 if( typeof col != 'string' ) col = col[0];
161 if( oilsRptPathRel(d) == i.relation && oilsRptPathCol(d) == col ) {
162 var param = (i.alias) ? i.alias.match(/::PARAM\d*/) : null;
163 if( param ) delete oilsRpt.params[param];
171 if(!oilsRpt.def.select) {
172 oilsRpt.def.select = [];
173 oilsReportBuilderReset();
176 for( var j = 0; j < list.length; j++ )
177 /* if there are no items left in the "select" clause for the given
178 relation, trim this relation from the "from" clause */
179 if(!grep(oilsRpt.def.select,
180 function(i){ return (i.relation == oilsRptPathRel(list[j])); }))
181 oilsRptPruneFromClause(oilsRptPathRel(list[j]));
187 /* for each item in the path list, remove the associated data
188 from the "from" clause */
190 function oilsRptPruneFromClause(relation, node) {
191 _debug("removing relation from 'from' clause " + relation);
192 if(!node) node = oilsRpt.def.from.join;
193 for( var i in node ) {
194 if( node[i].alias == relation ) {
196 /* if we have subtrees, don't delete our tree node */
204 if( oilsRptPruneFromClause(relation, node[i].join ) ) {
205 if(oilsRptObjectKeys(node[i].join).length == 0) {
207 /* if there are no items in the select clause with a relation matching
208 this nodes alias, we can safely remove this node from the tree */
209 if(!grep(oilsRpt.def.select,function(r){return (r.relation==node[i].alias)}))
220 /* adds an item to the display window */
221 function oilsAddRptFilterItem(val) {
222 oilsAddSelectorItem(oilsRptFilterSelector, val);
225 /* removes a specific item from the display window */
226 function oilsDelFilterItem(val) {
227 oilsDelSelectorItem(oilsRptFilterSelector, val);
230 /* removes selected items from the display window */
231 function oilsDelSelectedFilterItems() {
232 oilsDelSelectedItems(oilsRptFilterSelector);
236 /* adds an item to the display window */
237 function oilsAddSelectorItem(sel, val, name) {
238 name = (name) ? name : oilsRptMakeLabel(val);
239 _debug("adding selector item "+name+' = ' +val);
240 for( var i = 0; i < sel.options.length; i++ ) {
241 var opt = sel.options[i];
242 if( opt.value == val ) return false;
244 insertSelectorVal( sel, -1, name, val );
249 /* removes a specific item from the display window */
250 function oilsDelSelectorItem(sel, val) {
251 _debug("deleting selector item "+val);
252 var opts = sel.options;
253 for( var i = 0; i < opts.length; i++ ) {
255 if( opt.value == val ) {
256 if( i == opts.length - 1 )
258 else opts[i] = opts[i+1];
264 /* removes selected items from the display window */
265 function oilsDelSelectedItems(sel) {
266 var list = getSelectedList(sel);
267 for( var i = 0; i < list.length; i++ )
268 oilsDelSelectorItem(sel, list[i]);
273 /* hides the different field editor tabs */
274 function oilsRptHideEditorDivs() {
275 hideMe(DOM.oils_rpt_tform_div);
276 hideMe(DOM.oils_rpt_filter_div);
277 hideMe(DOM.oils_rpt_agg_filter_div);
282 This draws the 3-tabbed window containing the transform,
283 filter, and aggregate filter picker window
285 function oilsRptDrawDataWindow(path) {
286 var col = oilsRptPathCol(path);
287 var cls = oilsRptPathClass(path);
288 var field = oilsRptFindField(oilsIDL[cls], col);
290 appendClear(DOM.oils_rpt_editor_window_label, text(oilsRptMakeLabel(path)));
291 appendClear(DOM.oils_rpt_editor_window_datatype, text(field.datatype));
293 _debug("setting update data window for column "+col+' on class '+cls);
295 var div = DOM.oils_rpt_column_editor;
296 /* set a preliminary top position so the page won't bounce around */
297 div.setAttribute('style','top:'+oilsMouseX+'px');
299 /* unhide the div so we can determine the dimensions */
302 /* don't let them see the floating div until the position is fully determined */
303 div.style.visibility='hidden';
305 oilsRptDrawTransformWindow(path, col, cls, field);
306 oilsRptDrawFilterWindow(path, col, cls, field);
308 //oilsRptSetFilters(field.datatype);
310 //oilsRptDoFilterWidgets();
312 //DOM.oils_rpt_filter_tform_selector.onchange = oilsRptDoFilterWidgets;
314 buildFloatingDiv(div, 600);
316 /* now let them see it */
317 div.style.visibility='visible';
319 oilsRptSetDataWindowActions(div);
323 function oilsRptSetDataWindowActions(div) {
324 /* give the tab links behavior */
325 DOM.oils_rpt_tform_tab.onclick =
326 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_tform_div)};
327 DOM.oils_rpt_filter_tab.onclick =
328 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_filter_div)};
329 DOM.oils_rpt_agg_filter_tab.onclick =
330 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_agg_filter_div)};
332 DOM.oils_rpt_tform_tab.onclick();
333 DOM.oils_rpt_column_editor_close_button.onclick = function(){hideMe(div);};
337 function oilsRptDrawFilterWindow(path, col, cls, field) {
338 oilsRptCurrentFilterTform = new oilsRptTFormManager(DOM.oils_rpt_filter_tform_table);
339 oilsRptCurrentFilterTform.build(field.datatype, false, true);
340 oilsRptCurrentFilterOpManager = new oilsRptOpManager(DOM.oils_rpt_filter_op_table);
344 /* draws the transform window */
345 function oilsRptDrawTransformWindow(path, col, cls, field) {
346 DOM.oils_rpt_tform_label_input.value = oilsRptMakeLabel(path);
347 var dtype = field.datatype;
349 DOM.oils_rpt_tform_submit.onclick =
352 var tform = oilsRptGetTform(dtype);
353 _debug('found tform: ' + js2JSON(tform));
354 var params = getRptTformParams(dtype, tform);
355 _debug('found tform params: ' + js2JSON(params));
356 tform = (tform == 'raw') ? null : tform;
359 var tform = oilsRptCurrentTform.getCurrentTForm();
360 oilsAddRptDisplayItem(path, DOM.oils_rpt_tform_label_input.value, tform.value, tform.params )
364 DOM.oils_rpt_tform_label_input.focus();
365 DOM.oils_rpt_tform_label_input.select();
367 oilsRptCurrentTform = new oilsRptTFormManager(DOM.oils_rpt_tform_table);
368 oilsRptCurrentTform.build(dtype, true, true);
371 oilsRptHideTformFields();
372 oilsRptUnHideTformFields(dtype);
375 _debug("Building transiform window for datatype "+dtype);
378 unHideMe($('oils_rpt_tform_'+dtype+'_div'));
379 $('oils_rpt_tform_all_raw').checked = true;
384 function oilsRptHideTformFields() {
385 var rows = DOM.oils_rpt_tform_tbody.childNodes;
386 for( var i = 0; i < rows.length; i++ )
387 if( rows[i] && rows[i].nodeType == 1 )
391 function oilsRptUnHideTformFields(dtype) {
392 var rows = DOM.oils_rpt_tform_tbody.childNodes;
393 for( var i = 0; i < rows.length; i++ ) {
395 if( row && row.nodeType == 1 &&
396 (row.getAttribute('datatype')=='all'
397 || row.getAttribute('datatype') == dtype)) {
404 function oilsRptGetTform(datatype) {
405 for( var i in oilsRptTransforms[datatype] )
406 if( $('oils_rpt_tform_'+datatype+'_'+oilsRptTransforms[datatype][i]).checked )
407 return oilsRptTransforms[datatype][i];
408 for( var i in oilsRptTransforms.all )
409 if( $('oils_rpt_tform_all_'+oilsRptTransforms.all[i]).checked )
410 return oilsRptTransforms.all[i];
417 function getRptTformParams(type, tform) {
423 DOM.oils_rpt_tform_string_substring_offset.value,
424 DOM.oils_rpt_tform_string_substring_length.value];
431 /* given a transform selector, this displays the appropriate
432 transforms for the given datatype.
433 if aggregate is true, is displays the aggregate transforms */
435 function oilsRptSetTransforms(sel, dtype, show_agg, show_noagg) {
436 for( var i = 0; i < sel.options.length; i++ ) {
437 var opt = sel.options[i];
438 var t = opt.getAttribute('datatype');
439 if( t && t != dtype ){
442 var ag = opt.getAttribute('aggregate');
445 else if( ag && ! show_agg )
447 else if( !ag && show_noagg )
457 /* displays the correct filter-transforms for the given datatype */
459 function oilsRptSetFilters(dtype) {
461 DOM.oils_rpt_filter_submit.onclick = function() {
462 var data = oilsRptDoFilterWidgets();
463 alert(js2JSON(data));
466 var sel = DOM.oils_rpt_filter_tform_selector;
467 for( var i = 0; i < sel.options.length; i++ ) {
468 var opt = sel.options[i];
469 _debug(opt.getAttribute('op'));
470 var t = opt.getAttribute('datatype');
471 if( t && t != dtype ) hideMe(opt);
477 /* hides all of the filter widgets */
478 function oilsRptHideFilterWidgets(node) {
480 node = DOM.oils_rpt_filter_tform_widget_td;
481 if( node.nodeType != 1 ) return;
482 if( node.getAttribute('widget') ) {
485 var cs = node.childNodes;
486 for( var i = 0; cs && i < cs.length; i++ )
487 oilsRptHideFilterWidgets(cs[i]);
491 /* what does this need to do? */
492 function oilsRptSetFilterOpActions() {
497 /* hides/unhides the appropriate widgets and returns the parameter
498 array appropriate for the selected widget */
499 function oilsRptDoFilterWidgets() {
500 filter = getSelectorVal(DOM.oils_rpt_filter_tform_selector);
501 oilsRptHideFilterWidgets();
508 /* generic transforms */
510 if(!op) op = 'equals';
514 if(!op) op = 'ilike';
526 if(!op) op = 'not in';
528 if(!op) op = 'between';
530 if(!op) op = 'not between';
531 unHideMe(DOM.oils_rpt_filter_tform_input);
532 params = [DOM.oils_rpt_filter_tform_input.value];
535 /* timestamp transforms */
537 if(!op) op = 'between';
538 case 'date_not_between':
539 if(!op) op = 'not between';
542 unHideMe(DOM.oils_rpt_filter_tform_date_1);
543 unHideMe(DOM.oils_rpt_filter_tform_date_2);
544 unHideMe(DOM.oils_rpt_filter_tform_date_hint);
545 DOM.oils_rpt_filter_tform_date_1.value = mkYearMonDay();
546 DOM.oils_rpt_filter_tform_date_2.value = mkYearMonDay();
548 DOM.oils_rpt_filter_tform_date_1.value,
549 DOM.oils_rpt_filter_tform_date_2.value
555 if(!tform) tform = 'dow';
556 case 'dow_not_between':
557 if(!op) op = 'not between';
558 if(!tform) tform = 'dow';
563 if(!tform) tform = 'dom';
564 case 'dom_not_between':
565 if(!op) op = 'not between';
566 if(!tform) tform = 'dom';
569 case 'month_between':
571 if(!tform) tform = 'moy';
572 case 'month_not_between':
573 if(!op) op = 'not between';
574 if(!tform) tform = 'moy';
577 case 'quarter_between':
579 if(!tform) tform = 'qoy';
580 case 'quarter_not_between':
581 if(!op) op = 'not between';
582 if(!tform) tform = 'qoy';
586 if(!op) op = 'between';
587 if(!tform) tform = 'year_trunc';
588 case 'year_not_between':
589 if(!op) op = 'not between';
590 if(!tform) tform = 'year_trunc';
594 if(!op) op = 'between';
595 if(!tform) tform = 'age';
596 case 'age_not_between':
597 if(!op) op = 'not between';
598 if(!tform) tform = 'age';
601 /* string transforms */
603 if(!tform) tform = 'substring';
608 if(!tform) tform = 'dow';
612 if(!tform) tform = 'dow';
614 /* numeric transforms */
617 if(!tform) tform = 'dow';
621 if(!tform) tform = 'dow';
624 return { op : op, params : params, tform : tform };