/[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

Annotation of /trunk/bfilter.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (hide annotations)
Wed Sep 15 15:30:04 2004 UTC (19 years, 7 months ago) by dpavlin
File MIME type: application/javascript
File size: 4460 byte(s)
major refacture: 0 element is searched, all others can be used in result
function to generate html specific to one result. All that will be displayed
by calling display function which can add additional markup before or after
results.

1 dpavlin 1 /*
2     Fast filtering function using pre-sorted list elements
3     Dobrica Pavlinusic, dpavlin@rot13.org 2004-09-06
4 dpavlin 10 Matko Andjelinic, matko.andjelinic@gmail.com 2004-09-09 (contributed OO implementation)
5 dpavlin 1 */
6    
7 dpavlin 2
8 dpavlin 10 function BFilter(arr) {
9     this.id_cache = Array();
10     // total number of hits
11     this.hits = 0;
12 dpavlin 1
13 dpavlin 25 // this function is called for each result
14     this.result = function (arr) {
15     return '<li><a href="'+arr[1]+'">'+
16     (this.hits % 2 == 0 ? '<span style="background: #e0e0e0;">' : '') +
17     arr[0] +
18     (this.hits % 2 == 0 ? '</span>' : '') +
19     '</a></li>';
20     }
21    
22     // this function is called when updating innerHTML with results
23     this.display = function (html) {
24     return '<ul>'+html+'</ul>';
25     }
26    
27    
28 dpavlin 10 if (! arr) {
29     this.debug("ERROR: can't search empty array");
30     return;
31     }
32 dpavlin 1
33 dpavlin 10 this.arr = arr;
34     this.debug("index has "+this.arr.length+" parts");
35    
36     if (! arr.min_len) {
37     this.results("ERROR: index structure problem");
38     return;
39 dpavlin 1 } else {
40 dpavlin 10 this.min_len = arr.min_len;
41     }
42    
43     this.debug("index part has "+this.min_len+" parts");
44    
45     this.show_status();
46    
47     }
48    
49     BFilter.prototype.element_id = function (id,no_alert) {
50     if (this.id_cache[id]) {
51     return this.id_cache[id];
52     } else {
53 dpavlin 1 var el = document.getElementById(id);
54     if (el) {
55 dpavlin 10 this.id_cache[id] = el;
56 dpavlin 1 return el;
57     } else {
58 dpavlin 10 if (! no_alert) {
59     alert("can't find element id: "+id);
60     } else {
61     // don't look it up again
62     this.id_cache[id] = null;
63     }
64 dpavlin 1 }
65     }
66 dpavlin 22 return null;
67 dpavlin 1 }
68    
69    
70 dpavlin 10 BFilter.prototype.show_status = function (status) {
71 dpavlin 1 var html;
72 dpavlin 10 if (this.hits > 0) {
73     html = "shown "+this.hits+" entries";
74 dpavlin 1 } else {
75     html = "no results";
76     }
77     if (! status) {
78 dpavlin 10 html = "Enter "+this.min_len+" letter"+(this.min_len == 1 ? '' : 's')+" to filter entries";
79 dpavlin 1 status = "";
80     }
81    
82 dpavlin 10 var el = this.element_id("status");
83 dpavlin 1 el.innerHTML = html+status+"\n";
84     }
85    
86 dpavlin 10 BFilter.prototype.results = function (html,clean) {
87 dpavlin 1
88     if (! html) { html = ""; }
89    
90     // results_div.style.cursor = 'wait'; // 'auto'
91 dpavlin 10 var results_div = this.element_id("results");
92 dpavlin 1 if (clean) {
93 dpavlin 25 results_div.innerHTML = html;
94 dpavlin 1 } else {
95 dpavlin 25 results_div.innerHTML += this.display(html);
96 dpavlin 1 }
97     }
98    
99 dpavlin 10
100     BFilter.prototype.debug = function (html) {
101    
102     //return;
103    
104     // check if debugging is on
105     if (! html) { return 1; }
106    
107     var debug_div = this.element_id("debug",1);
108 dpavlin 22 if (! debug_div) { return null; }
109 dpavlin 10
110 dpavlin 12 debug_div.innerHTML += html + "<br>\n";
111 dpavlin 22
112     return null;
113 dpavlin 10 }
114    
115    
116 dpavlin 2 // modified binary search to find first element with substring
117 dpavlin 10 BFilter.prototype.binarySearch = function (arr, find) {
118 dpavlin 6 if (!arr || typeof (find) == "undefined" || !arr.length) {
119 dpavlin 2 return null;
120     }
121     var low = 0;
122     var high = arr.length - 1;
123     var middlearr = parseInt(arr.length / 2);
124     var lastTry;
125     while (low <= high) {
126     var mid = (low + high) / 2;
127     var aTry = (mid < 1) ? 0 : parseInt(mid);
128    
129 dpavlin 25 var curr = arr[aTry][0].substr(0,find.length).toLowerCase();
130 dpavlin 12 this.debug("low="+low+" high="+high+" lastTry="+lastTry+" "+aTry+": "+curr);
131 dpavlin 2 if (curr < find) {
132     low = aTry + 1;
133     continue;
134     }
135     if (curr > find) {
136     high = aTry - 1;
137     continue;
138     }
139     if (curr == find) {
140     high = aTry - 1;
141     lastTry = aTry;
142     continue;
143     }
144     return aTry;
145     }
146 dpavlin 12 this.debug("lastTry="+lastTry);
147 dpavlin 1
148 dpavlin 2 if (typeof (lastTry) != "undefined") {
149     return lastTry;
150     } else {
151     return null;
152     }
153     }
154    
155 dpavlin 10 BFilter.prototype.filter = function (document, find) {
156 dpavlin 1
157 dpavlin 10 this.results('',1);
158     this.hits = 0;
159 dpavlin 1
160 dpavlin 10 if (find.length < this.min_len) {
161     this.show_status();
162 dpavlin 1 return;
163     }
164    
165 dpavlin 12 this.debug("filter: '"+find+"'");
166 dpavlin 1
167     var find_lc = find.toLowerCase();
168    
169 dpavlin 10 var part = find_lc.substr(0,this.min_len);
170 dpavlin 1
171     // no part found
172 dpavlin 10 if (! this.arr[part]) {
173     this.show_status(" for <em>"+find+"</em><br>");
174     this.debug("no part "+part);
175 dpavlin 1 return;
176     }
177    
178     // start anim icon
179     //results("<img src=\"pie.gif\">&nbsp;Please wait, filtering...\n",1);
180    
181 dpavlin 22 var i;
182    
183 dpavlin 1 // full part? (optimization)
184 dpavlin 10 if (find.length == this.min_len) {
185 dpavlin 1 var html = '';
186 dpavlin 22 for (i = 0; i < this.arr[part].length; i++) {
187 dpavlin 25 html += this.result(this.arr[part][i]);
188 dpavlin 10 this.hits++;
189 dpavlin 1 }
190 dpavlin 10 this.results(html);
191 dpavlin 1 } else {
192    
193 dpavlin 10 var from = this.binarySearch(this.arr[part], find_lc);
194 dpavlin 1
195 dpavlin 2 if (from != null) {
196    
197 dpavlin 12 this.debug("loop "+from+" ... "+this.arr[part].length);
198 dpavlin 5
199 dpavlin 22 html = '';
200 dpavlin 5
201 dpavlin 22 for(i = from ; i < this.arr[part].length ; i++) {
202 dpavlin 25 if (this.arr[part][i][0].substring(0,find.length).toLowerCase() != find_lc) {
203 dpavlin 10 this.debug("loop exit at "+i);
204 dpavlin 2 break;
205     }
206 dpavlin 25 html += this.result(this.arr[part][i]);
207 dpavlin 10 this.hits++;
208 dpavlin 1 }
209 dpavlin 5
210 dpavlin 10 this.results(html);
211 dpavlin 1 }
212    
213     }
214    
215 dpavlin 10 this.show_status(" for <em>"+find+"</em>");
216 dpavlin 1
217     }
218    

  ViewVC Help
Powered by ViewVC 1.1.26