/[bfilter]/trunk/bfilter.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/bfilter.js

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 10 by dpavlin, Fri Sep 10 12:16:21 2004 UTC revision 42 by dpavlin, Wed Dec 15 15:35:24 2004 UTC
# Line 4  Line 4 
4     Matko Andjelinic, matko.andjelinic@gmail.com 2004-09-09 (contributed OO implementation)     Matko Andjelinic, matko.andjelinic@gmail.com 2004-09-09 (contributed OO implementation)
5  */  */
6    
7    top.__bfilter_obj = new Array();
8    
9    
10  function BFilter(arr) {  function BFilter(arr) {
11          this.id_cache = Array();          this.id_cache = Array();
12          // total number of hits          // total number of hits
13          this.hits = 0;          this.hits = 0;
14          this.html_pre = '<a href="';  
15          this.html_mid = '">';          // store reference to this object for later (YAK)
16          this.html_post = '</a><br/>';          this.obj_count = top.__bfilter_obj.length;
17          this.html_full_pre = '';          top.__bfilter_obj[this.obj_count] = this;
18          this.html_full_post = '';  
19            // clear results html
20            this.results_html = null;
21    
22            // show results after 0.2s
23            this.timeout = 200;
24            this.timeout_handle = null;
25    
26          if (! arr) {          if (! arr) {
27                  this.debug("ERROR: can't search empty array");                  this.debug("ERROR: can't search empty array");
# Line 24  function BFilter(arr) { Line 32  function BFilter(arr) {
32          this.debug("index has "+this.arr.length+" parts");          this.debug("index has "+this.arr.length+" parts");
33    
34          if (! arr.min_len) {          if (! arr.min_len) {
35                  this.results("ERROR: index structure problem");                  alert("ERROR: index structure problem");
36                  return;                  return;
37          } else {          } else {
38                  this.min_len = arr.min_len;                  this.min_len = arr.min_len;
# Line 34  function BFilter(arr) { Line 42  function BFilter(arr) {
42    
43          this.show_status();          this.show_status();
44    
45            // show alert for non-existent elements?
46            this.show_alert = 1;
47    
48  }  }
49    
50  BFilter.prototype.element_id = function (id,no_alert) {  BFilter.prototype.element_id = function (id,no_alert) {
51          if (this.id_cache[id]) {          if (this.id_cache[id]) {
52                  return this.id_cache[id];                  return this.id_cache[id];
53          } else {          } else {
54                  var el = document.getElementById(id);                  var el = self.document.getElementById(id);
55                  if (el) {                  if (el) {
56                          this.id_cache[id] = el;                          this.id_cache[id] = el;
57                          return el;                          return el;
58                  } else {                  } else {
59                          if (! no_alert) {                          if (! no_alert && this.show_alert) {
60                                  alert("can't find element id: "+id);                                  this.show_alert = confirm("can't find element id: "+id);
61                          } else {                          } else {
62                                  // don't look it up again                                  // don't look it up again
63                                  this.id_cache[id] = null;                                  this.id_cache[id] = null;
64                          }                          }
65                  }                  }
66          }          }
67            return null;
68  }  }
69    
70    
71  BFilter.prototype.show_status = function (status) {  BFilter.prototype.show_status = function (query,no_hits) {
72          var html;          var html = "";
73          if (this.hits > 0) {          if (! no_hits) {
74                  html = "shown "+this.hits+" entries";                  if (this.hits > 0) {
75          } else {                          html = "shown "+this.hits+" entries";
76                  html = "no results";                  } else {
77                            html = "no results";
78                    }
79                    if (! status) {
80                            html = "Enter "+this.min_len+" letter"+(this.min_len == 1 ? '' : 's')+" to filter entries";
81                            status = "";
82                    }
83          }          }
84          if (! status) {          if (! query) {
85                  html = "Enter "+this.min_len+" letter"+(this.min_len == 1 ? '' : 's')+" to filter entries";                  html = "Enter "+this.min_len+" letter"+(this.min_len == 1 ? '' : 's')+" to filter entries";
86                  status = "";                  query = "";
87            } else {
88                    query = " for <em>"+query+"</em>";
89          }          }
90    
91          var el = this.element_id("status");          var el = this.element_id("status");
92          el.innerHTML = html+status+"\n";          el.innerHTML = html+query+"\n";
93    
94            return true;
95  }  }
96    
97  BFilter.prototype.results = function (html,clean) {  // this function is called to clean old results list
98    BFilter.prototype.clear_results = function () {
99            var results_div = this.element_id("results");
100            results_div.innerHTML = '';
101            this.results_html = '';
102            return true;
103    }
104    
105          if (! html) { html = ""; }  // this function is called for each result
106    BFilter.prototype.result = function (arr) {
107            this.results_html += '<li><a href="'+arr[1]+'">'+
108                    (this.hits % 2 == 0 ? '<span style="background: #e0e0e0;">' : '') +
109                    arr[0] +
110                    (this.hits % 2 == 0 ? '</span>' : '') +
111                    '</a></li>';
112            return true;
113    }
114    
115          // results_div.style.cursor = 'wait'; // 'auto'  // this function is called when updating innerHTML with results
116    BFilter.prototype.show_results = function () {
117          var results_div = this.element_id("results");          var results_div = this.element_id("results");
118          if (clean) {          if (this.results_html) {
119                  results_div.innerHTML = html + "\n";                  results_div.innerHTML = '<ul>'+this.results_html+'</ul>';
         } else {  
                 results_div.innerHTML += this.html_full_pre + html +"\n" + this.html_full_post;  
120          }          }
121            return true;
122  }  }
123    
   
124  BFilter.prototype.debug = function (html) {  BFilter.prototype.debug = function (html) {
125    
126          //return;          //return;
# Line 94  BFilter.prototype.debug = function (html Line 129  BFilter.prototype.debug = function (html
129          if (! html) { return 1; }          if (! html) { return 1; }
130    
131          var debug_div = this.element_id("debug",1);          var debug_div = this.element_id("debug",1);
132          if (! debug_div) { return; }          if (! debug_div) { return null; }
133    
134          if (debug_div.innerHTML) {          debug_div.innerHTML += html + "<br>\n";
135                  debug_div.innerHTML =+ html + "x<br>\n";  
136          } else {          return null;
                 debug_div.innerHTML = html + "y<br>\n";  
         }  
137  }  }
138    
139    
140  // modified binary search to find first element with substring  // modified binary search to find first element with substring
141  BFilter.prototype.binarySearch = function (arr, find) {  BFilter.prototype.binarySearch = function (arr, user_filter) {
142          if (!arr || typeof (find) == "undefined" || !arr.length) {          if (!arr || typeof (user_filter) == "undefined" || !arr.length) {
143                  return null;                  return null;
144          }          }
145          var low = 0;          var low = 0;
146          var high = arr.length - 1;          var high = arr.length - 1;
147          var middlearr = parseInt(arr.length / 2);          var middlearr = parseInt(arr.length / 2);
148            this.debug("binarySearch: "+low+"-("+middlearr+")-"+high+" for "+user_filter);
149          var lastTry;          var lastTry;
150          while (low <= high) {          while (low <= high) {
151                  var mid = (low + high) / 2;                  var mid = (low + high) / 2;
152                  var aTry = (mid < 1) ? 0 : parseInt(mid);                  var aTry = (mid < 1) ? 0 : parseInt(mid);
153                    
154                  var curr = arr[aTry][1].substr(0,find.length).toLowerCase();                  var curr = arr[aTry][0].substr(0,user_filter.length).toLowerCase();
155                  this.debug("low="+low+" high="+high+" lastTry="+lastTry+" "+aTry+": "+curr+"<br>");                  this.debug(low+"-"+high+", "+aTry+"="+curr+" last="+lastTry);
156                  if (curr < find) {                  if (curr < user_filter) {
157                          low = aTry + 1;                          low = aTry + 1;
158                          continue;                          continue;
159                  }                  }
160                  if (curr > find) {                  if (curr > user_filter) {
161                          high = aTry - 1;                          high = aTry - 1;
162                          continue;                          continue;
163                  }                  }
164                  if (curr == find) {                  if (curr == user_filter) {
165                          high = aTry - 1;                          high = aTry - 1;
166                          lastTry = aTry;                          lastTry = aTry;
167                          continue;                          continue;
168                  }                  }
169                  return aTry;                  return aTry;
170          }          }
171          this.debug("lastTry="+lastTry+"<br>");          this.debug("lastTry="+lastTry);
172    
173          if (typeof (lastTry) != "undefined") {          if (typeof (lastTry) != "undefined") {
174                  return lastTry;                  return lastTry;
# Line 143  BFilter.prototype.binarySearch = functio Line 177  BFilter.prototype.binarySearch = functio
177          }          }
178  }  }
179    
180  BFilter.prototype.filter = function (document, find) {  BFilter.prototype.filter = function (user_filter) {
181            this.debug("set timeout for "+this.obj_count+" to "+this.timeout);
182            if (this.timeout_handle) {
183                    clearTimeout(this.timeout_handle);
184                    this.timeout_handle = null;
185            }
186            this.timeout_handle=setTimeout("top.__bfilter_obj["+this.obj_count+"].show_filter('"+user_filter.replace(/'/,"\\'")+"');", this.timeout);
187            return true;
188    }
189    
190    BFilter.prototype.show_filter = function (user_filter) {
191    
192          this.results('',1);          this.show_status("Showing entries with <em>"+user_filter+"</em>\n");
193    
194            if (this.timeout_handle) {
195                    clearTimeout(this.timeout_handle);
196                    this.timeout_handle = null;
197                    this.debug("timeout cleared");
198            }
199    
200            this.clear_results();
201          this.hits = 0;          this.hits = 0;
202    
203          if (find.length < this.min_len) {          if (user_filter.length < this.min_len) {
204                  this.show_status();                  this.show_status();
205                  return;                  return;
206          }          }
207    
208          this.debug("filter: '"+find+"'<br>");          var user_filter_lc = user_filter.toLowerCase();
209            
210          var find_lc = find.toLowerCase();          this.debug("filter: '"+user_filter_lc+"'");
211    
212          var part = find_lc.substr(0,this.min_len);          var part = user_filter_lc.substr(0,this.min_len);
213    
214          // no part found          // no part found
215          if (! this.arr[part]) {          if (! this.arr[part]) {
216                  this.show_status(" for <em>"+find+"</em><br>");                  this.show_status(user_filter);
217                  this.debug("no part "+part);                  this.debug("no part "+part);
218                  return;                  return;
219          }          }
220    
221          // start anim icon          // start anim icon
222          //results("<img  src=\"pie.gif\">&nbsp;Please wait, filtering...\n",1);          //<img  src=\"pie.gif\">&nbsp;Please wait, filtering...
223    
224            var i;
225    
226          // full part? (optimization)          // full part? (optimization)
227          if (find.length == this.min_len) {          if (user_filter.length == this.min_len) {
228                  var html = '';                  for (i = 0; i < this.arr[part].length; i++) {
229                  for (var i = 0; i < this.arr[part].length; i++) {                          this.result(this.arr[part][i]);
                         html += this.html_pre +  
                                 this.arr[part][i][0] +  
                                 this.html_mid +  
                                 (this.hits % 2 == 0 ? '<span style="background: #e0e0e0">' : '');  
                         if (this.debug()) { html += i+": "; }  
                         html += this.arr[part][i][1] +  
                                 (this.hits % 2 == 0 ? '</span>' : '') +  
                                 this.html_post + "\n";  
230                          this.hits++;                          this.hits++;
231                  }                  }
232                  this.results(html);                  this.show_results();
233          } else {          } else {
234    
235                  var from = this.binarySearch(this.arr[part], find_lc);                  var from = this.binarySearch(this.arr[part], user_filter_lc);
236    
237                  if (from != null) {                  if (from != null) {
238                                    
239                          this.debug("loop "+from+" ... "+this.arr[part].length)+"<br>\n";                          this.debug("loop "+from+" ... "+this.arr[part].length);
   
                         var html = '';  
240    
241                          for(var i = from ; i < this.arr[part].length ; i++) {                          for(i = from ; i < this.arr[part].length ; i++) {
242                                  if (this.arr[part][i][1].substring(0,find.length).toLowerCase() != find_lc) {                                  if (this.arr[part][i][0].substring(0,user_filter.length).toLowerCase() != user_filter_lc) {
243                                          this.debug("loop exit at "+i);                                          this.debug("loop exit at "+i);
244                                          break;                                          break;
245                                  }                                  }
246                                  html += this.html_pre +                                  this.result(this.arr[part][i]);
                                         this.arr[part][i][0] +  
                                         this.html_mid +  
                                         (this.hits % 2 == 0 ? '<span style="background: #e0e0e0">' : '');  
                                 if (this.debug()) { html += i+": "; }  
                                 html += this.arr[part][i][1] +  
                                         (this.hits % 2 == 0 ? '</span>' : '') +  
                                         this.html_post + "\n";  
247                                  this.hits++;                                  this.hits++;
248                          }                          }
249    
250                          this.results(html);                          this.show_results();
251                  }                  }
252    
253          }          }
254    
255          this.show_status(" for <em>"+find+"</em>");          this.show_status(user_filter);
256    
257  }  }
258    
259    BFilter.prototype.show_all = function (user_filter) {
260    
261            this.show_status("Showing all entries\n");
262    
263            if (this.timeout_handle) {
264                    clearTimeout(this.timeout_handle);
265                    this.timeout_handle = null;
266                    this.debug("timeout cleared");
267            }
268    
269            this.clear_results();
270            this.hits = 0;
271    
272            for (part in this.arr) {
273                    // skip elements which are not really parts
274                    if (part == 'length' || part == 'min_len') continue;
275    
276                    this.debug("part: "+part);
277                    for(var i = 0 ; i < this.arr[part].length ; i++) {
278                            this.result(this.arr[part][i]);
279                            this.hits++;
280                    }
281    
282                    this.show_results();
283            }
284    
285            this.show_status(user_filter);
286    
287    }
288    

Legend:
Removed from v.10  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26