PageSourceSearch

https://www.bestbassgear.com/js/mirasvit/code/searchautocomplete/autocomplete.js?q=051216

js bestbassgear.com collected 2026-10-02 17:58:29 UTC 8,867 bytes, 344 lines download raw bytes

1jQuery.noConflict();
2jQuery(function($) {
3
4SearchAutocomplete = Backbone.View.extend({
5    url           : null,
6    result        : null,
7    suggest       : null,
8    query         : null,
9    delay         : 100,
10    queryMinChars : 3,
11    shown         : false,
12
13    events : {
14        'keydown .UI-SEARCH'  : 'onKeydown',
15        'keyup .UI-SEARCH'    : 'onKeyup',
16        'blur .UI-SEARCH'     : 'onBlur',
17        'focus .UI-SEARCH'    : 'onFocus',
18        'change .UI-CATEGORY' : 'onChangeCategory'
19    },
20
21    initialize: function()
22    {
23        var self = this;
24        _.bindAll(self);
25    },
26
27    init: function(el)
28    {
29        var self = this;
30
31        self.setElement(el);
32
33        self.url           = self.$el.attr('data-url');
34        self.delay         = self.$el.attr('data-delay');
35        self.queryMinChars = self.$el.attr('data-minchars');
36        self.$listenField  = $('.UI-SEARCH', self.$el);
37        self.$suggestField = $('.UI-SEARCH-SUGGEST', self.$el);
38        self.$placeholder  = $('.UI-PLACEHOLDER', self.$el);
39        self.$loader       = $('.UI-LOADER', self.$el);
40        self.$category     = $('.UI-CATEGORY', self.$el);
41        self.$categoryText = $('.UI-CATEGORY-TEXT', self.$el);
42        self.result        = '';
43        self.query         = self.$listenField.val();
44
45        self.baseWidth = $('.UI-NAV-INPUT').width();
46
47        self.onChangeCategory();
48    },
49
50    onChangeCategory: function()
51    {
52        var self = this;
53        var text = $('option:selected', self.$category).text();
54
55        if (self.$categoryText.length) {
56            self.$categoryText.html(text);
57            $('.UI-NAV-INPUT').css('padding-left', self.$categoryText.width() + 35);
58            $('.UI-CATEGORY').css('width', self.$categoryText.width() + 35);
59            // $('.UI-NAV-INPUT').css('width', self.baseWidth -(self.$categoryText.width() + 35));
60        }
61
62        self.result = '';
63    },
64
65    onKeydown: function(e)
66    {
67        var self = this;
68        e.stopPropagation();
69
70        if (!self.shown) {
71            return;
72        }
73
74        switch(e.keyCode) {
75            case 13: // enter
76                return;
77
78            case 9: // tab
79            case 27: // escape
80                e.preventDefault();
81                break;
82
83            case 38: // up arrow
84                e.preventDefault();
85                self.prev();
86                break;
87
88            case 40: // down arrow
89                e.preventDefault();
90                self.next();
91                break;
92        }
93    },
94
95    onKeyup: function(e)
96    {
97        var self = this;
98        e.stopPropagation();
99        e.preventDefault();
100
101        switch(e.keyCode) {
102            case 40: // down arrow
103            case 38: // up arrow
104                break;
105
106            case 27: // escape
107                self.hide();
108                break;
109
110            case 13:
111                if (!self.shown) {
112                    return;
113                }
114
115                if ($('.active', self.$placeholder).length) {
116                    self.select();
117                }
118                break;
119
120            default:
121                var q = self.$listenField.val();
122                window.setTimeout(function() {
123                    if (q == self.$listenField.val() && self.$listenField.val() != self.query) {
124                        self.lookup();
125                    }
126                }, self.delay);
127
128                self.$placeholder.html(self.result);
129                self.highlighter(self.$placeholder);
130        }
131    },
132
133    onBlur: function(e)
134    {
135        var self = this;
136
137        setTimeout(function() {
138            self.select();
139        }, 300);
140    },
141
142    onFocus: function (e)
143    {
144        var self = this;
145
146        if (self.query.length >= self.queryMinChars) {
147            if (self.result == '') {
148                self.lookup();
149            } else {
150                self.show();
151            }
152        }
153    },
154
155    mouseover: function (e)
156    {
157        var self = this;
158
159        $('.active', self.$placeholder).removeClass('active');
160
161        $(e.currentTarget).addClass('active');
162    },
163
164    mouseout: function (e)
165    {
166        $(e.currentTarget).removeClass('active');
167    },
168
169    click: function (e)
170    {
171        var self = this;
172        e.stopPropagation();
173        e.preventDefault();
174
175        self.select();
176    },
177
178    next: function (e)
179    {
180        var self = this;
181        var next;
182
183        var $active = $('.active', self.$placeholder);
184        $active.removeClass('active');
185
186        if ($active.length === 0) {
187            next = $($('li', self.$placeholder).get(0));
188        } else {
189            next = $active.next();
190        }
191
192        if (next) {
193            next.addClass('active');
194        }
195    },
196
197    prev: function (e)
198    {
199        var self = this;
200        var prev;
201
202        var active = $('.active', self.$placeholder);
203        active.removeClass('active');
204
205        if (active.length === 0) {
206            prev = $($('li', self.$placeholder).get($('li', self.$placeholder).length - 1));
207        } else {
208            prev = active.prev();
209        }
210
211        if (prev) {
212            prev.addClass('active');
213        }
214    },
215
216    select: function()
217    {
218        var self = this;
219
220        if ($('.active', self.$placeholder).length) {
221            var val = $('.active', self.$placeholder).attr('data-url');
222            window.location.href = val;
223        }
224
225        return this.hide();
226    },
227
228    lookup: function ()
229    {
230        var self = this;
231
232        self.query = self.$listenField.val();
233        if (self.query.length >= self.queryMinChars) {
234            self.process(self.query);
235        } else {
236            self.hide();
237        }
238    },
239
240    process: function(query)
241    {
242        var self = this;
243
244        var cat = '';
245        if (self.$category.val() !== undefined) {
246            cat = '&' + self.$category.attr('name') + '=' + self.$category.val();
247        }
248
249        $.ajax({
250            url      : self.url + '?q=' + encodeURIComponent(query) + cat,
251            dataType : 'json',
252            type     : 'GET',
253            beforeSend: function() {
254                clearTimeout(self.processTimer);
255                self.processTimer = setTimeout(function() {
256                    self.$loader.show();
257                }, 250);
258            },
259            success  : function(response) {
260                clearTimeout(self.processTimer);
261
262                self.$loader.hide();
263
264                if (response.query.toLowerCase().trim() === self.$listenField.val().toLowerCase().trim()) {
265                    if (response.items.length) {
266                        self.show(response.items);
267                    } else {
268                        self.hide();
269                    }
270                }
271            }
272        });
273    },
274
275    show: function(html)
276    {
277        var self = this;
278
279        if (html ==- undefined) {
280            if (self.result === '') {
281                return;
282            }
283        } else {
284            self.result = html;
285            self.$placeholder.html(html);
286            self.highlighter(self.$placeholder);
287        }
288
289        self.$placeholder.show();
290        self.shown = true;
291
292        $('li', self.$placeholder).each(function(key, el) {
293            var $el = $(el);
294            $el.on('mouseover', self.mouseover);
295            $el.on('mouseout', self.mouseout);
296            $el.on('click', self.click);
297        });
298
299        return this;
300    },
301
302    hide: function ()
303    {
304        var self = this;
305
306        self.$placeholder.hide();
307        self.shown = false;
308
309        return this;
310    },
311
312    highlighter: function (item)
313    {
314        var self = this;
315
316        $('.highlight', item).each(function(key, el) {
317            var $el     = $(el);
318            var arQuery = self.$listenField.val().split(' ');
319            var html    = $el.text();
320
321            arQuery.each(function(word) {
322                if ($.trim(word)) {
323                    word = word.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
324                    if ("strong".indexOf(word) == -1) {
325                        html = html.replace(new RegExp('(' + word + ')', 'ig'), function ($1, match) {
326                            return '<strong>' + match + '</strong>';
327                        });
328                    }
329                }
330            });
331
332            $el.html(html);
333        });
334    }
335});
336
337$(function() {
338    _.each($('.UI-SEARCHAUTOCOMPLETE'), function (el) {
339        var autocomplete = new SearchAutocomplete();
340        autocomplete.init(el);
341    });
342});
343
344});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.