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

Commit d1f9453

Browse files
fix(typeahead): don't show matches if an element is not focused
Closes #964
1 parent c6ba8d7 commit d1f9453

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/typeahead/test/typeahead.spec.js

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
describe('typeahead tests', function () {
22

3-
var $scope, $compile, $document;
3+
var $scope, $compile, $document, $timeout;
44
var changeInputValueTo;
55

66
beforeEach(module('ui.bootstrap.typeahead'));
@@ -18,7 +18,7 @@ describe('typeahead tests', function () {
1818
};
1919
});
2020
}));
21-
beforeEach(inject(function (_$rootScope_, _$compile_, _$document_, $sniffer) {
21+
beforeEach(inject(function (_$rootScope_, _$compile_, _$document_, _$timeout_, $sniffer) {
2222
$scope = _$rootScope_;
2323
$scope.source = ['foo', 'bar', 'baz'];
2424
$scope.states = [
@@ -27,6 +27,7 @@ describe('typeahead tests', function () {
2727
];
2828
$compile = _$compile_;
2929
$document = _$document_;
30+
$timeout = _$timeout_;
3031
changeInputValueTo = function (element, value) {
3132
var inputEl = findInput(element);
3233
inputEl.val(value);
@@ -396,6 +397,25 @@ describe('typeahead tests', function () {
396397
expect(inputEl.val()).toEqual('bar@host.com');
397398
});
398399

400+
it('issue 964 - should not show popup with matches if an element is not focused', function () {
401+
402+
$scope.items = function(viewValue) {
403+
return $timeout(function(){
404+
return [viewValue];
405+
});
406+
};
407+
var element = prepareInputEl("<div><input ng-model='result' typeahead='item for item in items($viewValue)'></div>");
408+
var inputEl = findInput(element);
409+
410+
changeInputValueTo(element, 'match');
411+
$scope.$digest();
412+
413+
inputEl.blur();
414+
$timeout.flush();
415+
416+
expect(element).toBeClosed();
417+
});
418+
399419
it('does not close matches popup on click in input', function () {
400420
var element = prepareInputEl("<div><input ng-model='result' typeahead='item for item in source | filter:$viewValue'></div>");
401421
var inputEl = findInput(element);

src/typeahead/typeahead.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
6565
//expressions used by typeahead
6666
var parserResult = typeaheadParser.parse(attrs.typeahead);
6767

68+
var hasFocus;
6869

6970
//pop-up element used to display matches
7071
var popUpEl = angular.element('<typeahead-popup></typeahead-popup>');
@@ -100,7 +101,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
100101

101102
//it might happen that several async queries were in progress if a user were typing fast
102103
//but we are interested only in responses that correspond to the current view value
103-
if (inputValue === modelCtrl.$viewValue) {
104+
if (inputValue === modelCtrl.$viewValue && hasFocus) {
104105
if (matches.length > 0) {
105106

106107
scope.activeIdx = 0;
@@ -145,6 +146,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
145146
//$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
146147
modelCtrl.$parsers.unshift(function (inputValue) {
147148

149+
hasFocus = true;
150+
148151
if (inputValue && inputValue.length >= minSearch) {
149152
if (waitTime > 0) {
150153
if (timeoutPromise) {
@@ -250,6 +253,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
250253
}
251254
});
252255

256+
element.bind('blur', function (evt) {
257+
hasFocus = false;
258+
});
259+
253260
// Keep reference to click handler to unbind it.
254261
var dismissClickHandler = function (evt) {
255262
if (element[0] !== evt.target) {

0 commit comments

Comments
 (0)