Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
fix(typeahead): timeout cancellation when deleting characters
Browse files Browse the repository at this point in the history
Closes #2074
  • Loading branch information
Michal Wesolowski authored and pkozlowski-opensource committed May 2, 2014
1 parent 941a382 commit 5dc5792
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
15 changes: 15 additions & 0 deletions src/typeahead/test/typeahead.spec.js
Expand Up @@ -555,6 +555,21 @@ describe('typeahead tests', function () {
expect($scope.isLoading).toBeFalsy();
});

it('should cancel old timeout when deleting characters', inject(function ($timeout) {
var values = [];
$scope.loadMatches = function(viewValue) {
values.push(viewValue);
return $scope.source;
};
var element = prepareInputEl('<div><input ng-model="result" typeahead="item for item in loadMatches($viewValue) | filter:$viewValue" typeahead-min-length="2" typeahead-wait-ms="200"></div>');
changeInputValueTo(element, 'match');
changeInputValueTo(element, 'm');

$timeout.flush();

expect(values).not.toContain('match');
}));

it('does not close matches popup on click in input', function () {
var element = prepareInputEl('<div><input ng-model="result" typeahead="item for item in source | filter:$viewValue"></div>');
var inputEl = findInput(element);
Expand Down
21 changes: 15 additions & 6 deletions src/typeahead/typeahead.js
Expand Up @@ -173,6 +173,18 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
//Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
var timeoutPromise;

var scheduleSearchWithTimeout = function(inputValue) {
timeoutPromise = $timeout(function () {
getMatchesAsync(inputValue);
}, waitTime);
};

var cancelPreviousTimeout = function() {
if (timeoutPromise) {
$timeout.cancel(timeoutPromise);
}
};

//plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
//$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
modelCtrl.$parsers.unshift(function (inputValue) {
Expand All @@ -181,17 +193,14 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap

if (inputValue && inputValue.length >= minSearch) {
if (waitTime > 0) {
if (timeoutPromise) {
$timeout.cancel(timeoutPromise);//cancel previous timeout
}
timeoutPromise = $timeout(function () {
getMatchesAsync(inputValue);
}, waitTime);
cancelPreviousTimeout();
scheduleSearchWithTimeout(inputValue);
} else {
getMatchesAsync(inputValue);
}
} else {
isLoadingSetter(originalScope, false);
cancelPreviousTimeout();
resetMatches();
}

Expand Down

0 comments on commit 5dc5792

Please sign in to comment.