PageSourceSearch

https://www.ecampus.com/include/js/jquery.autocomplete.custom.js?v=jqu2

js ecampus.com collected 2026-10-01 10:32:44 UTC 16,009 bytes, 520 lines download raw bytes

1/**
2*  Ajax Autocomplete for jQuery, version 1.1.3
3*  (c) 2010 Tomas Kirda
4*
5*  Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
6*  For details, see the web site: http://www.devbridge.com/projects/autocomplete/jquery/
7*
8*  Last Review: 04/19/2010
9*/
10
11/*jslint onevar: true, evil: true, nomen: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */
12/*global window: true, document: true, clearInterval: true, setInterval: true, jQuery: true */
13
14(function($) {
15
16  var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g');
17
18  function fnFormatResult(value, data, currentValue) {
19	var prefix;
20	var suffix;
21	var innervalue;
22	var startindex;
23	var endindex;
24	var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')';
25	var bFound = false;
26	
27	startindex = value.indexOf('<!--AutoSuggestTitle-->', 0);
28	
29	if (startindex > 0)
30	{
31		bFound = true;
32		
33		prefix = value.substring(0, startindex + 23);
34		
35		endindex = value.indexOf('<!--EndAutoSuggestTitle-->', startindex + 23);
36		
37		if (endindex > 0)
38		{
39			suffix = value.substring(endindex);
40			innervalue = value.substring(startindex + 23, endindex);
41			
42			innervalue = innervalue.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
43			value = prefix + innervalue + suffix;
44		}
45	}
46	
47    startindex = value.indexOf('<!--AutoSuggestAuthor-->', 0);
48	
49	if (startindex > 0)
50	{
51		bFound = true;
52		
53		prefix = value.substring(0, startindex + 24);
54		
55		endindex = value.indexOf('<!--EndAutoSuggestAuthor-->', startindex + 24);
56		
57		if (endindex > 0)
58		{
59			suffix = value.substring(endindex);
60			innervalue = value.substring(startindex + 24, endindex);
61			
62			innervalue = innervalue.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
63			value = prefix + innervalue + suffix;
64		}
65	}
66	
67	startindex = value.indexOf('<!--AutoSuggestHelpDeskQuestion-->', 0);
68	
69	if (startindex > 0)
70	{
71		bFound = true;
72		
73		prefix = value.substring(0, startindex + 34);
74		
75		endindex = value.indexOf('<!--EndAutoSuggestHelpDeskQuestion-->', startindex + 34);
76		
77		if (endindex > 0)
78		{
79			suffix = value.substring(endindex);
80			innervalue = value.substring(startindex + 34, endindex);
81			
82			innervalue = innervalue.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
83			value = prefix + innervalue + suffix;
84		}
85	}
86	
87	if (!bFound)
88	{
89		value = value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
90	}
91	
92    return value;
93  }
94
95  function Autocomplete(el, options) {
96    this.el = $(el);
97    this.el.attr('autocomplete', 'off');
98    this.suggestions = [];
99    this.data = [];
100    this.badQueries = [];
101    this.selectedIndex = -1;
102    this.currentValue = this.el.val();
103    this.intervalId = 0;
104    this.cachedResponse = [];
105    this.onChangeInterval = null;
106    this.ignoreValueChange = false;
107    this.serviceUrl = options.serviceUrl;
108    this.isLocal = false;
109    this.options = {
110      autoSubmit: false,
111      minChars: 1,
112      maxHeight: 300,
113      deferRequestBy: 0,
114      width: 0,
115      highlight: true,
116      suggest_verbiage: 'Suggested Books:',
117      params: {},
118      fnFormatResult: fnFormatResult,
119      delimiter: null,
120      zIndex: 9999
121    };
122    this.initialize();
123    this.setOptions(options);
124  }
125  
126  $.fn.autocomplete = function(options) {
127    return new Autocomplete(this.get(0)||$('<input />'), options);
128  };
129
130
131  Autocomplete.prototype = {
132
133    killerFn: null,
134
135    initialize: function() {
136
137      var me, uid, autocompleteElId;
138      me = this;
139      uid = Math.floor(Math.random()*0x100000).toString(16);
140      uidSuggest = Math.floor(Math.random()*0x100000).toString(16);
141      autocompleteElId = 'Autocomplete_' + uid;
142	  autocompleteElIdSuggest = 'Autocomplete_' + uidSuggest;
143	  
144      this.killerFn = function(e) {
145        if ($(e.target).parents('.autocomplete').length === 0) {
146          me.killSuggestions();
147          me.disableKillerFn();
148        }
149      };
150
151      if (!this.options.width) { this.options.width = this.el.width(); }
152      this.mainContainerId = 'AutocompleteContainter_' + uid;
153		
154      $('<div id="' + this.mainContainerId + '" style="position:absolute;z-index:9999;"><div class="autocomplete-w1"><div class="autocomplete-suggest" id="' + autocompleteElIdSuggest + '" style="display:none; width:300px;">' + this.options.suggest_verbiage + '</div><div class="autocomplete" id="' + autocompleteElId + '" style="display:none; width:300px;"></div></div></div>').appendTo('body');
155
156      this.container = $('#' + autocompleteElId);
157      this.containerSuggest = $('#' + autocompleteElIdSuggest);
158      this.fixPosition();
159      if (window.opera) {
160        this.el.on('keypress', function(e) { me.onKeyPress(e); });
161      } else {
162        this.el.on('keydown', function(e) { me.onKeyPress(e); });
163      }
164      this.el.on('keyup', function(e) { me.onKeyUp(e); });
165      this.el.on('blur', function() { me.enableKillerFn(); });
166      this.el.on('focus', function() { me.fixPosition(); });
167    },
168    
169    setOptions: function(options){
170      var o = this.options;
171      $.extend(o, options);
172            
173      if(o.lookup){
174        this.isLocal = true;
175        if (Array.isArray(o.lookup)){ o.lookup = { suggestions:o.lookup, data:[] }; }
176      }
177      $('#'+this.mainContainerId).css({ zIndex:o.zIndex });
178      this.containerSuggest.html(o.suggest_verbiage);
179      this.container.css({ maxHeight: o.maxHeight + 'px', width:o.width });
180      this.containerSuggest.css({ maxHeight: o.maxHeight + 'px', width:o.width });
181      
182      if (o.containerClass && this.mainContainerId)
183	      $('#' + this.mainContainerId).addClass(o.containerClass);
184    },
185    
186    clearCache: function(){
187      this.cachedResponse = [];
188      this.badQueries = [];
189    },
190    
191    disable: function(){
192      this.disabled = true;
193    },
194    
195    enable: function(){
196      this.disabled = false;
197    },
198
199    fixPosition: function() {
200      var offset = this.el.offset();
201      $('#' + this.mainContainerId).css({ top: (offset.top + this.el.innerHe
201ight()) + 'px', left: offset.left + 'px' });
202    },
203
204    enableKillerFn: function() {
205      var me = this;
206      $(document).on('click', me.killerFn);
207    },
208
209    disableKillerFn: function() {
210      var me = this;
211      $(document).on('click', me.killerFn);
212    },
213
214    killSuggestions: function() {
215      var me = this;
216      this.stopKillSuggestions();
217      this.intervalId = window.setInterval(function() { me.hide(); me.stopKillSuggestions(); }, 300);
218    },
219
220    stopKillSuggestions: function() {
221      window.clearInterval(this.intervalId);
222    },
223
224    onKeyPress: function(e) {
225      if (this.disabled || !this.enabled) { return; }
226      // return will exit the function
227      // and event will not be prevented
228      switch (e.keyCode) {
229        case 27: //KEY_ESC:
230          this.el.val(this.currentValue);
231          this.hide();
232          break;
233        case 9: //KEY_TAB:
234        case 13: //KEY_RETURN:
235            if (this.selectedIndex === -1) {
236                this.hide();
237                return;
238            }
239
240            if (e.keyCode !== 13) { this.select(this.selectedIndex); }
241
242            if (e.keyCode === 9) { return; }
243          break;
244        case 38: //KEY_UP:
245          this.moveUp();
246          break;
247        case 40: //KEY_DOWN:
248          this.moveDown();
249          break;
250        default:
251          return;
252      }
253      e.stopImmediatePropagation();
254      e.preventDefault();
255    },
256
257    onKeyUp: function(e) {
258      if(this.disabled){ return; }
259      switch (e.keyCode) {
260        case 38: //KEY_UP:
261        case 40: //KEY_DOWN:
262            return;
263        case 13:
264            // Get the product URL that they hit Enter on.
265            var product_url = $(this.suggestions[this.selectedIndex]).find("a").attr("href");
266
267            // If there's a url, go to it.
268            if (product_url)
269                document.location = product_url;
270
271            return;
272      }
273      clearInterval(this.onChangeInterval);
274      if (this.currentValue !== this.el.val()) {
275        if (this.options.deferRequestBy > 0) {
276          // Defer lookup in case when value changes very quickly:
277          var me = this;
278          this.onChangeInterval = setInterval(function() { me.onValueChange(); }, this.options.deferRequestBy);
279        } else {
280          this.onValueChange();
281        }
282      }
283    },
284
285    onValueChange: function() {
286      clearInterval(this.onChangeInterval);
287      this.currentValue = this.el.val();
288      var q = this.getQuery(this.currentValue);
289      this.selectedIndex = -1;
290      if (this.ignoreValueChange) {
291        this.ignoreValueChange = false;
292        return;
293      }
294      if (q === '' || q.length < this.options.minChars) {
295        this.hide();
296      } else {
297        this.getSuggestions(q);
298      }
299    },
300
301    getQuery: function(val) {
302      var d, arr;
303      d = this.options.delimiter;
304      if (!d) { return val.trim(); }
305      arr = val.split(d);
306      return arr[arr.length - 1].trim();
307    },
308
309    getSuggestionsLocal: function(q) {
310      var ret, arr, len, val, i;
311      arr = this.options.lookup;
312      len = arr.suggestions.length;
313      ret = { suggestions:[], data:[] };
314      q = q.toLowerCase();
315      for(i=0; i< len; i++){
316        val = arr.suggestions[i];
317        if(val.toLowerCase().indexOf(q) === 0){
318          ret.suggestions.push(val);
319          ret.data.push(arr.data[i]);
320        }
321      }
322      return ret;
323    },
324    
325    getSuggestions: function(q) {
326		q = q.toLowerCase();
327      var cr, me;
328      cr = this.isLocal ? this.getSuggestionsLocal(q) : this.cachedResponse[q];
329		
330      if (cr && Array.isArray(cr.suggestions)) {
331        this.suggestions = cr.suggestions;
332        this.data = cr.data;
333        this.suggest();
334      } else if (!this.isBadQuery(q)) {
335        me = this;
336        me.options.params.query = q;
337        //$.get(this.serviceUrl, me.options.params, function(txt) { me.processResponse(txt); }, 'text');
338
339          var timeout = 20000;
340
341          if (me.options.timeout)
342              timeout = me.options.timeout;
343
344          $.ajax({
345              type: "get",
346              url: this.serviceUrl,
347              data: me.options.params,
348              cache: true,
349              contentType: "text/html;charset=iso-8859-1",
350              beforeSend: function (jqXHR) {
351                  jqXHR.overrideMimeType('text/html;charset=iso-8859-1');
352              },
353              timeout: timeout
354          })
355
356              .done(function (html) {
357                  me.processResponse(html);
358              })
359
360              .fail(function () {
361                  fn = me.options.onFail;
362                  if (typeof fn === 'function') { fn(); }
363              });
364      }
365    },
366
367    isBadQuery: function(q) {
368      var i = this.badQueries.length;
369      while (i--) {
370        if (q.indexOf(this.badQueries[i]) === 0) { return true; }
371      }
372      return false;
373    },
374
375    hide: function() {
376      this.enabled = false;
377      this.selectedIndex = -1;
378      this.container.hide();
379      this.containerSuggest.hide();
380    },
381
382    suggest: function() {
383      if (this.suggestions.length === 0) {
384        this.hide();
385        return;
386      }
387	
388		//alert(this.getQuery(this.currentValue));
389		
390      var me, len, div, f, v, i, s, mOver, mClick;
391      me = this;
392      len = this.suggestions.length;
393      f = this.options.fnFormatResult;
394      v = this.getQuery(this.currentValue);
395      mOver = function(xi) { return function() { me.activate(xi); }; };
396      mClick = function(xi) { return function() { me.select(xi); }; };
397      this.container.hide().empty();
398      
399      //this.container.append('<div id="autosuggest_suggested">Suggested Books:</div>');
400      
401      for (i = 0; i < len; i++) {
402        s = this.suggestions[i];
403        div = $((me.selectedIndex === i ? '<div class="selected"' : '<div') + '>' + f(s, this.data[i], v) + '</div>');
404        div.on('mouseover', mOver(i));
405        div.on('click', mClick(i));
406        this.container.append(div);
407      }
408      this.enabled = true;
409      this.container.show();
410      this.containerSuggest.show();
411    },
412
413    processResponse: function(text) {
414      var response;
415      try {
416        response = eval('(' + text + ')');
417      } catch (err) { return; }
418      if (!Array.isArray(response.data)) { response.data = []; }
419      if(!this.options.noCache){
420        this.cachedResponse[response.query] = response;
421        if (response.suggestions.length === 0) { this.badQueries.push(response.query); }
422      }
423      
424      if (response.query === this.getQuery(this.currentValue).toLowerCase()) {
425        this.suggestions = response.suggestions;
426        this.data = response.data;
427        this.suggest(); 
428      }
429    },
430
431    activate: function(index) {
432      var divs, activeItem;
433      divs = this.container.children();
434      // Clear previous selection:
435      if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
436        $(divs.get(this.selectedIndex)).removeClass();
437      }
438      this.selectedIndex = index;
439      if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
440        activeItem = divs.get(this.selectedIndex);
441        $(activeItem).addClass('selected');
442      }
443      return activeItem;
444    },
445
446    deactivate: function(div, index) {
447      div.className = '';
448      if (this.selectedIndex === index) { this.selectedIndex = -1; }
449    },
450
451    select: function(i) {
452      var selectedValue, f;
453      selectedValue = this.suggestions[i];
454      if (selectedValue) {
455        //this.el.val(selectedValue);
456        if (this.options.autoSubmit) {
457          f = this.el.parents('form');
458            if (f.length > 0) {
459                f.get(0).trigger('submit'); }
460            }
461        this.ignoreValueChange = true;
462        this.hide();
463        this.onSelect(i);
464      }
465    },
466
467    moveUp: function() {
468      if (this.selectedIndex === -1) { return; }
469      if (this.selectedIndex === 0) {
470        this.container.children().get(0).className = '';
471        this.selectedIndex = -1;
472        this.el.val(this.currentValue);
473        return;
474      }
475      this.adjustScroll(this.selectedIndex - 1);
476    },
477
478    moveDown: function() {
479      if (this.selectedIndex === (this.suggestions.length - 1)) { return; }
480      this.adjustScroll(this.selectedIndex + 1);
481    },
482
483    adjustScroll: function(i) {
484      var activeItem, offsetTop, upperBound, lowerBound;
485      activeItem = this.activate(i);
486      offsetTop = activeItem.offsetTop;
487      upperBound = this.container.scrollTop();
488      lowerBound = upperBound + this.options.maxHeight - 25;
489      if (offsetTop < upperBound) {
490        this.container.scrollTop(offsetTop);
491      } else if (offsetTop > lowerBound) {
492        this.container.scrollTop(offsetTop - this.options.maxHeight + 25);
493      }
494      //this.el.val(this.getValue(this.suggestions[i]));
495    },
496
497    onSelect: function(i) {
498      var me, fn, s, d;
499      me = this;
500      fn = me.options.onSelect;
501      s = me.suggestions[i];
502      d = me.data[i];
503      //me.el.val(me.getValue(s));
504      if (typeof fn === 'function') { fn(s, d, me.el); }
505    },
506
507    getValue: function(value){
508        var del, currVal, arr, me;
509        me = this;
510        del = me.options.delimiter;
511        if (!del) { return value; }
512        currVal = me.currentValue;
513        arr = currVal.split(del);
514        if (arr.length === 1) { return value; }
515        return currVal.substr(0, currVal.length - arr[arr.length - 1].length) + value;
516    }
517
518  };
519
520}(jQuery));

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.