From 5dc57927e85adb3f9522be8b0760d613b17cb034 Mon Sep 17 00:00:00 2001 From: Michal Wesolowski Date: Wed, 16 Apr 2014 18:24:11 +0200 Subject: [PATCH] fix(typeahead): timeout cancellation when deleting characters Closes #2074 --- src/typeahead/test/typeahead.spec.js | 15 +++++++++++++++ src/typeahead/typeahead.js | 21 +++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/typeahead/test/typeahead.spec.js b/src/typeahead/test/typeahead.spec.js index 790f7ee535..6efd0f465c 100644 --- a/src/typeahead/test/typeahead.spec.js +++ b/src/typeahead/test/typeahead.spec.js @@ -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('
'); + 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('
'); var inputEl = findInput(element); diff --git a/src/typeahead/typeahead.js b/src/typeahead/typeahead.js index 8795ef6fe0..832d88e71f 100644 --- a/src/typeahead/typeahead.js +++ b/src/typeahead/typeahead.js @@ -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) { @@ -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(); }