diff --git a/README.md b/README.md index b71f1f34b..785840651 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,8 @@ When initializing an autocomplete, there are a number of options you can configu * `autoselectOnBlur` – If `true`, when the input is blurred, the first rendered suggestion in the dropdown will automatically have the `cursor` class, and pressing `` will select it. This option should be used on mobile, see [#113](https://github.com/algolia/autocomplete.js/issues/113) +* `tabAutocomplete` – If `true`, pressing tab will select the first rendered suggestion in the dropdown. Defaults to `true`. + * `hint` – If `false`, the autocomplete will not show a hint. Defaults to `true`. * `debug` – If `true`, the autocomplete will not close on `blur`. Defaults to `false`. diff --git a/src/angular/directive.js b/src/angular/directive.js index 862b09df6..4b79b27c7 100644 --- a/src/angular/directive.js +++ b/src/angular/directive.js @@ -72,6 +72,7 @@ angular.module('algolia.autocomplete', []) minLength: scope.options.minLength, autoselect: scope.options.autoselect, autoselectOnBlur: scope.options.autoselectOnBlur, + tabAutocomplete: scope.options.tabAutocomplete, openOnFocus: scope.options.openOnFocus, templates: scope.options.templates, debug: scope.options.debug, diff --git a/src/autocomplete/typeahead.js b/src/autocomplete/typeahead.js index 2cec1b7b4..1967afb92 100644 --- a/src/autocomplete/typeahead.js +++ b/src/autocomplete/typeahead.js @@ -32,6 +32,7 @@ function Typeahead(o) { this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; this.autoWidth = (o.autoWidth === undefined) ? true : !!o.autoWidth; this.clearOnSelected = !!o.clearOnSelected; + this.tabAutocomplete = (o.tabAutocomplete === undefined) ? true : !!o.tabAutocomplete; o.hint = !!o.hint; @@ -285,6 +286,12 @@ _.mixin(Typeahead.prototype, { }, _onTabKeyed: function onTabKeyed(type, $e) { + if (!this.tabAutocomplete) { + // Closing the dropdown enables further tabbing + this.dropdown.close(); + return; + } + var datum; if (datum = this.dropdown.getDatumForCursor()) { diff --git a/src/jquery/plugin.js b/src/jquery/plugin.js index a633ed53a..1194a35d1 100644 --- a/src/jquery/plugin.js +++ b/src/jquery/plugin.js @@ -57,6 +57,7 @@ methods = { minLength: o.minLength, autoselect: o.autoselect, autoselectOnBlur: o.autoselectOnBlur, + tabAutocomplete: o.tabAutocomplete, openOnFocus: o.openOnFocus, templates: o.templates, debug: o.debug, diff --git a/src/standalone/index.js b/src/standalone/index.js index 100daebaf..c6d344160 100644 --- a/src/standalone/index.js +++ b/src/standalone/index.js @@ -42,6 +42,7 @@ function autocomplete(selector, options, datasets, typeaheadObject) { minLength: options.minLength, autoselect: options.autoselect, autoselectOnBlur: options.autoselectOnBlur, + tabAutocomplete: options.tabAutocomplete, openOnFocus: options.openOnFocus, templates: options.templates, debug: options.debug, diff --git a/test/unit/typeahead_spec.js b/test/unit/typeahead_spec.js index 8888c969e..621bed15a 100644 --- a/test/unit/typeahead_spec.js +++ b/test/unit/typeahead_spec.js @@ -464,7 +464,7 @@ describe('Typeahead', function() { }); describe('when cursor is not in use', function() { - it('should autocomplete', function() { + it('should autocomplete if tabAutocomplete is true', function() { var spy; this.input.getQuery.and.returnValue('bi'); @@ -478,6 +478,35 @@ describe('Typeahead', function() { expect(this.input.setInputValue).toHaveBeenCalledWith(testDatum.value); expect(spy).toHaveBeenCalled(); }); + + it('should not autocomplete if tabAutocomplete is false', function() { + this.view.tabAutocomplete = false; + + var spy; + + this.input.getQuery.and.returnValue('bi'); + this.input.getHint.and.returnValue(testDatum.value); + this.input.isCursorAtEnd.and.returnValue(true); + this.dropdown.getDatumForTopSuggestion.and.returnValue(testDatum); + this.$input.on('autocomplete:autocompleted', spy = jasmine.createSpy()); + + this.input.trigger('tabKeyed'); + + expect(this.input.setInputValue).not.toHaveBeenCalledWith(testDatum.value); + expect(spy).not.toHaveBeenCalled(); + }); + + it('should close the dropdown if tabAutocomplete is false', function() { + this.view.tabAutocomplete = false; + + this.input.getQuery.and.returnValue('bi'); + this.input.getHint.and.returnValue(testDatum.value); + this.input.isCursorAtEnd.and.returnValue(true); + + this.input.trigger('tabKeyed'); + + expect(this.dropdown.close).toHaveBeenCalled(); + }); }); });