]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/reports/oils_rpt_builder.js
more filter work, still need to refactor parts of the delete call
[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         oilsInitReports();
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                 }
14         );
15 }
16
17 function oilsReportBuilderReset() {
18         var n = (oilsRpt) ? oilsRpt.name : "";
19         oilsRpt = new oilsReport();
20         oilsRpt.name = n;
21         oilsRptDisplaySelector  = DOM.oils_rpt_display_selector;
22         oilsRptFilterSelector   = DOM.oils_rpt_filter_selector;
23         oilsRptAggFilterSelector= DOM.oils_rpt_agg_filter_selector;
24         removeChildren(oilsRptDisplaySelector);
25         removeChildren(oilsRptFilterSelector);
26         removeChildren(oilsRptAggFilterSelector);
27         oilsRptDebug();
28         oilsRptResetParams();
29 }
30
31
32 /* adds an item to the display window */
33 function oilsAddRptDisplayItem(path, name, tform, params) {
34         if( ! oilsAddSelectorItem(oilsRptDisplaySelector, path, name) ) 
35                 return;
36
37         /* add the selected columns to the report output */
38         name = (name) ? name : oilsRptPathCol(path);
39         if( !tform ) tform = 'Bare';
40
41         /* add this item to the select blob */
42         var sel = {
43                 relation: oilsRptPathRel(path), 
44                 alias:    name,
45                 column:   { transform: tform, colname: oilsRptPathCol(path) }
46         };
47
48         if( params ) sel.column.params = params;
49         oilsRpt.def.select.push(sel);
50
51         mergeObjects( oilsRpt.def.from, oilsRptBuildFromClause(path));
52         oilsRptDebug();
53 }
54
55 /* takes a column path and builds a from-clause object for the path */
56 function oilsRptBuildFromClause(path) {
57
58         /* the path is the full path (relation) from the source 
59                 object to the column in question (e.g. au-home_ou-aou-name)*/
60         var parts = path.split(/-/);
61
62         /* the final from clause */
63         var obj = {}; 
64
65         /* reference to the current position in the from clause */
66         var tobj = obj; 
67
68         var newpath = "";
69
70         /* walk the path, fleshing the from clause as we go */
71         for( var i = 0; i < parts.length; i += 2 ) {
72
73                 var cls = parts[i]; /* class name (id) */
74                 var col = parts[i+1]; /* column name */
75
76                 /* a "node" is a class description from the IDL, it 
77                         contains relevant info, plus a list of "fields",
78                         or column objects */
79                 var node = oilsIDL[cls];
80                 var pkey = oilsRptFindField(node, node.pkey);
81
82                 /* a "field" is a parsed version of a column from the IDL,
83                         contains datatype, column name, etc. */
84                 var field = oilsRptFindField(node, col);
85
86                 /* re-construct the path as we go so 
87                         we know what all we've seen thus far */
88                 newpath = (newpath) ? newpath + '-'+ cls : cls;
89
90                 /* extract relevant info */
91                 tobj.table = node.table;
92                 tobj.alias = newpath;
93                 _debug('field type is ' + field.type);
94                 if( i == (parts.length - 2) ) break;
95
96                 /* we still have columns left in the path, keep adding join's */
97                 var path_col = col;
98                 if(field.reltype != 'has_a')
99                         col = pkey.name + '-' + col;
100
101                 tobj.join = {};
102                 tobj = tobj.join;
103
104                 tobj[col] = {};
105                 tobj = tobj[col];
106                 if( field.type == 'link' )
107                         tobj.key = field.key;
108
109                 newpath = newpath + '-'+ path_col;
110         }
111
112         _debug("built 'from' clause: path="+path+"\n"+formatJSON(js2JSON(obj)));
113         return obj;
114 }
115
116
117 /* removes a specific item from the display window */
118 function oilsDelDisplayItem(val) {
119         oilsDelSelectorItem(oilsRptDisplaySelector, val);
120 }
121
122 /* removes selected items from the display window */
123 function oilsDelSelectedDisplayItems() {
124         var list = oilsDelSelectedItems(oilsRptDisplaySelector);
125
126         /* remove the de-selected columns from the report output */
127         oilsRpt.def.select = grep( oilsRpt.def.select, 
128                 function(i) {
129                         for( var j = 0; j < list.length; j++ ) {
130                                 var d = list[j];
131                                 var col = i.column;
132
133                                 if( oilsRptPathRel(d) == i.relation && oilsRptPathCol(d) == col.colname ) {
134                                         //var param = (i.alias) ? i.alias.match(/::PARAM\d*/) : null;
135                                         //      if( param ) delete oilsRpt.params[param];
136                                         return false;
137                                 }
138                         }
139                         return true;
140                 }
141         );
142
143         if(!oilsRpt.def.select) {
144                 oilsRpt.def.select = [];
145                 //oilsReportBuilderReset();
146
147         } else {
148                 for( var j = 0; j < list.length; j++ ) 
149                         /* if there are no items left in the "select", "where", or "having" clauses 
150                                 for the given relation, trim this relation from the "from" clause */
151                         if(     !grep(oilsRpt.def.select,
152                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
153                                 && !grep(oilsRpt.def.where,
154                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
155                                 && !grep(oilsRpt.def.having,
156                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
157                         ) oilsRptPruneFromClause(oilsRptPathRel(list[j]));
158         }
159
160         oilsRptDebug();
161 }
162
163 /* for each item in the path list, remove the associated data
164         from the "from" clause */
165
166 function oilsRptPruneFromClause(relation, node) {
167         _debug("removing relation from 'from' clause " + relation);
168         if(!node) node = oilsRpt.def.from.join;
169         for( var i in node ) {
170                 if( node[i].alias == relation ) {
171                         if( node[i].join ) {
172                                 /* if we have subtrees, don't delete our tree node */
173                                 return false;
174                         } else {
175                                 delete node[i];
176                                 return true;
177                         } 
178                 } else {
179                         if( node[i].join ) {
180                                 if( oilsRptPruneFromClause(relation, node[i].join ) ) {
181                                         if(oilsRptObjectKeys(node[i].join).length == 0) {
182                                                 delete node[i].join;
183                                                 /* if there are no items in the select clause with a relation matching
184                                                         this nodes alias, we can safely remove this node from the tree */
185                                                 if(!grep(oilsRpt.def.select,function(r){return (r.relation==node[i].alias)}))
186                                                         delete node[i];
187                                                 return true;
188                                         }
189                                 }
190                         }
191                 }
192         }
193         return false;
194 }
195
196 function oilsRptFilterName(path, tform, filter) {
197 }
198
199 /* adds an item to the display window */
200 function oilsAddRptFilterItem(path, tform, filter) {
201         _debug("Adding filter item for "+path+" tform="+tform+" filter="+filter);
202
203         var name = oilsRptMakeLabel(path);
204         if(tform) name += ' ('+tform+')';
205         name += ' "' + filter + '"';
206
207         var epath = path + ':'+filter+':';
208         if(tform) epath += tform;
209
210         /*
211         if( ! oilsAddSelectorItem(oilsRptFilterSelector, path, name) )
212                 return;
213                 */
214
215         if( ! oilsAddSelectorItem(oilsRptFilterSelector, epath, name) )
216                 return;
217
218         var where = {
219                 relation: oilsRptPathRel(path), 
220                 column:   { transform: tform, colname: oilsRptPathCol(path) },
221                 condition : {}
222         };
223         where.condition[filter] = oilsRptNextParam();
224
225         switch(tform) {
226                 case 'substring' : where.column.params = oilsRptNextParam();
227         }
228
229         oilsRpt.def.where.push(where);
230         mergeObjects( oilsRpt.def.from, oilsRptBuildFromClause(path));
231         oilsRptDebug();
232 }
233
234 /* removes a specific item from the display window */
235 //function oilsDelFilterItem(path) {
236         //oilsDelSelectorItem(oilsRptFilterSelector, path);
237 //}
238
239 /* removes selected items from the display window */
240 function oilsDelSelectedFilterItems() {
241
242         /* the values in this list are formed:  <path>:<operation>:<tform (optional)> */
243         var list = oilsDelSelectedItems(oilsRptFilterSelector);
244
245         var flist = [];
246
247         for( var i = 0; i < list.length; i++ ) {
248                 var item = list[i];
249                 flist.push( {
250                         path:           item.replace(/:.*/,''),
251                         filter: item.replace(/.*:(.*):.*/,'$1'),
252                         tform:  item.replace(/.*?:.*?:(.*)/,'$1')
253                 });
254         }
255
256
257         /* XXX refactor the below to take operation and transform into account
258                 since the same path can be used multiple times as long as a different
259                 filter and/or transform is used */
260
261         /* remove the de-selected columns from the report output */
262         oilsRpt.def.where = grep( oilsRpt.def.where, 
263                 function(i) {
264                         for( var j = 0; j < list.length; j++ ) {
265                                 var d = list[j];
266                                 var col = i.column;
267
268                                 if( oilsRptPathRel(d) == i.relation && oilsRptPathCol(d) == col.colname ) {
269                                         var param = (i.alias) ? i.alias.match(/::PARAM\d*/) : null;
270                                         if( param ) delete oilsRpt.params[param];
271                                         return false;
272                                 }
273                         }
274                         return true;
275                 }
276         );
277
278         if(!oilsRpt.def.where) {
279                 oilsRpt.def.where = [];
280                 //oilsReportBuilderReset();
281
282         } else {
283                 for( var j = 0; j < list.length; j++ ) 
284                         /* if there are no items left in the "select", "where", or "having" clauses 
285                                 for the given relation, trim this relation from the "from" clause */
286                         if(     !grep(oilsRpt.def.select,
287                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
288                                 && !grep(oilsRpt.def.where,
289                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
290                                 && !grep(oilsRpt.def.having,
291                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
292                         ) oilsRptPruneFromClause(oilsRptPathRel(list[j]));
293         }
294
295         oilsRptDebug();
296 }
297
298 /* adds an item to the display window */
299 function oilsAddRptAggFilterItem(val) {
300         oilsAddSelectorItem(oilsRptAggFilterSelector, val);
301 }
302
303 /* removes a specific item from the display window */
304 function oilsDelAggFilterItem(val) {
305         oilsDelSelectorItem(oilsRptAggFilterSelector, val);
306 }
307
308 /* removes selected items from the display window */
309 function oilsDelSelectedAggFilterItems() {
310         var list = oilsDelSelectedItems(oilsRptAggFilterSelector);
311
312         /* remove the de-selected columns from the report output */
313         oilsRpt.def.having = grep( oilsRpt.def.having, 
314                 function(i) {
315                         for( var j = 0; j < list.length; j++ ) {
316                                 var d = list[j];
317                                 var col = i.column;
318
319                                 /* if this columsn has a transform, 
320                                         it will be an object { tform => column } */
321                                 if( typeof col != 'string' ) 
322                                         for( var c in col ) col = col[c];
323
324                                 /* if this transform requires params, the column 
325                                         will be the first item in the param set array */
326                                 if( typeof col != 'string' ) col = col[0];
327
328                                 if( oilsRptPathRel(d) == i.relation && oilsRptPathCol(d) == col ) {
329                                         var param = (i.alias) ? i.alias.match(/::PARAM\d*/) : null;
330                                         if( param ) delete oilsRpt.params[param];
331                                         return false;
332                                 }
333                         }
334                         return true;
335                 }
336         );
337
338         if(!oilsRpt.def.having) {
339                 oilsRpt.def.having = [];
340                 oilsReportBuilderReset();
341
342         } else {
343                 for( var j = 0; j < list.length; j++ ) 
344                         /* if there are no items left in the "select", "where", or "having" clauses 
345                                 for the given relation, trim this relation from the "from" clause */
346                         if(     !grep(oilsRpt.def.select,
347                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
348                                 && !grep(oilsRpt.def.where,
349                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
350                                 && !grep(oilsRpt.def.having,
351                                         function(i){ return (i.relation == oilsRptPathRel(list[j])); })
352                         ) oilsRptPruneFromClause(oilsRptPathRel(list[j]));
353         }
354
355         oilsRptDebug();
356 }
357
358
359 /* adds an item to the display window */
360 function oilsAddSelectorItem(sel, val, name) {
361         name = (name) ? name : oilsRptMakeLabel(val);
362         _debug("adding selector item "+name+' = ' +val);
363         for( var i = 0; i < sel.options.length; i++ ) {
364                 var opt = sel.options[i];
365                 if( opt.value == val ) return false;
366         }
367         insertSelectorVal( sel, -1, name, val );
368         return true;
369 }
370
371
372 /* removes a specific item from the display window */
373 function oilsDelSelectorItem(sel, val) {
374         _debug("deleting selector item "+val);
375         var opts = sel.options;
376         for( var i = 0; i < opts.length; i++ ) {
377                 var opt = opts[i];
378                 if( opt.value == val )  {
379                         if( i == opts.length - 1 ) 
380                                 opts[i] = null;
381                         else opts[i] = opts[i+1];
382                         return;
383                 }
384         }
385 }
386
387 /* removes selected items from the display window */
388 function oilsDelSelectedItems(sel) {
389         var list = getSelectedList(sel);
390         for( var i = 0; i < list.length; i++ ) 
391                 oilsDelSelectorItem(sel, list[i]);
392         return list;
393 }
394
395
396 /* hides the different field editor tabs */
397 function oilsRptHideEditorDivs() {
398         hideMe(DOM.oils_rpt_tform_div);
399         hideMe(DOM.oils_rpt_filter_div);
400         hideMe(DOM.oils_rpt_agg_filter_div);
401 }
402
403
404 /**
405   This draws the 3-tabbed window containing the transform,
406   filter, and aggregate filter picker window
407   */
408 function oilsRptDrawDataWindow(path) {
409         var col = oilsRptPathCol(path);
410         var cls = oilsRptPathClass(path);
411         var field = oilsRptFindField(oilsIDL[cls], col);
412
413         appendClear(DOM.oils_rpt_editor_window_label, text(oilsRptMakeLabel(path)));
414         appendClear(DOM.oils_rpt_editor_window_datatype, text(field.datatype));
415
416         _debug("setting update data window for column "+col+' on class '+cls);
417
418         var div = DOM.oils_rpt_column_editor;
419         /* set a preliminary top position so the page won't bounce around */
420         div.setAttribute('style','top:'+oilsMouseX+'px');
421
422         /* unhide the div so we can determine the dimensions */
423         unHideMe(div);
424
425         /* don't let them see the floating div until the position is fully determined */
426         div.style.visibility='hidden'; 
427
428         oilsRptDrawTransformWindow(path, col, cls, field);
429         oilsRptDrawFilterWindow(path, col, cls, field);
430
431         //oilsRptSetFilters(field.datatype);
432
433         //oilsRptDoFilterWidgets();
434
435         //DOM.oils_rpt_filter_tform_selector.onchange = oilsRptDoFilterWidgets;
436
437         buildFloatingDiv(div, 600);
438
439         /* now let them see it */
440         div.style.visibility='visible';
441
442         oilsRptSetDataWindowActions(div);
443 }
444
445
446 function oilsRptSetDataWindowActions(div) {
447         /* give the tab links behavior */
448         DOM.oils_rpt_tform_tab.onclick = 
449                 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_tform_div)};
450         DOM.oils_rpt_filter_tab.onclick = 
451                 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_filter_div)};
452         DOM.oils_rpt_agg_filter_tab.onclick = 
453                 function(){oilsRptHideEditorDivs();unHideMe(DOM.oils_rpt_agg_filter_div)};
454
455         DOM.oils_rpt_tform_tab.onclick();
456         DOM.oils_rpt_column_editor_close_button.onclick = function(){hideMe(div);};
457 }
458
459
460 function oilsRptDrawFilterWindow(path, col, cls, field) {
461
462         var fsel = $n(DOM.oils_rpt_filter_op_table,'selector');
463         for( var i = 0; i < fsel.options.length; i++ ){
464                 var opt = fsel.options[i];
465                 var dt = opt.getAttribute('datatype');
466                 _debug(dt);
467
468                 /* add a special case for boolean objects, since the only 
469                         operation that makes sense is "="  */
470                 if( field.datatype == 'bool' ) {
471                         hideMe(opt);
472                         if( opt.getAttribute('value') == '=' )
473                                 unHideMe(opt);
474
475                 } else {
476                         if( dt && dt != field.datatype )
477                                 hideMe(opt);
478                         else unHideMe(opt);
479                 }
480         }
481
482
483         DOM.oils_rpt_filter_submit.onclick = function() {
484                 var tsel = $n(DOM.oils_rpt_filter_tform_table,'selector');
485                 var tform = getSelectorVal(tsel);
486                 var filter = getSelectorVal(fsel);
487                 oilsAddRptFilterItem(path, tform, filter);
488         }
489         oilsRptShowFilters($n(DOM.oils_rpt_filter_tform_table,'selector'), field.datatype, false, true);
490                 
491         /*
492         oilsRptCurrentFilterTform = new oilsRptTFormManager(DOM.oils_rpt_filter_tform_table);
493         oilsRptCurrentFilterTform.build(field.datatype, false, true);
494         oilsRptCurrentFilterOpManager = new oilsRptOpManager(DOM.oils_rpt_filter_op_table);
495         */
496 }
497
498 function oilsRptShowFilters( selector, dtype, show_agg, show_noagg ) {
499         for( var i = 0; i < selector.options.length; i++ ) {
500                 var opt = selector.options[i];
501                 var t = opt.getAttribute('datatype');
502                 if( t && t != dtype ){
503                         hideMe(opt);
504                 } else {
505                         var ag = opt.getAttribute('aggregate');
506                         if( ag && show_agg )
507                                 unHideMe(opt);
508                         else if( ag && ! show_agg )
509                                 hideMe(opt)
510                         else if( !ag && show_noagg )
511                                 unHideMe(opt);
512                         else hideMe(opt);
513                 }
514         }
515 }
516
517
518 /* draws the transform window */
519 function oilsRptDrawTransformWindow(path, col, cls, field) {
520         DOM.oils_rpt_tform_label_input.value = oilsRptMakeLabel(path);
521         var dtype = field.datatype;
522
523         DOM.oils_rpt_tform_submit.onclick = 
524                 function(){ 
525                         var sel = $n(DOM.oils_rpt_tform_table,'selector');
526                         var tform = getSelectorVal(sel);
527                         oilsAddRptDisplayItem(path, DOM.oils_rpt_tform_label_input.value, tform ) 
528                 };
529
530
531         DOM.oils_rpt_tform_label_input.focus();
532         DOM.oils_rpt_tform_label_input.select();
533
534         /*
535         oilsRptCurrentTform = new oilsRptTFormManager(DOM.oils_rpt_tform_table);
536         oilsRptCurrentTform.build(dtype, true, true);
537         */
538
539         _debug($n(DOM.oils_rpt_tform_table,'selector'));
540
541         oilsRptShowFilters($n(DOM.oils_rpt_tform_table,'selector'), dtype, true, true);
542
543         /*
544         oilsRptHideTformFields();
545         oilsRptUnHideTformFields(dtype);
546         */
547
548         _debug("Building transform window for datatype "+dtype);
549
550         /*
551         unHideMe($('oils_rpt_tform_'+dtype+'_div'));
552         $('oils_rpt_tform_all_raw').checked = true;
553         */
554 }
555
556 /*
557 function oilsRptHideTformFields() {
558         var rows = DOM.oils_rpt_tform_tbody.childNodes;
559         for( var i = 0; i < rows.length; i++ )
560                 if( rows[i] && rows[i].nodeType == 1 )
561                         hideMe(rows[i]);
562 }
563
564 function oilsRptUnHideTformFields(dtype) {
565         var rows = DOM.oils_rpt_tform_tbody.childNodes;
566         for( var i = 0; i < rows.length; i++ ) {
567                 var row = rows[i]
568                 if( row && row.nodeType == 1 && 
569                         (row.getAttribute('datatype')=='all' 
570                                 || row.getAttribute('datatype') == dtype)) {
571                         unHideMe(row);
572                 }
573         }
574 }
575
576
577 function oilsRptGetTform(datatype) {
578         for( var i in oilsRptTransforms[datatype] ) 
579                 if( $('oils_rpt_tform_'+datatype+'_'+oilsRptTransforms[datatype][i]).checked )
580                         return oilsRptTransforms[datatype][i];
581         for( var i in oilsRptTransforms.all ) 
582                 if( $('oils_rpt_tform_all_'+oilsRptTransforms.all[i]).checked )
583                         return oilsRptTransforms.all[i];
584         return null;
585 }
586 */
587
588
589 /*
590 function getRptTformParams(type, tform) {
591         switch(type) {
592                 case 'string' :
593                         switch(tform) {
594                                 case 'substring' :
595                                         return [
596                                                 DOM.oils_rpt_tform_string_substring_offset.value, 
597                                                 DOM.oils_rpt_tform_string_substring_length.value];
598                         }
599         }
600 }
601 */
602
603
604 /* given a transform selector, this displays the appropriate 
605         transforms for the given datatype.
606         if aggregate is true, is displays the aggregate transforms */
607 /*
608 function oilsRptSetTransforms(sel, dtype, show_agg, show_noagg) {
609         for( var i = 0; i < sel.options.length; i++ ) {
610                 var opt = sel.options[i];
611                 var t = opt.getAttribute('datatype');
612                 if( t && t != dtype ){
613                         hideMe(opt);
614                 } else {
615                         var ag = opt.getAttribute('aggregate');
616                         if( ag && show_agg )
617                                 unHideMe(opt);
618                         else if( ag && ! show_agg )
619                                 hideMe(opt)
620                         else if( !ag && show_noagg )
621                                 unHideMe(opt);
622                         else
623                                 hideMe(opt);
624                 }
625         }
626 }
627 */
628
629
630 /* displays the correct filter-transforms for the given datatype */
631 /*
632 function oilsRptSetFilters(dtype) {
633
634         DOM.oils_rpt_filter_submit.onclick = function() {
635                 var data = oilsRptDoFilterWidgets();
636                 alert(js2JSON(data));
637         }
638
639         var sel = DOM.oils_rpt_filter_tform_selector;
640         for( var i = 0; i < sel.options.length; i++ ) {
641                 var opt = sel.options[i];
642                 _debug(opt.getAttribute('op'));
643                 var t = opt.getAttribute('datatype');
644                 if( t && t != dtype ) hideMe(opt);
645                 else unHideMe(opt);
646         }
647 }
648 */
649
650 /* hides all of the filter widgets */
651 function oilsRptHideFilterWidgets(node) {
652         if(!node)
653                 node = DOM.oils_rpt_filter_tform_widget_td;
654         if( node.nodeType != 1 ) return;
655         if( node.getAttribute('widget') ) {
656                 hideMe(node);
657         } else {
658                 var cs = node.childNodes;
659                 for( var i = 0; cs && i < cs.length; i++ )
660                         oilsRptHideFilterWidgets(cs[i]);
661         }
662 }
663
664 /* what does this need to do? */
665 function oilsRptSetFilterOpActions() {
666 }
667
668
669
670 /* hides/unhides the appropriate widgets and returns the parameter
671         array appropriate for the selected widget */
672 function oilsRptDoFilterWidgets() {
673         filter = getSelectorVal(DOM.oils_rpt_filter_tform_selector);
674         oilsRptHideFilterWidgets();
675         var op = null;
676         var tform = null;
677         var params = null;
678
679         switch(filter) {
680                 
681                 /* generic transforms */
682                 case 'equals':
683                         if(!op) op = 'equals';
684                 case 'like':
685                         if(!op) op = 'like';
686                 case 'ilike':
687                         if(!op) op = 'ilike';
688                 case 'gt':
689                         if(!op) op = '>';
690                 case 'gte':
691                         if(!op) op = '>=';
692                 case 'lt':
693                         if(!op) op = '<';
694                 case 'lte':
695                         if(!op) op = '<=';
696                 case 'in':
697                         if(!op) op = 'in';
698                 case 'not_in':
699                         if(!op) op = 'not in';
700                 case 'between':
701                         if(!op) op = 'between';
702                 case 'not_between':
703                         if(!op) op = 'not between';
704                         unHideMe(DOM.oils_rpt_filter_tform_input);      
705                         params = [DOM.oils_rpt_filter_tform_input.value];
706                         break;
707
708                 /* timestamp transforms */
709                 case 'date_between':
710                         if(!op) op = 'between';
711                 case 'date_not_between':
712                         if(!op) op = 'not between';
713                         tform = 'date';
714                         var d = new Date();
715                         unHideMe(DOM.oils_rpt_filter_tform_date_1);
716                         unHideMe(DOM.oils_rpt_filter_tform_date_2);
717                         unHideMe(DOM.oils_rpt_filter_tform_date_hint);
718                         DOM.oils_rpt_filter_tform_date_1.value = mkYearMonDay();
719                         DOM.oils_rpt_filter_tform_date_2.value = mkYearMonDay();
720                         params = [
721                                 DOM.oils_rpt_filter_tform_date_1.value,
722                                 DOM.oils_rpt_filter_tform_date_2.value
723                         ];
724                         break;
725
726                 case 'dow_between':
727                         op = 'between';
728                         if(!tform) tform = 'dow';
729                 case 'dow_not_between':
730                         if(!op) op = 'not between';
731                         if(!tform) tform = 'dow';
732                         break;
733
734                 case 'dom_between':
735                         op = 'between';
736                         if(!tform) tform = 'dom';
737                 case 'dom_not_between':
738                         if(!op) op = 'not between';
739                         if(!tform) tform = 'dom';
740                         break;
741
742                 case 'month_between':
743                         op = 'between';
744                         if(!tform) tform = 'moy';
745                 case 'month_not_between':
746                         if(!op) op = 'not between';
747                         if(!tform) tform = 'moy';
748                         break;
749
750                 case 'quarter_between':
751                         op = 'between';
752                         if(!tform) tform = 'qoy';
753                 case 'quarter_not_between':
754                         if(!op) op = 'not between';
755                         if(!tform) tform = 'qoy';
756                         break;
757
758                 case 'year_between':
759                         if(!op) op = 'between';
760                         if(!tform) tform = 'year_trunc';
761                 case 'year_not_between':
762                         if(!op) op = 'not between';
763                         if(!tform) tform = 'year_trunc';
764                         break;
765
766                 case 'age_between':
767                         if(!op) op = 'between';
768                         if(!tform) tform = 'age';
769                 case 'age_not_between':
770                         if(!op) op = 'not between';
771                         if(!tform) tform = 'age';
772                         break;
773
774                 /* string transforms */
775                 case 'substring':
776                         if(!tform) tform = 'substring';
777                         break;
778
779                 case 'lower':
780                         if(!op) op = '';
781                         if(!tform) tform = 'dow';
782
783                 case 'upper':
784                         if(!op) op = '';
785                         if(!tform) tform = 'dow';
786
787                 /* numeric transforms */
788                 case 'round':
789                         if(!op) op = '';
790                         if(!tform) tform = 'dow';
791
792                 case 'int':
793                         if(!op) op = '';
794                         if(!tform) tform = 'dow';
795         }
796
797         return { op : op, params : params, tform : tform };
798 }
799
800
801
802