31ab09c3bdfdba9026ba5d573258c2f3a6c80d9e
[plewww.git] / plekit / table / table.js
1 var debug=false;
2
3 /* for debugging purposes */
4 function plc_timestamp () {
5   var now = new Date();
6   return now.getMinutes() + ':' + now.getSeconds() + '.' + now.getMilliseconds() ; 
7 }
8
9 function plc_message (message) {
10   console.log ( plc_timestamp() + ' : ' + message);
11 }
12
13 /* when a table gets paginated, displays context info */
14 function plekit_table_paginator (opts,table_id) {
15
16   if(!("currentPage" in opts)) { return; }
17     
18   var p = document.createElement('p');
19   var table=$(table_id);
20   var t = $(table_id+'-fdtablePaginaterWrapTop');
21   var b = $(table_id+'-fdtablePaginaterWrapBottom');
22
23   /* when there's no visible entry, the pagination code removes the wrappers */
24   if ( (!t) || (!b) ) return;
25
26   /* get how many entries are matching:
27      opts.visibleRows only holds the contents of the current page
28      so we store the number of matching entries in the table 'matching' attribute
29   */
30   var totalMatches = opts.totalRows;
31   var matching=table['matching'];
32   if (matching) totalMatches = matching;
33
34   var label;
35
36   var matches_text;
37   if (totalMatches != opts.totalRows) {
38     matches_text = totalMatches + "/" + opts.totalRows;
39   } else {
40     matches_text = opts.totalRows;
41   }
42   var first = ((opts.currentPage-1) * opts.rowsPerPage) +1;
43   var last = Math.min((opts.currentPage * opts.rowsPerPage),totalMatches);
44   var items_text = "Items [" + first + " - " + last + "] of " + matches_text;
45   var page_text = "Page " + opts.currentPage + " of " + Math.ceil(totalMatches / opts.rowsPerPage);
46   label = items_text + " -- " + page_text;
47
48   p.className = "paginationText";    
49   p.appendChild(document.createTextNode(label));
50
51   /*  t.insertBefore(p.cloneNode(true), t.firstChild); */
52   b.appendChild(p);
53 }
54
55
56 /* locates a table from its id and alters the classname to reflect new table size */
57 function plekit_pagesize_set (table_id,size_id,def_size) {
58   var table=document.getElementById(table_id);
59   var size_area=document.getElementById(size_id);
60   if ( ! size_area.value ) {
61     size_area.value=def_size;
62   }
63   var size=size_area.value;
64   table.className=table.className.replace(/paginate-\d+/,"paginate-"+size); 
65   tablePaginater.init(table_id);
66 }
67
68 function plekit_pagesize_reset(table_id, size_id, size) {
69   var table=document.getElementById(table_id);
70   var size_area=document.getElementById(size_id);
71   size_area.value=size;
72   table.className=table.className.replace(/paginate-\d+/,"paginate-"+size); 
73   tablePaginater.init(table_id);
74 }
75   
76 /* set or clear the ' invisibleRow' in the tr's classname, according to visible */
77 function plekit_table_row_visible (row,visible) {
78   var cn=row.className;
79   /* clear */
80   cn=cn.replace("invisibleRow","");
81   cn.strip();
82   if (! visible) cn += " invisibleRow";
83   row.className=cn;
84 }
85
86 // Working around MSIE...
87 if ('undefined' == typeof Node)
88     Node = { ELEMENT_NODE: 1, TEXT_NODE: 3 };
89
90 // Extract actual text from a DOM node (remove internal tags and so on)
91 function getInnerText(node) {
92         var result = '';
93         if (Node.TEXT_NODE == node.nodeType)
94                 return node.nodeValue;
95         if (Node.ELEMENT_NODE != node.nodeType)
96                 return '';
97         for (var index = 0; index < node.childNodes.length; ++index)
98                 result += getInnerText(node.childNodes.item(index));
99         return result;
100 } // getInnerText
101
102 // cache in the <tr> node the concatenation of the innerTexts of its cells
103 function plekit_tr_text (tr) {
104   // if cached, use it
105   if (tr['text_to_match']) return tr['text_to_match'];
106   // otherwise compute it
107   var text="";
108   var cells=tr.cells;
109   for (var i=0; i<cells.length; i++) 
110     text += getInnerText(cells[i]) + " ";
111   text = text.strip().toLowerCase();
112   tr['text_to_match'] = text;
113   return text;
114 }
115
116 var plekit_table_filter_timeout = null;
117 /* scan the table, and mark as visible 
118    the rows that match (either AND or OR the patterns) */
119 function plekit_table_filter(table_id,pattern_id,and_id) {
120   clearTimeout(plekit_table_filter_timeout);
121   plekit_table_filter_timeout = setTimeout(function() {
122                                              plekit_lazy_table_filter(table_id,pattern_id,and_id)
123                                            },
124                                            200);
125 }
126
127 function plekit_lazy_table_filter (table_id,pattern_id,and_id) {
128
129   if (debug) plc_message ('entering plekit_lazy_table_filter');
130
131   var table=$(table_id);
132   var css='#'+table_id+'>tbody';
133   var rows = $$(css)[0].rows;
134   var pattern_area = $(pattern_id);
135   var pattern_text = pattern_area.value;
136   var matching_entries=0;
137   var and_button=$(and_id);
138   var and_if_true=and_button.checked;
139
140   // canonicalize white spaces 
141   pattern_text = pattern_text.replace(/^\s+/, '').replace(/\s+$/, '').replace(/\s+/g,' ');
142   
143   if (pattern_text.indexOf ("&") != -1) {
144     pattern_text = pattern_text.replace(/&/," ");
145     pattern_area.value=pattern_text;
146     and_button.checked=true;
147     return;
148   } else if (pattern_text.indexOf ("|") != -1 ) {
149     pattern_text = pattern_text.replace(/\|/," ");
150     pattern_area.value=pattern_text;
151     and_button.checked=false;
152     return;
153   }
154     
155   var match_attempts=0;
156   var start=(new Date).getTime();
157
158   // if we're running with the same pattern
159   var previous_pattern=table['previous_pattern'];
160   var previous_mode=table['previous_mode'];
161   if ( (previous_pattern == pattern_text) && (previous_mode == and_if_true) ) {
162     return;
163   }
164
165   if (debug) plc_message ('inside plekit_lazy_table_filter');
166
167   var searches=new Array();
168   var patterns=new Array();
169   if (pattern_text.length > 0) {
170       // re compile all patterns 
171       var pattern_texts = pattern_text.strip().split(" ");
172       for (var i=0; i < pattern_texts.length; i++) {
173           // ignore case
174           searches[i]=pattern_texts[i].toLowerCase();
175           patterns[i]=new RegExp(pattern_texts[i],"i");
176       }
177   }
178
179   // scan rows, elaborate 'visible'
180   for (var row_index = 0; row_index < rows.length ; row_index++) {
181     var tr=rows[row_index];
182     var visible=false;
183     
184     /*empty pattern */
185     if (patterns.length == 0) {
186       visible=true;
187     } else if (and_if_true) {
188       /* AND mode: all patterns must match */
189       visible=true;
190       var against=plekit_tr_text (tr);
191       for (var search_index=0; search_index<searches.length; search_index++) {
192         var search=searches[search_index];
193         match_attempts++;
194         if ( against.search(search) < 0) {
195           visible=false;
196           break;          
197         }
198       }
199     } else {
200       /* OR mode: any match is good enough */
201       visible=false;
202       var against = plekit_tr_text(tr);
203       for (var search_index=0; search_index < searches.length; search_index++) {
204         var search=searches[search_index];
205         match_attempts++;
206         if (against.search(search) >= 0) {
207           visible=true;
208           break;
209         }
210       }
211     }
212
213     plekit_table_row_visible(tr,visible);
214     if (visible) matching_entries +=1;
215   }
216   // save for next run
217   table['previous_pattern']=pattern_text;
218   table['previous_mode']=and_if_true;
219   
220   var end=(new Date).getTime();
221   var match_ms=end-start;
222
223   if (debug) plc_message ('almost at end of plekit_lazy_table_filter');
224
225   // optimize useless calls to init, by comparing # of matching entries
226   var previous_matching=table['previous_matching'];
227   if (matching_entries == previous_matching) {
228     return;
229   }
230   
231   table['matching']=matching_entries;
232   table['match_attempts']=match_attempts;
233   tablePaginater.init(table_id);
234   var end2=(new Date).getTime();
235   var paginate_ms=end2-end;
236
237   if (debug) plc_message ('exiting plekit_lazy_table_filter with paginate_ms=' + paginate_ms);
238
239 }
240
241 function plekit_table_filter_reset (table_id, pattern_id,and_id) {
242   /* reset pattern */
243   document.getElementById(pattern_id).value="";
244   plekit_table_filter (table_id, pattern_id,and_id);
245 }