/[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 11 - (hide annotations)
Fri Sep 10 12:42:58 2004 UTC (19 years, 7 months ago) by dpavlin
File MIME type: application/javascript
File size: 4833 byte(s)
combobox implementation by Matko Andjelinic

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

  ViewVC Help
Powered by ViewVC 1.1.26