/*
*  Ajax Autocomplete for jQuery, version 1.0.4
*  (c) 2009 Tomas Kirda
*
*  Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
*  For details, see the web site: http://www.devbridge.com/projects/autocomplete/jquery/
*
*  Last Review: 18:00 PM 3/30/2009
*/
(function(c) { c.fn.autocomplete = function(d) { return this.each(function() { return new a(this, d); }); }; var b = function(g, f, d) { var e = d.replace(/([.*+?|(){}[\]\\])/g, "\\$1"); return g.replace(new RegExp(e, "gi"), "<strong>" + d + "</strong>"); }; var a = function(e, d) { this.el = c(e); this.id = this.el.attr("id"); this.el.attr("autocomplete", "off"); this.suggestions = []; this.data = []; this.badQueries = []; this.selectedIndex = -1; this.currentValue = this.el.val(); this.intervalId = 0; this.cachedResponse = []; this.onChangeInterval = null; this.ignoreValueChange = false; this.serviceUrl = d.serviceUrl; this.options = { autoSubmit: false, minChars: 1, maxHeight: 300, deferRequestBy: 0, width: 0, highlight: true, params: {}, fnFormatResult: b }; if (d) { c.extend(this.options, d); } this.initialize(); }; a.isArray = function(d) { return d && d.constructor === Array; }; a.prototype = { killerFn: null, initialize: function() { var f = this; this.killerFn = function(g) { if (c(g.target).parents(".autocomplete").size() === 0) { f.killSuggestions(); f.disableKillerFn(); } }; var d = new Date().getTime(); var e = "Autocomplete_" + d; if (!this.options.width) { this.options.width = this.el.width(); } this.mainContainerId = "AutocompleteContainter_" + d; c('<div id="' + this.mainContainerId + '" style="position:absolute;"><div class="autocomplete-w1"><div class="autocomplete-w2"><div class="autocomplete" id="' + e + '" style="display:none; width:' + this.options.width + 'px;"></div></div></div></div>').appendTo("body"); this.container = c("#" + e); this.fixPosition(); if (window.opera) { this.el.keypress(function(g) { f.onKeyPress(g); }); } else { this.el.keydown(function(g) { f.onKeyPress(g); }); } this.el.keyup(function(g) { f.onKeyUp(g); }); this.el.blur(function() { f.enableKillerFn(); }); this.el.focus(function() { f.fixPosition(); }); this.container.css({ maxHeight: this.options.maxHeight + "px" }); }, fixPosition: function() { var d = this.el.offset(); c("#" + this.mainContainerId).css({ top: (d.top + this.el.innerHeight()) + "px", left: d.left + "px" }); }, enableKillerFn: function() { var d = this; c(document).bind("click", d.killerFn); }, disableKillerFn: function() { var d = this; c(document).unbind("click", d.killerFn); }, killSuggestions: function() { var d = this; this.stopKillSuggestions(); this.intervalId = window.setInterval(function() { d.hide(); d.stopKillSuggestions(); }, 300); }, stopKillSuggestions: function() { window.clearInterval(this.intervalId); }, onKeyPress: function(d) { if (!this.enabled) { return; } switch (d.keyCode) { case 27: this.el.val(this.currentValue); this.hide(); break; case 9: case 13: if (this.selectedIndex === -1) { this.hide(); return; } this.select(this.selectedIndex); if (d.keyCode === 9) { return; } break; case 38: this.moveUp(); break; case 40: this.moveDown(); break; default: return; } d.stopImmediatePropagation(); d.preventDefault(); }, onKeyUp: function(f) { switch (f.keyCode) { case 38: case 40: return; } clearInterval(this.onChangeInterval); if (this.currentValue !== this.el.val()) { if (this.options.deferRequestBy > 0) { var d = this; this.onChangeInterval = setInterval(function() { d.onValueChange(); }, this.options.deferRequestBy); } else { this.onValueChange(); } } }, onValueChange: function() { clearInterval(this.onChangeInterval); this.currentValue = this.el.val(); this.selectedIndex = -1; if (this.ignoreValueChange) { this.ignoreValueChange = false; return; } if (this.currentValue === "" || this.currentValue.length < this.options.minChars) { this.hide(); } else { this.getSuggestions(); } }, getSuggestions: function() { var e = this.cachedResponse[this.currentValue]; if (e && a.isArray(e.suggestions)) { this.suggestions = e.suggestions; this.data = e.data; this.suggest(); } else { if (!this.isBadQuery(this.currentValue)) { var d = this; c.get(this.serviceUrl, { query: this.currentValue }, function(f) { d.processResponse(f); }, "json"); } } }, isBadQuery: function(e) { var d = this.badQueries.length; while (d--) { if (e.indexOf(this.badQueries[d]) === 0) { return true; } } return false; }, hide: function() { this.enabled = false; this.selectedIndex = -1; this.container.hide(); }, suggest: function() { if (this.suggestions.length === 0) { this.hide(); return; } var g, d, j, h; g = this; d = this.suggestions.length; h = this.options.fnFormatResult; this.container.hide().empty(); for (var e = 0; e < d; e++) { j = c((g.selectedIndex === e ? '<div class="selected"' : "<div") + ' title="' + this.suggestions[e] + '">' + h(this.suggestions[e], this.data[e], this.currentValue) + "</div>"); j.mouseover((function(f) { return function() { g.activate(f); }; })(e)); j.click((function(f) { return function() { g.select(f); }; })(e)); this.container.append(j); } this.enabled = true; this.container.show(); }, processResponse: function(e) { var d; try { d = e; if (!a.isArray(d.data)) { d.data = []; } } catch (f) { return; } this.suggestions = d.suggestions; this.data = d.data; this.cachedResponse[d.query] = d; if (d.suggestions.length === 0) { this.badQueries.push(d.query); } if (d.query === this.currentValue) { this.suggest(); } }, activate: function(d) { var e = this.container.children(); var f; if (this.selectedIndex !== -1 && e.length > this.selectedIndex) { c(e.get(this.selectedIndex)).attr("class", ""); } this.selectedIndex = d; if (this.selectedIndex !== -1 && e.length > this.selectedIndex) { f = e.get(this.selectedIndex); c(f).attr("class", "selected"); } return f; }, deactivate: function(e, d) { e.className = ""; if (this.selectedIndex === d) { this.selectedIndex = -1; } }, select: function(e) { var d = this.suggestions[e]; if (d) { this.el.val(d); if (this.options.autoSubmit) { var g = this.el.parents("form"); if (g.length > 0) { g.get(0).submit(); } } this.ignoreValueChange = true; this.hide(); this.onSelect(e); } }, moveUp: function() { if (this.selectedIndex === -1) { return; } if (this.selectedIndex === 0) { this.container.children().get(0).className = ""; this.selectedIndex = -1; this.el.val(this.currentValue); return; } this.adjustScroll(this.selectedIndex - 1); }, moveDown: function() { if (this.selectedIndex === (this.suggestions.length - 1)) { return; } this.adjustScroll(this.selectedIndex + 1); }, adjustScroll: function(d) { var h, e, f, g; h = this.activate(d); e = h.offsetTop; f = this.container.scrollTop(); g = f + this.options.maxHeight - 25; if (e < f) { this.container.scrollTop(e); } else { if (e > g) { this.container.scrollTop(e - this.options.maxHeight + 25); } } this.el.val(this.suggestions[d]); }, onSelect: function(d) { (this.options.onSelect || function() { })(this.suggestions[d], this.data[d]); } }; })(jQuery);
