diff --git a/content/styles.css b/content/styles.css index 3d11589..f3da7b4 100644 --- a/content/styles.css +++ b/content/styles.css @@ -1,7 +1,7 @@ body { font-family: sans-serif; font-size: 14px; line-height: 1.6em; margin: 0; padding: 0; } .container { width: 800px; margin: 0 auto; } -.autocomplete-suggestions { border: 1px solid #999; background: #FFF; cursor: default; overflow: auto; } +.autocomplete-suggestions { border: 1px solid #999; background: #FFF; cursor: default; overflow: auto; -webkit-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); -moz-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); } .autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; } .autocomplete-selected { background: #F0F0F0; } .autocomplete-suggestions strong { font-weight: normal; color: #3399FF; } diff --git a/src/jquery.autocomplete.js b/src/jquery.autocomplete.js index 47a30cf..5ab1a1c 100644 --- a/src/jquery.autocomplete.js +++ b/src/jquery.autocomplete.js @@ -44,7 +44,9 @@ ESC: 27, TAB: 9, RETURN: 13, + LEFT: 37, UP: 38, + RIGHT: 39, DOWN: 40 }; @@ -99,6 +101,7 @@ selected: 'autocomplete-selected', suggestion: 'autocomplete-suggestion' }; + that.hint = null; // Initialize and set options: that.initialize(); @@ -263,11 +266,28 @@ 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; } @@ -281,14 +301,24 @@ 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: case keys.RETURN: + if (e.which === keys.TAB && that.hint) { + that.selectHint(); + return; + } if (that.selectedIndex === -1) { that.hide(); return; } that.select(that.selectedIndex); - if (e.keyCode === keys.TAB && this.options.tabDisabled === false) { + if (e.which === keys.TAB && that.options.tabDisabled === false) { return; } break; @@ -314,7 +344,7 @@ return; } - switch (e.keyCode) { + switch (e.which) { case keys.UP: case keys.DOWN: return; @@ -486,11 +516,15 @@ }, signalHint: function (suggestion) { - var hintValue = ''; + var hintValue = '', + that = this; if (suggestion) { - hintValue = this.currentValue + suggestion.value.substr(this.currentValue.length); + hintValue = that.currentValue + suggestion.value.substr(that.currentValue.length); + } + if (that.hint !== suggestion) { + that.hint = suggestion; + (this.options.onHint || $.noop)(hintValue); } - (this.options.onHint || $.noop)(hintValue); }, verifySuggestionsFormat: function (suggestions) { @@ -546,6 +580,13 @@ return null; }, + selectHint: function () { + var that = this, + i = $.inArray(that.hint, that.suggestions); + + that.select(i); + }, + select: function (i) { var that = this; that.hide();