]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/reports/oils_rpt_builder.js
fixed some select clause orderinb bugs caused by adding non-aggregate display items...
[Evergreen.git] / Open-ILS / web / reports / oils_rpt_builder.js
1 /** initializes reports, some basid display settings, 
2   * grabs and builds the IDL tree
3   */
4 function oilsInitReportBuilder() {
5         if(!oilsInitReports()) return false;
6         oilsReportBuilderReset();
7         DOM.oils_rpt_table.onclick = 
8                 function(){hideMe(DOM.oils_rpt_column_editor)};
9         oilsDrawRptTree(
10                 function() { 
11                         hideMe(DOM.oils_rpt_tree_loading); 
12                         unHideMe(DOM.oils_rpt_table); 
13                         oilsRptBuilderDrawClone(new CGI().param('ct'));
14                 }
15         );
16
17         DOM.oils_rpt_builder_save_template.onclick = oilsReportBuilderSave;
18 }
19
20 function oilsRptBuilderDrawClone(templateId) {
21         if(!templateId) return;
22         unHideMe(DOM.oils_rpt_builder_cloning);
23
24         oilsRptFetchTemplate(templateId,
25                 function(template) { oilsRptBuilderDrawClone2(template);}
26         );
27 }
28
29
30 function oilsRptBuilderDrawClone2(template) {
31         appendClear( DOM.oils_rpt_build_cloning_name, template.name() );
32         DOM.oils_rpt_builder_new_name.value = template.name();
33         DOM.oils_rpt_builder_new_desc.value = template.description();
34
35         _debug(formatJSON(template.data()));
36
37         /* manually shove data into the display selectors */
38         var def = JSON2js(template.data());
39
40         var table = def.from.table;
41         var node;
42         for( var i in oilsIDL ) {
43                 node = oilsIDL[i];
44                 if( node.table == table ) {
45                         setSelector(DOM.oils_rpt_builder_type_selector, node.name);
46                         DOM.oils_rpt_builder_type_selector.onchange();
47                         break;
48                 }
49         }
50
51         iterate(def.select,
52                 function(item) {
53                         oilsAddRptDisplayItem(item.path, item.alias, item.column.transform)});
54
55         iterate(def.where,
56                 function(item) {
57                         oilsAddRptFilterItem(item.path, item.column.transform, oilsRptObjectKeys(item.condition)[0])});
58
59         iterate(def.having,
60                 function(item) {
61                         oilsAddRptHavingItem(item.path, item.column.transform, oilsRptObjectKeys(item.condition)[0])});
62
63         oilsRpt.setTemplate(template);
64         oilsRpt.templateObject = null; /* simplify debugging */
65 }
66
67 function oilsReportBuilderReset() {
68         var n = (oilsRpt) ? oilsRpt.name : "";
69         oilsRpt = new oilsReport();
70         oilsRpt.name = n;
71         oilsRptDisplaySelector  = DOM.oils_rpt_display_selector;
72         oilsRptFilterSelector   = DOM.oils_rpt_filter_selector;
73         oilsRptHavingSelector   = DOM.oils_rpt_agg_filter_selector;
74         removeChildren(oilsRptDisplaySelector);
75         removeChildren(oilsRptFilterSelector);
76         removeChildren(oilsRptHavingSelector);
77         //removeChildren(oilsRptOrderBySelector);
78         oilsRptResetParams();
79 }
80
81 function oilsReportBuilderSave() {
82
83         var tmpl = new rt();
84         tmpl.name(DOM.oils_rpt_builder_new_name.value);
85         tmpl.description(DOM.oils_rpt_builder_new_desc.value);
86         tmpl.owner(USER.id());
87         tmpl.folder(new CGI().param('folder'));
88         tmpl.data(js2JSON(oilsRpt.def));
89
90         if(!confirm('Name : '+tmpl.name() + '\nDescription: ' + tmpl.description()+'\nSave Template?'))
91                 return;
92
93         debugFMObject(tmpl);
94         //return; /* XXX */
95
96         var req = new Request(OILS_RPT_CREATE_TEMPLATE, SESSION, tmpl);
97         req.request.alertEvent = false;
98         req.callback(
99                 function(r) {
100                         var res = r.getResultObject();
101                         if(checkILSEvent(res)) {
102                                 alertILSEvent(res);
103                         } else {
104                                 if( res && res != '0' ) {
105                                         oilsRptAlertSuccess();
106                                         _l('oils_rpt.xhtml');
107                                 } 
108                         }
109                 }
110         );
111         
112         req.send();
113 }
114
115
116
117 /* adds an item to the display window */
118 function oilsAddRptDisplayItem(path, name, tform, params) {
119         if( ! oilsAddSelectorItem(oilsRptDisplaySelector, path, name) ) 
120                 return;
121
122         /* add the selected columns to the report output */
123         name = (name) ? name : oilsRptPathCol(path);
124         if( !tform ) tform = 'Bare';
125
126         var aggregate = oilsRptGetIsAgg(tform);
127
128         /* add this item to the select blob */
129         var sel = {
130                 relation: hex_md5(oilsRptPathRel(path)), 
131                 path : path,
132                 alias: name,
133                 column: { transform: tform, colname: oilsRptPathCol(path) }
134         };
135
136         if( params ) sel.column.params = params;
137         oilsRptAddSelectList(sel, tform);
138         mergeObjects( oilsRpt.def.from, oilsRptBuildFromClause(path));
139         oilsRptDebug();
140 }
141
142 function oilsRptAddSelectList(obj, tform) {
143         if(!oilsRptGetIsAgg(tform)) {
144                 var select = [];
145                 var added = false;
146                 for( var i = 0; i < oilsRpt.def.select.length; i++ ) {
147                         var item = oilsRpt.def.select[i];
148
149                         /* shove the item in question in front of the first agg tform */
150                         if( !added && oilsRptGetIsAgg( item.column.transform ) ) {
151                                 select.push(obj);
152                                 added = true;
153                         }
154                         select.push(item);
155                 }
156
157                 /* if there is no existing agg tfrom to 
158                         insert in front of, add me on the end */
159                 if(!added) select.push(obj);
160
161                 oilsRpt.def.select = select;
162
163                 if( added ) {
164                         /* re-draw the select display to get the order correct */
165                         var sel = oilsRptDisplaySelector;
166                         while( sel.options.length > 0 ) sel.options[0] = null;
167                         iterate(oilsRpt.def.select,
168                                 function(item) {
169                                         _debug('re-inserting display item ' + item.path);
170                                         oilsAddSelectorItem(oilsRptDisplaySelector, item.path, item.alias) });
171                 }
172
173         } else {
174                 /* shove agg transforms onto the end */
175                 oilsRpt.def.select.push(obj);
176         }
177 }
178
179
180
181 function oilsRptGetIsAgg(tform) {
182         return OILS_RPT_TRANSFORMS[tform].aggregate;
183 }
184
185 /* takes a column path and builds a from-clause object for the path */
186 function oilsRptBuildFromClause(path) {
187
188         /* the path is the full path (relation) from the source 
189                 object to the column in question (e.g. au-home_ou-aou-name)*/
190         var parts = path.split(/-/);
191
192         /* the final from clause */
193         var obj = {}; 
194
195         /* reference to the current position in the from clause */
196         var tobj = obj; 
197
198         var newpath = "";
199
200         /* walk the path, fleshing the from clause as we go */
201         for( var i = 0; i < parts.length; i += 2 ) {
202
203                 var cls = parts[i]; /* class name (id) */
204                 var col = parts[i+1]; /* column name */
205
206                 /* a "node" is a class description from the IDL, it 
207                         contains relevant info, plus a list of "fields",
208                         or column objects */
209                 var node = oilsIDL[cls];
210                 var pkey = oilsRptFindField(node, node.pkey);
211
212                 /* a "field" is a parsed version of a column from the IDL,
213                         contains datatype, column name, etc. */
214                 var field = oilsRptFindField(node, col);
215
216                 /* re-construct the path as we go so 
217                         we know what all we've seen thus far */
218                 newpath = (newpath) ? newpath + '-'+ cls : cls;
219
220                 /* extract relevant info */
221                 tobj.table = node.table;
222                 tobj.path = newpath;
223                 tobj.alias = hex_md5(newpath);
224
225                 _debug('field type is ' + field.type);
226                 if( i == (parts.length - 2) ) break;
227
228                 /* we still have columns left in the path, keep adding join's */
229                 var path_col = col;
230                 if(field.reltype != 'has_a')
231                         col = pkey.name + '-' + col;
232
233                 tobj.join = {};
234                 tobj = tobj.join;
235
236                 tobj[col] = {};
237                 tobj = tobj[col];
238                 if( field.type == 'link' ) {
239                         tobj.key = field.key;
240                         if( field.reltype == 'has_many' || field.reltype == 'might_have' )
241                                 tobj.type = 'left';
242                 }
243
244                 newpath = newpath + '-'+ path_col;
245         }
246
247         _debug("built 'from' clause: path="+path+"\n"+formatJSON(js2JSON(obj)));
248         return obj;
249 }
250
251 function oilsMoveUpDisplayItems() {
252         var sel = oilsRptDisplaySelector;
253         var idx = sel.selectedIndex;
254         if( idx == 0 ) return;
255         var opt = sel.options[idx];
256         sel.options[idx] = null;
257         idx--;
258         var val = opt.getAttribute('value');
259         insertSelectorVal(sel, idx, opt.innerHTML, val);
260         sel.options[idx].selected = true;
261
262         var arr = oilsRpt.def.select;
263         for( var i = 0; i < arr.length; i++ ) {
264                 if( arr[i].path == val ) {
265                         var other = arr[i-1];
266                         arr[i-1] = arr[i];
267                         arr[i] = other;
268                         break;
269                 }
270         }
271         oilsRptDebug();
272 }
273
274 function oilsMoveDownDisplayItems() {
275         var sel = oilsRptDisplaySelector;
276         var idx = sel.selectedIndex;
277         if( idx == sel.options.length - 1 ) return;
278         var opt = sel.options[idx];
279         sel.options[idx] = null;
280         idx++;
281         var val = opt.getAttribute('value');
282         insertSelectorVal(sel, idx, opt.innerHTML, val);
283         sel.options[idx].selected = true;
284
285         var arr = oilsRpt.def.select;
286         for( var i = 0; i < arr.length; i++ ) {
287                 if( arr[i].path == val ) {
288                         var other = arr[i+1];
289                         arr[i+1] = arr[i];
290                         arr[i] = other;
291                         break;
292                 }
293         }
294         oilsRptDebug();
295 }
296
297
298 /* removes a specific item from the display window */
299 /*
300 function oilsDelDisplayItem(val) {
301         oilsDelSelectorItem(oilsRptDisplaySelector, val);
302 }
303 */
304
305 /* removes selected items from the display window */
306 function oilsDelSelectedDisplayItems() {
307         var list = oilsDelSelectedItems(oilsRptDisplaySelector);
308
309         _debug('deleting list: ' + list);
310
311         /* remove the de-selected columns from the report output */
312         oilsRpt.def.select = grep( oilsRpt.def.select, 
313                 function(i) {
314                         for( var j = 0; j < list.length; j++ ) {
315                                 var d = list[j]; /* path */
316                                 var col = i.column;
317
318                                 _debug('in delete, looking at list = '+d+' : col = ' + 
319                                         col.colname + ' : relation = ' + i.relation + ' : encoded = ' + hex_md5(oilsRptPathRel(d)) );
320
321                                 if( hex_md5(oilsRptPathRel(d)) == i.relation && oilsRptPathCol(d) == col.colname ) {
322                                         return false;
323                                 }
324                         }
325                         return true;
326                 }
327         );
328
329         if(!oilsRpt.def.select) oilsRpt.def.select = [];
330         oilsRptPruneFromList(list);
331         oilsRptDebug();
332 }
333
334 function oilsRptPruneFromList(pathlist) {
335
336         for( var j = 0; j < pathlist.length; j++ ) {
337                 /* if there are no items left in the "select", "where", or "having" clauses 
338                         for the given relation, trim this relation from the "from" clause */
339                 var path = pathlist[j];
340                 var encrel = hex_md5(oilsRptPathRel(path));
341
342                 debug('seeing if we can prune from clause with relation = ' + encrel +' : path = ' + path);
343
344                 var func = function(i){ return (i.relation == hex_md5(oilsRptPathRel(path))); };
345
346                 if(     !grep(oilsRpt.def.select, func) && 
347                                 !grep(oilsRpt.def.where, func) && 
348                                 !grep(oilsRpt.def.having, func) ) {
349
350                         debug('looks like we can prune ' + path);
351
352                         oilsRptPruneFromClause(oilsRptPathRel(pathlist[j]));
353                 }
354         }
355 }
356
357
358 /* for each item in the path list, remove the associated data
359         from the "from" clause */
360
361 function oilsRptPruneFromClause(relation, node) {
362
363         var keys = oilsRptObjectKeys(node);
364         _debug("trying to remove relation: " + relation+'\n\tthis object has keys: '+keys);
365
366         if(!node) node = oilsRpt.def.from.join;
367         if(!node) return false;
368
369         for( var i in node ) {
370                 var child_node = node[i];
371                 _debug("\tanalyzing child node: "+child_node.path);
372
373                 // first, descend into the tree, and prune leaves 
374                 if( child_node.join ) {
375
376                         oilsRptPruneFromClause(relation, child_node.join); 
377                         var join_keys = oilsRptObjectKeys(child_node.join);
378                         _debug("\tchild has a sub-join for items : ["+ join_keys+"]");
379
380                         if(join_keys.length == 0) {
381                                 _debug("\tdeleting join for object "+i);
382                                 delete child_node.join;
383                         }
384                 }
385
386                 if( !child_node.join ) {
387
388                         _debug("\tchild node has no sub-join, seeing if we should delete it");
389
390                         var from_alias = child_node.alias;
391                         var func = function(n){ return (n.relation == from_alias)};
392         
393                         if(     !grep(oilsRpt.def.select, func) &&
394                                         !grep(oilsRpt.def.where, func) &&
395                                         !grep(oilsRpt.def.having, func) ) {
396         
397                                 /* we are not used by any other clauses */
398                                 _debug("\tdeleting node with relation: "+ from_alias);
399                                 delete node[i];
400                                 return true;
401                         }
402                 }
403         }
404
405         return false;
406 }
407
408 function oilsRptMkFilterTags(path, tform, filter) {
409         var name = oilsRptMakeLabel(path);
410         if(tform) name += ' ('+tform+')';
411         name += ' "' + filter + '"';
412         var epath = path + ':'+filter+':';
413         if(tform) epath += tform;
414
415         return [ name, epath ];
416 }
417
418
419 function oilsAddRptFilterItem(path, tform, filter) {
420         _debug("Adding filter item for "+path+" tform="+tform+" filter="+filter);
421
422         var name = oilsRptMkFilterTags(path, tform, filter);
423         var epath = name[1];
424         name = name[0];
425
426         if( ! oilsAddSelectorItem(oilsRptFilterSelector, epath, name) )
427                 return;
428
429         var where = {
430                 relation: hex_md5(oilsRptPathRel(path)), 
431                 path : path,
432                 column:   { transform: tform, colname: oilsRptPathCol(path) },
433                 condition : {}
434         };
435         if( filter == 'is' || filter == 'is not' )
436                 where.condition[filter] = null;
437         else where.condition[filter] = oilsRptNextParam();
438
439         switch(tform) {
440                 case 'substring' : where.column.params = oilsRptNextParam();
441         }
442
443         oilsRpt.def.where.push(where);
444         mergeObjects( oilsRpt.def.from, oilsRptBuildFromClause(path));
445         oilsRptDebug();
446 }
447
448
449 function oilsAddRptHavingItem(path, tform, filter) {
450         _debug("Adding filter item for "+path+" tform="+tform+" filter="+filter);
451
452         var name = oilsRptMkFilterTags(path, tform, filter);
453         var epath = name[1];
454         name = name[0];
455
456         if( ! oilsAddSelectorItem(oilsRptHavingSelector, epath, name) )
457                 return;
458
459         var having = {
460                 relation: hex_md5(oilsRptPathRel(path)), 
461                 path : path,
462                 column:   { transform: tform, colname: oilsRptPathCol(path) },
463                 condition : {}
464         };
465         if( filter == 'is' || filter == 'is not' )
466                 having.condition[filter] = null;
467         else having.condition[filter] = oilsRptNextParam();
468
469         switch(tform) {
470                 case 'substring' : having.column.params = oilsRptNextParam();
471         }
472
473         oilsRpt.def.having.push(having);
474         mergeObjects( oilsRpt.def.from, oilsRptBuildFromClause(path));
475         oilsRptDebug();
476 }
477
478
479
480 function oilsDelSelectedFilterItems() {
481         _oilsDelSelectedFilterItems('where');
482 }
483 function oilsDelSelectedAggFilterItems() {
484         _oilsDelSelectedFilterItems('having');
485 }
486
487 function _oilsDelSelectedFilterItems(type) {
488
489         /* the values in this list are formed:  <path>:<operation>:<transform> */
490         var list = oilsDelSelectedItems(oilsRptFilterSelector);
491
492         for( var i = 0; i < list.length; i++ ) {
493                 var enc_path = list[i];
494                 var data = oilsRptParseFilterEncPath(enc_path);
495                 oilsRpt.def[type] = grep( 
496                         oilsRpt.def[type],
497                         function(f) { 
498                                 return oilsRptFilterDataMatches( 
499                                         f, data.path, data.operation, data.tform );
500                         }
501                 );
502         }
503
504         if(!oilsRpt.def[type]) oilsRpt.def[type] = [];
505         oilsRptPruneFromList(list);
506         oilsRptDebug();
507 }
508
509 function oilsRptParseFilterEncPath(item) {
510         return {
511                 path:           item.replace(/:.*/,''),
512                 operation:      item.replace(/.*:(.*):.*/,'$1'),
513                 tform:  item.replace(/.*?:.*?:(.*)/,'$1')
514         };
515 }
516
517
518 function oilsRptFilterDataMatches(filter, path, operation, tform) {
519         var rel = hex_md5(oilsRptPathRel(path));
520         var col = oilsRptPathCol(path);
521
522         if(     col == filter.column.colname &&
523                         rel == filter.relation &&       
524                         tform == filter.column.transform &&
525                         operation == oilsRptObjectKeys(filter)[0] ) return true;
526
527         return false;
528 }
529
530 /*
531 function oilsRptFilterGrep(flist, filter) {
532
533         for( var j = 0; j < flist.length; j++ ) {
534
535                 var fil = flist[j];
536                 var col = filter.column;
537                 var frel = hex_md5(oilsRptPathRel(fil.path));
538                 var fcol = oilsRptPathCol(fil.path);
539
540                 var op = oilsRptObjectKeys(filter.condition)[0];
541
542                 if(     frel == filter.relation && 
543                                 fcol == col.colname && 
544                                 fil.operation == op &&
545                                 fil.tform == col.transform ) {
546                                 return false;
547                 }
548         }
549         return true;
550 }
551 */
552
553 /* adds an item to the display window */
554 function oilsAddRptAggFilterItem(val) {
555         oilsAddSelectorItem(oilsRptHavingFilterSelector, val);
556 }
557
558 /* removes a specific item from the display window */
559 function oilsDelAggFilterItem(val) {
560         oilsDelSelectorItem(oilsRptHavingFilterSelector, val);
561 }
562
563
564
565 /*
566 function ___oilsDelSelectedAggFilterItems() {
567         var list = oilsDelSelectedItems(oilsRptHavingFilterSelector);
568         oilsRpt.def.having = grep( oilsRpt.def.having, 
569                 function(i) {
570                         for( var j = 0; j < list.length; j++ ) {
571                                 var d = list[j];
572                                 var col = i.column;
573
574                                 if( typeof col != 'string' ) 
575                                         for( var c in col ) col = col[c];
576
577                                 if( typeof col != 'string' ) col = col[0];
578
579                                 if( oilsRptPathRel(d) == i.relation && oilsRptPathCol(d) == col ) {
580                                 */
581                                 //      var param = (i.alias) ? i.alias.match(/::P\d*/) : null;
582                                         /*
583                                         if( param ) delete oilsRpt.params[param];
584                                         return false;
585                                 }
586                         }
587                         return true;
588                 }
589         );
590
591         if(!oilsRpt.def.having) oilsRpt.def.having = [];
592         oilsRptPruneFromList(list);
593         oilsRptDebug();
594 }
595 */
596
597
598 /* adds an item to the display window */
599 function oilsAddSelectorItem(sel, val, name) {
600         name = (name) ? name : oilsRptMakeLabel(val);
601         for( var i = 0; i < sel.options.length; i++ ) {
602                 var opt = sel.options[i];
603                 if( opt.value == val ) return false;
604         }
605         var opt = insertSelectorVal( sel, -1, name, val );
606         opt.setAttribute('title', name);
607         return true;
608 }
609
610
611 /* removes a specific item from the display window */
612 function oilsDelSelectorItem(sel, val) {
613         var opts = sel.options;
614         for( var i = 0; i < opts.length; i++ ) {
615                 var opt = opts[i];
616                 if( opt.value == val )  {
617                         if( i == opts.length - 1 ) 
618                                 opts[i] = null;
619                         else opts[i] = opts[i+1];
620                         return;
621                 }
622         }
623 }
624
625 /* removes selected items from the display window */
626 function oilsDelSelectedItems(sel) {
627         var list = getSelectedList(sel);
628         for( var i = 0; i < list.length; i++ ) 
629                 oilsDelSelectorItem(sel, list[i]);
630         return list;
631 }
632
633
634 /* hides the different field editor tabs */
635 function oilsRptHideEditorDivs() {
636         hideMe(DOM.oils_rpt_tform_div);
637         hideMe(DOM.oils_rpt_filter_div);
638         hideMe(DOM.oils_rpt_agg_filter_div);
639         hideMe(DOM.oils_rpt_order_by_div);
640
641         removeCSSClass(DOM.oils_rpt_tform_tab.parentNode, 'oils_rpt_tab_picker_selected');
642         removeCSSClass(DOM.oils_rpt_filter_tab.parentNode, 'oils_rpt_tab_picker_selected');
643         removeCSSClass(DOM.oils_rpt_agg_filter_tab.parentNode, 'oils_rpt_tab_picker_selected');
644 }
645
646
647 /**
648   This draws the 3-tabbed window containing the transform,
649   filter, and aggregate filter picker window
650   */
651 function oilsRptDrawDataWindow(path) {
652         var col = oilsRptPathCol(path);
653         var cls = oilsRptPathClass(path);
654         var field = oilsRptFindField(oilsIDL[cls], col);
655
656         appendClear(DOM.oils_rpt_editor_window_label, text(oilsRptMakeLabel(path)));
657         appendClear(DOM.oils_rpt_editor_window_datatype, text(field.datatype));
658
659         _debug("setting update data window for column "+col+' on class '+cls);
660
661         var div = DOM.oils_rpt_column_editor;
662         /* set a preliminary top position so the page won't bounce around */
663
664
665         /* XXX */
666         //div.setAttribute('style','top:'+oilsMouseX+'px');
667
668         /* unhide the div so we can determine the dimensions */
669         unHideMe(div);
670
671         /* don't let them see the floating div until the position is fully determined */
672         div.style.visibility='hidden'; 
673
674         oilsRptDrawTransformWindow(path, col, cls, field);
675         oilsRptDrawFilterWindow(path, col, cls, field);
676         oilsRptDrawHavingWindow(path, col, cls, field);
677         //oilsRptDrawOrderByWindow(path, col, cls, field);
678
679         //buildFloatingDiv(div, 600);
680
681         //window.scrollTo(0,0);
682         window.scrollTo(0, 60);
683
684         /* now let them see it */
685         div.style.visibility='visible';
686         oilsRptSetDataWindowActions(div);
687 }
688
689
690 function oilsRptSetDataWindowActions(div) {
691         /* give the tab links behavior */
692
693
694         DOM.oils_rpt_tform_tab.onclick = 
695                 function(){
696                         oilsRptHideEditorDivs();
697                         unHideMe(DOM.oils_rpt_tform_div)
698                         addCSSClass(DOM.oils_rpt_tform_tab.parentNode, 'oils_rpt_tab_picker_selected');
699                 };
700
701         DOM.oils_rpt_filter_tab.onclick = 
702                 function(){
703                         oilsRptHideEditorDivs();
704                         unHideMe(DOM.oils_rpt_filter_div)
705                         addCSSClass(DOM.oils_rpt_filter_tab.parentNode, 'oils_rpt_tab_picker_selected');
706                 };
707         DOM.oils_rpt_agg_filter_tab.onclick = 
708                 function(){
709                         oilsRptHideEditorDivs();
710                         unHideMe(DOM.oils_rpt_agg_filter_div)
711                         addCSSClass(DOM.oils_rpt_agg_filter_tab.parentNode, 'oils_rpt_tab_picker_selected');
712                 };
713
714         /*
715         DOM.oils_rpt_order_by_tab.onclick = 
716                 function(){
717                         oilsRptHideEditorDivs();
718                         oilsRptDrawOrderByWindow();
719                         unHideMe(DOM.oils_rpt_order_by_div);
720                         };
721                         */
722
723         DOM.oils_rpt_tform_tab.onclick();
724         DOM.oils_rpt_column_editor_close_button.onclick = function(){hideMe(div);};
725 }
726
727
728 function oilsRptDrawFilterWindow(path, col, cls, field) {
729
730         var tformPicker = new oilsRptTformPicker( {     
731                         node : DOM.oils_rpt_filter_tform_table,
732                         datatype : field.datatype,
733                         non_aggregate : true
734                 }
735         );
736
737         var filterPicker = new oilsRptFilterPicker({
738                         node : DOM.oils_rpt_filter_op_table,
739                         datatype : field.datatype
740                 }
741         );
742
743         DOM.oils_rpt_filter_submit.onclick = function() {
744                 oilsAddRptFilterItem(
745                         path, tformPicker.getSelected(), filterPicker.getSelected());
746         }
747 }
748
749
750 function oilsRptDrawHavingWindow(path, col, cls, field) {
751         var tformPicker = new oilsRptTformPicker( {     
752                         node : DOM.oils_rpt_agg_filter_tform_table,
753                         datatype : field.datatype,
754                         aggregate : true
755                 }
756         );
757
758         var filterPicker = new oilsRptFilterPicker({
759                         node : DOM.oils_rpt_agg_filter_op_table,
760                         datatype : field.datatype
761                 }
762         );
763
764         DOM.oils_rpt_agg_filter_submit.onclick = function() {
765                 oilsAddRptHavingItem(
766                         path, tformPicker.getSelected(), filterPicker.getSelected());
767         }
768 }
769
770 /* draws the transform window */
771 function oilsRptDrawTransformWindow(path, col, cls, field) {
772         DOM.oils_rpt_tform_label_input.value = oilsRptMakeLabel(path);
773         var dtype = field.datatype;
774
775         var tformPicker = new oilsRptTformPicker( {     
776                         node : DOM.oils_rpt_tform_table,
777                         datatype : field.datatype,
778                         non_aggregate : true,
779                         aggregate : true
780                 }
781         );
782
783         DOM.oils_rpt_tform_submit.onclick = 
784                 function(){ 
785                         oilsAddRptDisplayItem(path, 
786                                 DOM.oils_rpt_tform_label_input.value, tformPicker.getSelected() );
787                 };
788
789         DOM.oils_rpt_tform_label_input.focus();
790         DOM.oils_rpt_tform_label_input.select();
791
792         _debug("Building transform window for datatype "+dtype);
793 }
794
795
796 //function oilsRptDrawOrderByWindow(path, col, cls, field) {
797 function oilsRptDrawOrderByWindow() {
798         var sel = DOM.oils_rpt_order_by_selector;
799         removeChildren(sel);
800         DOM.oils_rpt_order_by_submit.onclick = function() {
801                 oilsRptAddOrderBy(getSelectorVal(sel));
802         }
803
804         var cols = oilsRpt.def.select;
805         for( var i = 0; i < cols.length; i++ ) {
806                 var obj = cols[i];
807                 insertSelectorVal(sel, -1, obj.alias, obj.path);
808         }
809 }
810
811 function oilsRptAddOrderBy(path) {
812         var rel = hex_md5(oilsRptPathRel(path));
813         var order_by = oilsRpt.def.order_by;
814
815         /* if this item is already in the order by remove it and overwrite it */
816         order_by = grep(oilsRpt.def.order_by, 
817                 function(i) {return (i.path != path)});
818         
819         if(!order_by) order_by = [];
820
821         /* find the column definition in the select blob */
822         var obj = grep(oilsRpt.def.select,
823                 function(i) {return (i.path == path)});
824         
825         if(!obj) return;
826         obj = obj[0];
827         
828         order_by.push({ 
829                 relation : obj.relation, 
830                 column : obj.column,
831                 direction : getSelectorVal(DOM.oils_rpt_order_by_dir)
832         });
833
834         oilsRpt.def.order_by = order_by;
835         oilsRptDebug();
836 }
837
838
839