Skip to content
This repository has been archived by the owner on Nov 22, 2021. It is now read-only.

Commit

Permalink
feat(autocomplete): Add loadOnFocus option
Browse files Browse the repository at this point in the history
Add a new option, loadOnFocus, to enable the loading of suggestions when
the input element gains focus. This option has lower precedence than
minLength and loadOnEmpty options.
  • Loading branch information
mbenford committed Jul 27, 2014
1 parent ccc70c8 commit fe711f5
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 6 deletions.
22 changes: 16 additions & 6 deletions src/auto-complete.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* is available as $query.
* @param {boolean=} {loadOnEmpty=false} Flag indicating that the source option will be evaluated when the input content
* becomes empty. The $query variable will be passed to the expression as an empty string.
* @param {boolean=} {loadOnFocus=false} Flag indicating that the source option will be evaluated when the input element
* gains focus. The current input value is available as $query.
*/
tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInputConfig) {
function SuggestionList(loadFn, options) {
Expand Down Expand Up @@ -104,15 +106,16 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInpu
templateUrl: 'ngTagsInput/auto-complete.html',
link: function(scope, element, attrs, tagsInputCtrl) {
var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down],
suggestionList, tagsInput, options, getItem, getDisplayText, documentClick;
suggestionList, tagsInput, options, getItem, getDisplayText, shouldLoadSuggestions;

tagsInputConfig.load('autoComplete', scope, attrs, {
debounceDelay: [Number, 100],
minLength: [Number, 3],
highlightMatchedText: [Boolean, true],
maxResultsToShow: [Number, 10],
loadOnDownArrow: [Boolean, false],
loadOnEmpty: [Boolean, false]
loadOnEmpty: [Boolean, false],
loadOnFocus: [Boolean, false]
});

options = scope.options;
Expand All @@ -130,6 +133,10 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInpu
return safeToString(getItem(item));
};

shouldLoadSuggestions = function(value) {
return value && value.length >= options.minLength || !value && options.loadOnEmpty;
};

scope.suggestionList = suggestionList;

scope.addSuggestionByIndex = function(index) {
Expand Down Expand Up @@ -168,16 +175,19 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInpu
suggestionList.reset();
})
.on('input-change', function(value) {
var shouldLoadSuggestions = value && value.length >= options.minLength ||
!value && options.loadOnEmpty;

if (shouldLoadSuggestions) {
if (shouldLoadSuggestions(value)) {
suggestionList.load(value, tagsInput.getTags());
}
else {
suggestionList.reset();
}
})
.on('input-focus', function() {
var value = tagsInput.getCurrentTagText();
if (options.loadOnFocus && shouldLoadSuggestions(value)) {
suggestionList.load(value, tagsInput.getTags());
}
})
.on('input-keydown', function(e) {
// This hack is needed because jqLite doesn't implement stopImmediatePropagation properly.
// I've sent a PR to Angular addressing this issue and hopefully it'll be fixed soon.
Expand Down
36 changes: 36 additions & 0 deletions test/auto-complete.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,42 @@ describe('autoComplete directive', function() {
});
});

describe('load-on-focus option', function() {
it('initializes the option to false', function() {
// Arrange/Act
compile();

// Assert
expect(isolateScope.options.loadOnFocus).toBe(false);
});

it('calls the load function when the input element gains focus and the option is true', function() {
// Arrange
compile('load-on-focus="true"');
tagsInput.getCurrentTagText.and.returnValue('ABC');

// Act
eventHandlers['input-focus']();
$timeout.flush();

// Assert
expect($scope.loadItems).toHaveBeenCalledWith('ABC');
});

it('doesn\' call the load function when the input element gains focus and the option is false', function() {
// Arrange
compile('load-on-focus="false"');
tagsInput.getCurrentTagText.and.returnValue('ABC');

// Act
eventHandlers['input-focus']();
$timeout.flush();

// Assert
expect($scope.loadItems).not.toHaveBeenCalled();
});
});

describe('debounce-delay option', function() {
it('initializes the option to 100 milliseconds', function() {
// Arrange/Act
Expand Down

0 comments on commit fe711f5

Please sign in to comment.