diff --git a/devbridge-autocomplete.jquery.json b/devbridge-autocomplete.jquery.json index 43627d7..2d9c84e 100644 --- a/devbridge-autocomplete.jquery.json +++ b/devbridge-autocomplete.jquery.json @@ -6,7 +6,7 @@ "ajax", "autocomplete" ], - "version": "1.2.7", + "version": "1.2.8", "author": { "name": "Tomas Kirda", "url": "https://github.com/tkirda" diff --git a/dist/jquery.autocomplete.js b/dist/jquery.autocomplete.js index 85556a7..7f331bb 100644 --- a/dist/jquery.autocomplete.js +++ b/dist/jquery.autocomplete.js @@ -1,9 +1,9 @@ /** -* Ajax Autocomplete for jQuery, version 1.2.7 +* Ajax Autocomplete for jQuery, version 1.2.8 * (c) 2013 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/ +* For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete * */ @@ -26,17 +26,16 @@ var utils = (function () { return { - - extend: function (target, source) { - return $.extend(target, source); + escapeRegExChars: function (value) { + return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); }, - - createNode: function (html) { + createNode: function (containerClass) { var div = document.createElement('div'); - div.innerHTML = html; - return div.firstChild; + div.className = containerClass; + div.style.position = 'absolute'; + div.style.display = 'none'; + return div; } - }; }()), @@ -44,7 +43,9 @@ ESC: 27, TAB: 9, RETURN: 13, + LEFT: 37, UP: 38, + RIGHT: 39, DOWN: 40 }; @@ -69,9 +70,11 @@ noCache: false, onSearchStart: noop, onSearchComplete: noop, + onSearchError: noop, containerClass: 'autocomplete-suggestions', tabDisabled: false, dataType: 'text', + currentRequest: null, lookupFilter: function (suggestion, originalQuery, queryLowerCase) { return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1; }, @@ -92,7 +95,6 @@ that.cachedResponse = []; that.onChangeInterval = null; that.onChange = null; - that.ignoreValueChange = false; that.isLocal = false; that.suggestionsContainer = null; that.options = $.extend({}, defaults, options); @@ -100,6 +102,9 @@ selected: 'autocomplete-selected', suggestion: 'autocomplete-suggestion' }; + that.hint = null; + that.hintValue = ''; + that.selection = null; // Initialize and set options: that.initialize(); @@ -111,8 +116,7 @@ $.Autocomplete = Autocomplete; Autocomplete.formatResult = function (suggestion, currentValue) { - var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g'), - pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')'; + var pattern = '(' + utils.escapeRegExChars(currentValue) + ')'; return suggestion.value.replace(new RegExp(pattern, 'gi'), '$1<\/strong>'); }; @@ -138,16 +142,16 @@ } }; - // Determine suggestions width: - if (!options.width || options.width === 'auto') { - options.width = that.el.outerWidth(); - } - - that.suggestionsContainer = Autocomplete.utils.createNode(''); + that.suggestionsContainer = Autocomplete.utils.createNode(options.containerClass); container = $(that.suggestionsContainer); - container.appendTo(options.appendTo).width(options.width); + container.appendTo(options.appendTo); + + // Only set width if it was provided: + if (options.width !== 'auto') { + container.width(options.width); + } // Listen for mouse over event on suggestions list: container.on('mouseover.autocomplete', suggestionSelector, function () { @@ -162,21 +166,32 @@ // Listen for click event on suggestions list: container.on('click.autocomplete', suggestionSelector, function () { - that.select($(this).data('index'), false); + that.select($(this).data('index')); }); that.fixPosition(); - // Opera does not like keydown: - if (window.opera) { - that.el.on('keypress.autocomplete', function (e) { that.onKeyPress(e); }); - } else { - that.el.on('keydown.autocomplete', function (e) { that.onKeyPress(e); }); - } + that.fixPositionCapture = function () { + if (that.visible) { + that.fixPosition(); + } + }; + $(window).on('resize.autocomplete', that.fixPositionCapture); + + that.el.on('keydown.autocomplete', function (e) { that.onKeyPress(e); }); that.el.on('keyup.autocomplete', function (e) { that.onKeyUp(e); }); that.el.on('blur.autocomplete', function () { that.onBlur(); }); - that.el.on('focus.autocomplete', function () { that.fixPosition(); }); + that.el.on('focus.autocomplete', function () { that.onFocus(); }); + that.el.on('change.autocomplete', function (e) { that.onKeyUp(e); }); + }, + + onFocus: function () { + var that = this; + that.fixPosition(); + if (that.options.minChars <= that.el.val().length) { + that.onValueChange(); + } }, onBlur: function () { @@ -187,7 +202,7 @@ var that = this, options = that.options; - utils.extend(options, suppliedOptions); + $.extend(options, suppliedOptions); that.isLocal = $.isArray(options.lookup); @@ -210,12 +225,16 @@ clear: function () { this.clearCache(); - this.currentValue = null; + this.currentValue = ''; this.suggestions = []; }, disable: function () { - this.disabled = true; + var that = this; + that.disabled = true; + if (that.currentRequest) { + that.currentRequest.abort(); + } }, enable: function () { @@ -224,7 +243,8 @@ fixPosition: function () { var that = this, - offset; + offset, + styles; // Don't adjsut position if custom container has been specified: if (that.options.appendTo !== 'body') { @@ -233,10 +253,16 @@ offset = that.el.offset(); - $(that.suggestionsContainer).css({ + styles = { top: (offset.top + that.el.outerHeight()) + 'px', left: offset.left + 'px' - }); + }; + + if (that.options.width === 'auto') { + styles.width = (that.el.outerWidth() - 2) + 'px'; + } + + $(that.suggestionsContainer).css(styles); }, enableKillerFn: function () { @@ -255,18 +281,35 @@ that.intervalId = window.setInterval(function () { that.hide(); that.stopKillSuggestions(); - }, 300); + }, 50); }, stopKillSuggestions: function () { window.clearInterval(this.intervalId); }, + isCursorAtEnd: function () { + var that = this, + valLength = that.el.val().length, + selectionStart = that.element.selectionStart, + range; + + if (typeof selectionStart === 'number') { + return selectionStart === valLength; + } + if (document.selection) { + range = document.selection.createRange(); + range.moveStart('character', -valLength); + return valLength === range.text.length; + } + return true; + }, + onKeyPress: function (e) { var that = this; // If suggestions are hidden and user presses arrow down, display suggestions: - if (!that.disabled && !that.visible && e.keyCode === keys.DOWN && that.currentValue) { + if (!that.disabled && !that.visible && e.which === keys.DOWN && that.currentValue) { that.suggest(); return; } @@ -275,19 +318,30 @@ return; } - switch (e.keyCode) { + switch (e.which) { case keys.ESC: that.el.val(that.currentValue); that.hide(); break; + case keys.RIGHT: + if (that.hint && that.options.onHint && that.isCursorAtEnd()) { + that.selectHint(); + break; + } + return; case keys.TAB: + if (that.hint && that.options.onHint) { + that.selectHint(); + return; + } + // Fall through to RETURN case keys.RETURN: if (that.selectedIndex === -1) { that.hide(); return; } - that.select(that.selectedIndex, e.keyCode === keys.RETURN); - if (e.keyCode === keys.TAB && this.options.tabDisabled === false) { + that.select(that.selectedIndex); + if (e.which === keys.TAB && that.options.tabDisabled === false) { return; } break; @@ -313,7 +367,7 @@ return; } - switch (e.keyCode) { + switch (e.which) { case keys.UP: case keys.DOWN: return; @@ -322,6 +376,7 @@ clearInterval(that.onChangeInterval); if (that.currentValue !== that.el.val()) { + that.findBestHint(); if (that.options.deferRequestBy > 0) { // Defer lookup in case when value changes very quickly: that.onChangeInterval = setInterval(function () { @@ -337,17 +392,17 @@ var that = this, q; + if (that.selection) { + that.selection = null; + (that.options.onInvalidateSelection || $.noop)(); + } + clearInterval(that.onChangeInterval); - that.currentValue = that.element.value; + that.currentValue = that.el.val(); q = that.getQuery(that.currentValue); that.selectedIndex = -1; - if (that.ignoreValueChange) { - that.ignoreValueChange = false; - return; - } - if (q.length < that.options.minChars) { that.hide(); } else { @@ -397,14 +452,20 @@ if ($.isFunction(options.serviceUrl)) { serviceUrl = options.serviceUrl.call(that.element, q); } - $.ajax({ + if (that.currentRequest) { + that.currentRequest.abort(); + } + that.currentRequest = $.ajax({ url: serviceUrl, data: options.ignoreParams ? null : options.params, type: options.type, dataType: options.dataType }).done(function (data) { + that.currentRequest = null; that.processResponse(data, q); options.onSearchComplete.call(that.element, q); + }).fail(function (jqXHR, textStatus, errorThrown) { + options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown); }); } }, @@ -427,6 +488,7 @@ that.visible = false; that.selectedIndex = -1; $(that.suggestionsContainer).hide(); + that.signalHint(null); }, suggest: function () { @@ -441,21 +503,73 @@ className = that.classes.suggestion, classSelected = that.classes.selected, container = $(that.suggestionsContainer), - html = ''; + beforeRender = that.options.beforeRender, + html = '', + width; // Build suggestions inner HTML: $.each(that.suggestions, function (i, suggestion) { html += '
' + formatResult(suggestion, value) + '
'; }); - container.html(html).show(); - that.visible = true; + // If width is auto, adjust width before displaying suggestions, + // because if instance was created before input had width, it will be zero. + // Also it adjusts if input width has changed. + // -2px to account for suggestions border. + if (that.options.width === 'auto') { + width = that.el.outerWidth() - 2; + container.width(width > 0 ? width : 300); + } + + container.html(html); // Select first value by default: if (that.options.autoSelectFirst) { that.selectedIndex = 0; container.children().first().addClass(classSelected); } + + if ($.isFunction(beforeRender)) { + beforeRender.call(that.element, container); + } + + container.show(); + that.visible = true; + + that.findBestHint(); + }, + + findBestHint: function () { + var that = this, + value = that.el.val().toLowerCase(), + bestMatch = null; + + if (!value) { + return; + } + + $.each(that.suggestions, function (i, suggestion) { + var foundMatch = suggestion.value.toLowerCase().indexOf(value) === 0; + if (foundMatch) { + bestMatch = suggestion; + } + return !foundMatch; + }); + + that.signalHint(bestMatch); + }, + + signalHint: function (suggestion) { + var hintValue = '', + that = this; + if (suggestion) { + hintValue = that.currentValue + suggestion.value.substr(that.currentValue.length); + } + if (that.hintValue !== hintValue) { + that.hintValue = hintValue; + that.hint = suggestion; + (this.options.onHint || $.noop)(hintValue); + } }, verifySuggestionsFormat: function (suggestions) { @@ -511,16 +625,17 @@ return null; }, - select: function (i, shouldIgnoreNextValueChange) { + selectHint: function () { var that = this, - selectedValue = that.suggestions[i]; + i = $.inArray(that.hint, that.suggestions); - if (selectedValue) { - that.el.val(selectedValue); - that.ignoreValueChange = shouldIgnoreNextValueChange; - that.hide(); - that.onSelect(i); - } + that.select(i); + }, + + select: function (i) { + var that = this; + that.hide(); + that.onSelect(i); }, moveUp: function () { @@ -534,6 +649,7 @@ $(that.suggestionsContainer).children().first().removeClass(that.classes.selected); that.selectedIndex = -1; that.el.val(that.currentValue); + that.findBestHint(); return; } @@ -573,6 +689,7 @@ } that.el.val(that.getValue(that.suggestions[index].value)); + that.signalHint(null); }, onSelect: function (index) { @@ -580,7 +697,11 @@ onSelectCallback = that.options.onSelect, suggestion = that.suggestions[index]; - that.el.val(that.getValue(suggestion.value)); + that.currentValue = that.getValue(suggestion.value); + that.el.val(that.currentValue); + that.signalHint(null); + that.suggestions = []; + that.selection = suggestion; if ($.isFunction(onSelectCallback)) { onSelectCallback.call(that.element, suggestion); @@ -611,6 +732,7 @@ var that = this; that.el.off('.autocomplete').removeData('autocomplete'); that.disableKillerFn(); + $(window).off('resize.autocomplete', that.fixPositionCapture); $(that.suggestionsContainer).remove(); } }; diff --git a/dist/jquery.autocomplete.min.js b/dist/jquery.autocomplete.min.js index 5901114..f467e3d 100644 --- a/dist/jquery.autocomplete.min.js +++ b/dist/jquery.autocomplete.min.js @@ -1,25 +1,28 @@ /** -* Ajax Autocomplete for jQuery, version 1.2.7 +* Ajax Autocomplete for jQuery, version 1.2.8 * (c) 2013 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/ * */ -(function(e){"function"===typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function g(a,b){var c=function(){},c={autoSelectFirst:!1,appendTo:"body",serviceUrl:null,lookup:null,onSelect:null,width:"auto",minChars:1,maxHeight:300,deferRequestBy:0,params:{},formatResult:g.formatResult,delimiter:null,zIndex:9999,type:"GET",noCache:!1,onSearchStart:c,onSearchComplete:c,containerClass:"autocomplete-suggestions",tabDisabled:!1,dataType:"text",lookupFilter:function(a,b,c){return-1!== -a.value.toLowerCase().indexOf(c)},paramName:"query",transformResult:function(a){return"string"===typeof a?e.parseJSON(a):a}};this.element=a;this.el=e(a);this.suggestions=[];this.badQueries=[];this.selectedIndex=-1;this.currentValue=this.element.value;this.intervalId=0;this.cachedResponse=[];this.onChange=this.onChangeInterval=null;this.isLocal=this.ignoreValueChange=!1;this.suggestionsContainer=null;this.options=e.extend({},c,b);this.classes={selected:"autocomplete-selected",suggestion:"autocomplete-suggestion"}; -this.initialize();this.setOptions(b)}var h={extend:function(a,b){return e.extend(a,b)},createNode:function(a){var b=document.createElement("div");b.innerHTML=a;return b.firstChild}};g.utils=h;e.Autocomplete=g;g.formatResult=function(a,b){var c="("+b.replace(RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\)","g"),"\\$1")+")";return a.value.replace(RegExp(c,"gi"),"$1")};g.prototype={killerFn:null,initialize:function(){var a=this,b="."+a.classes.suggestion,c=a.classes.selected, -d=a.options,f;a.element.setAttribute("autocomplete","off");a.killerFn=function(b){0===e(b.target).closest("."+a.options.containerClass).length&&(a.killSuggestions(),a.disableKillerFn())};if(!d.width||"auto"===d.width)d.width=a.el.outerWidth();a.suggestionsContainer=g.utils.createNode('');f=e(a.suggestionsContainer);f.appendTo(d.appendTo).width(d.width);f.on("mouseover.autocomplete",b,function(){a.activate(e(this).data("index"))}); -f.on("mouseout.autocomplete",function(){a.selectedIndex=-1;f.children("."+c).removeClass(c)});f.on("click.autocomplete",b,function(){a.select(e(this).data("index"),!1)});a.fixPosition();if(window.opera)a.el.on("keypress.autocomplete",function(b){a.onKeyPress(b)});else a.el.on("keydown.autocomplete",function(b){a.onKeyPress(b)});a.el.on("keyup.autocomplete",function(b){a.onKeyUp(b)});a.el.on("blur.autocomplete",function(){a.onBlur()});a.el.on("focus.autocomplete",function(){a.fixPosition()})},onBlur:function(){this.enableKillerFn()}, -setOptions:function(a){var b=this.options;h.extend(b,a);if(this.isLocal=e.isArray(b.lookup))b.lookup=this.verifySuggestionsFormat(b.lookup);e(this.suggestionsContainer).css({"max-height":b.maxHeight+"px",width:b.width+"px","z-index":b.zIndex})},clearCache:function(){this.cachedResponse=[];this.badQueries=[]},clear:function(){this.clearCache();this.currentValue=null;this.suggestions=[]},disable:function(){this.disabled=!0},enable:function(){this.disabled=!1},fixPosition:function(){var a;"body"===this.options.appendTo&& -(a=this.el.offset(),e(this.suggestionsContainer).css({top:a.top+this.el.outerHeight()+"px",left:a.left+"px"}))},enableKillerFn:function(){e(document).on("click.autocomplete",this.killerFn)},disableKillerFn:function(){e(document).off("click.autocomplete",this.killerFn)},killSuggestions:function(){var a=this;a.stopKillSuggestions();a.intervalId=window.setInterval(function(){a.hide();a.stopKillSuggestions()},300)},stopKillSuggestions:function(){window.clearInterval(this.intervalId)},onKeyPress:function(a){if(!this.disabled&& -!this.visible&&40===a.keyCode&&this.currentValue)this.suggest();else if(!this.disabled&&this.visible){switch(a.keyCode){case 27:this.el.val(this.currentValue);this.hide();break;case 9:case 13:if(-1===this.selectedIndex){this.hide();return}this.select(this.selectedIndex,13===a.keyCode);if(9===a.keyCode&&!1===this.options.tabDisabled)return;break;case 38:this.moveUp();break;case 40:this.moveDown();break;default:return}a.stopImmediatePropagation();a.preventDefault()}},onKeyUp:function(a){var b=this; -if(!b.disabled){switch(a.keyCode){case 38:case 40:return}clearInterval(b.onChangeInterval);if(b.currentValue!==b.el.val())if(0'+a(e,b)+""});f.html(g).show();this.visible=!0;this.options.autoSelectFirst&&(this.selectedIndex=0,f.children().first().addClass(d))}},verifySuggestionsFormat:function(a){return a.length&&"string"=== -typeof a[0]?e.map(a,function(a){return{value:a,data:null}}):a},processResponse:function(a,b){var c=this.options,d=c.transformResult(a,b);d.suggestions=this.verifySuggestionsFormat(d.suggestions);c.noCache||(this.cachedResponse[d[c.paramName]]=d,0===d.suggestions.length&&this.badQueries.push(d[c.paramName]));b===this.getQuery(this.currentValue)&&(this.suggestions=d.suggestions,this.suggest())},activate:function(a){var b=this.classes.selected,c=e(this.suggestionsContainer),d=c.children();c.children("."+ -b).removeClass(b);this.selectedIndex=a;return-1!==this.selectedIndex&&d.length>this.selectedIndex?(a=d.get(this.selectedIndex),e(a).addClass(b),a):null},select:function(a,b){var c=this.suggestions[a];c&&(this.el.val(c),this.ignoreValueChange=b,this.hide(),this.onSelect(a))},moveUp:function(){-1!==this.selectedIndex&&(0===this.selectedIndex?(e(this.suggestionsContainer).children().first().removeClass(this.classes.selected),this.selectedIndex=-1,this.el.val(this.currentValue)):this.adjustScroll(this.selectedIndex- -1))},moveDown:function(){this.selectedIndex!==this.suggestions.length-1&&this.adjustScroll(this.selectedIndex+1)},adjustScroll:function(a){var b=this.activate(a),c,d;b&&(b=b.offsetTop,c=e(this.suggestionsContainer).scrollTop(),d=c+this.options.maxHeight-25,bd&&e(this.suggestionsContainer).scrollTop(b-this.options.maxHeight+25),this.el.val(this.getValue(this.suggestions[a].value)))},onSelect:function(a){var b=this.options.onSelect;a=this.suggestions[a]; -this.el.val(this.getValue(a.value));e.isFunction(b)&&b.call(this.element,a)},getValue:function(a){var b=this.options.delimiter,c;if(!b)return a;c=this.currentValue;b=c.split(b);return 1===b.length?a:c.substr(0,c.length-b[b.length-1].length)+a},dispose:function(){this.el.off(".autocomplete").removeData("autocomplete");this.disableKillerFn();e(this.suggestionsContainer).remove()}};e.fn.autocomplete=function(a,b){return 0===arguments.length?this.first().data("autocomplete"):this.each(function(){var c= -e(this),d=c.data("autocomplete");if("string"===typeof a){if(d&&"function"===typeof d[a])d[a](b)}else d&&d.dispose&&d.dispose(),d=new g(this,a),c.data("autocomplete",d)})}}); \ No newline at end of file +(function(c){"function"===typeof define&&define.amd?define(["jquery"],c):c(jQuery)})(function(c){function g(a,b){var d=function(){},d={autoSelectFirst:!1,appendTo:"body",serviceUrl:null,lookup:null,onSelect:null,width:"auto",minChars:1,maxHeight:300,deferRequestBy:0,params:{},formatResult:g.formatResult,delimiter:null,zIndex:9999,type:"GET",noCache:!1,onSearchStart:d,onSearchComplete:d,onSearchError:d,containerClass:"autocomplete-suggestions",tabDisabled:!1,dataType:"text",currentRequest:null,lookupFilter:function(a, +b,d){return-1!==a.value.toLowerCase().indexOf(d)},paramName:"query",transformResult:function(a){return"string"===typeof a?c.parseJSON(a):a}};this.element=a;this.el=c(a);this.suggestions=[];this.badQueries=[];this.selectedIndex=-1;this.currentValue=this.element.value;this.intervalId=0;this.cachedResponse=[];this.onChange=this.onChangeInterval=null;this.isLocal=!1;this.suggestionsContainer=null;this.options=c.extend({},d,b);this.classes={selected:"autocomplete-selected",suggestion:"autocomplete-suggestion"}; +this.hint=null;this.hintValue="";this.selection=null;this.initialize();this.setOptions(b)}var l=function(){return{escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},createNode:function(a){var b=document.createElement("div");b.className=a;b.style.position="absolute";b.style.display="none";return b}}}();g.utils=l;c.Autocomplete=g;g.formatResult=function(a,b){var d="("+l.escapeRegExChars(b)+")";return a.value.replace(RegExp(d,"gi"),"$1")};g.prototype= +{killerFn:null,initialize:function(){var a=this,b="."+a.classes.suggestion,d=a.classes.selected,e=a.options,f;a.element.setAttribute("autocomplete","off");a.killerFn=function(b){0===c(b.target).closest("."+a.options.containerClass).length&&(a.killSuggestions(),a.disableKillerFn())};a.suggestionsContainer=g.utils.createNode(e.containerClass);f=c(a.suggestionsContainer);f.appendTo(e.appendTo);"auto"!==e.width&&f.width(e.width);f.on("mouseover.autocomplete",b,function(){a.activate(c(this).data("index"))}); +f.on("mouseout.autocomplete",function(){a.selectedIndex=-1;f.children("."+d).removeClass(d)});f.on("click.autocomplete",b,function(){a.select(c(this).data("index"))});a.fixPosition();a.fixPositionCapture=function(){a.visible&&a.fixPosition()};c(window).on("resize.autocomplete",a.fixPositionCapture);a.el.on("keydown.autocomplete",function(b){a.onKeyPress(b)});a.el.on("keyup.autocomplete",function(b){a.onKeyUp(b)});a.el.on("blur.autocomplete",function(){a.onBlur()});a.el.on("focus.autocomplete",function(){a.onFocus()}); +a.el.on("change.autocomplete",function(b){a.onKeyUp(b)})},onFocus:function(){this.fixPosition();if(this.options.minChars<=this.el.val().length)this.onValueChange()},onBlur:function(){this.enableKillerFn()},setOptions:function(a){var b=this.options;c.extend(b,a);if(this.isLocal=c.isArray(b.lookup))b.lookup=this.verifySuggestionsFormat(b.lookup);c(this.suggestionsContainer).css({"max-height":b.maxHeight+"px",width:b.width+"px","z-index":b.zIndex})},clearCache:function(){this.cachedResponse=[];this.badQueries= +[]},clear:function(){this.clearCache();this.currentValue="";this.suggestions=[]},disable:function(){this.disabled=!0;this.currentRequest&&this.currentRequest.abort()},enable:function(){this.disabled=!1},fixPosition:function(){var a;"body"===this.options.appendTo&&(a=this.el.offset(),a={top:a.top+this.el.outerHeight()+"px",left:a.left+"px"},"auto"===this.options.width&&(a.width=this.el.outerWidth()-2+"px"),c(this.suggestionsContainer).css(a))},enableKillerFn:function(){c(document).on("click.autocomplete", +this.killerFn)},disableKillerFn:function(){c(document).off("click.autocomplete",this.killerFn)},killSuggestions:function(){var a=this;a.stopKillSuggestions();a.intervalId=window.setInterval(function(){a.hide();a.stopKillSuggestions()},50)},stopKillSuggestions:function(){window.clearInterval(this.intervalId)},isCursorAtEnd:function(){var a=this.el.val().length,b=this.element.selectionStart;return"number"===typeof b?b===a:document.selection?(b=document.selection.createRange(),b.moveStart("character", +-a),a===b.text.length):!0},onKeyPress:function(a){if(!this.disabled&&!this.visible&&40===a.which&&this.currentValue)this.suggest();else if(!this.disabled&&this.visible){switch(a.which){case 27:this.el.val(this.currentValue);this.hide();break;case 39:if(this.hint&&this.options.onHint&&this.isCursorAtEnd()){this.selectHint();break}return;case 9:if(this.hint&&this.options.onHint){this.selectHint();return}case 13:if(-1===this.selectedIndex){this.hide();return}this.select(this.selectedIndex);if(9===a.which&& +!1===this.options.tabDisabled)return;break;case 38:this.moveUp();break;case 40:this.moveDown();break;default:return}a.stopImmediatePropagation();a.preventDefault()}},onKeyUp:function(a){var b=this;if(!b.disabled){switch(a.which){case 38:case 40:return}clearInterval(b.onChangeInterval);if(b.currentValue!==b.el.val())if(b.findBestHint(),0'+a(c,b)+""});"auto"===this.options.width&&(k=this.el.outerWidth()-2,f.width(0this.selectedIndex?(a=e.get(this.selectedIndex),c(a).addClass(b), +a):null},selectHint:function(){var a=c.inArray(this.hint,this.suggestions);this.select(a)},select:function(a){this.hide();this.onSelect(a)},moveUp:function(){-1!==this.selectedIndex&&(0===this.selectedIndex?(c(this.suggestionsContainer).children().first().removeClass(this.classes.selected),this.selectedIndex=-1,this.el.val(this.currentValue),this.findBestHint()):this.adjustScroll(this.selectedIndex-1))},moveDown:function(){this.selectedIndex!==this.suggestions.length-1&&this.adjustScroll(this.selectedIndex+ +1)},adjustScroll:function(a){var b=this.activate(a),d,e;b&&(b=b.offsetTop,d=c(this.suggestionsContainer).scrollTop(),e=d+this.options.maxHeight-25,be&&c(this.suggestionsContainer).scrollTop(b-this.options.maxHeight+25),this.el.val(this.getValue(this.suggestions[a].value)),this.signalHint(null))},onSelect:function(a){var b=this.options.onSelect;a=this.suggestions[a];this.currentValue=this.getValue(a.value);this.el.val(this.currentValue);this.signalHint(null); +this.suggestions=[];this.selection=a;c.isFunction(b)&&b.call(this.element,a)},getValue:function(a){var b=this.options.delimiter,c;if(!b)return a;c=this.currentValue;b=c.split(b);return 1===b.length?a:c.substr(0,c.length-b[b.length-1].length)+a},dispose:function(){this.el.off(".autocomplete").removeData("autocomplete");this.disableKillerFn();c(window).off("resize.autocomplete",this.fixPositionCapture);c(this.suggestionsContainer).remove()}};c.fn.autocomplete=function(a,b){return 0===arguments.length? +this.first().data("autocomplete"):this.each(function(){var d=c(this),e=d.data("autocomplete");if("string"===typeof a){if(e&&"function"===typeof e[a])e[a](b)}else e&&e.dispose&&e.dispose(),e=new g(this,a),d.data("autocomplete",e)})}}); \ No newline at end of file diff --git a/src/jquery.autocomplete.js b/src/jquery.autocomplete.js index 0a0baee..7f331bb 100644 --- a/src/jquery.autocomplete.js +++ b/src/jquery.autocomplete.js @@ -1,9 +1,9 @@ /** -* Ajax Autocomplete for jQuery, version 1.2.7 +* Ajax Autocomplete for jQuery, version 1.2.8 * (c) 2013 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/ +* For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete * */