From d1f9453003c0db5f1486df8d1336add0ef20fa54 Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Sun, 22 Sep 2013 13:03:16 +0200 Subject: [PATCH] fix(typeahead): don't show matches if an element is not focused Closes #964 --- src/typeahead/test/typeahead.spec.js | 24 ++++++++++++++++++++++-- src/typeahead/typeahead.js | 9 ++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/typeahead/test/typeahead.spec.js b/src/typeahead/test/typeahead.spec.js index 0675f257a1..1c374f40fe 100644 --- a/src/typeahead/test/typeahead.spec.js +++ b/src/typeahead/test/typeahead.spec.js @@ -1,6 +1,6 @@ describe('typeahead tests', function () { - var $scope, $compile, $document; + var $scope, $compile, $document, $timeout; var changeInputValueTo; beforeEach(module('ui.bootstrap.typeahead')); @@ -18,7 +18,7 @@ describe('typeahead tests', function () { }; }); })); - beforeEach(inject(function (_$rootScope_, _$compile_, _$document_, $sniffer) { + beforeEach(inject(function (_$rootScope_, _$compile_, _$document_, _$timeout_, $sniffer) { $scope = _$rootScope_; $scope.source = ['foo', 'bar', 'baz']; $scope.states = [ @@ -27,6 +27,7 @@ describe('typeahead tests', function () { ]; $compile = _$compile_; $document = _$document_; + $timeout = _$timeout_; changeInputValueTo = function (element, value) { var inputEl = findInput(element); inputEl.val(value); @@ -396,6 +397,25 @@ describe('typeahead tests', function () { expect(inputEl.val()).toEqual('bar@host.com'); }); + it('issue 964 - should not show popup with matches if an element is not focused', function () { + + $scope.items = function(viewValue) { + return $timeout(function(){ + return [viewValue]; + }); + }; + var element = prepareInputEl("
"); + var inputEl = findInput(element); + + changeInputValueTo(element, 'match'); + $scope.$digest(); + + inputEl.blur(); + $timeout.flush(); + + expect(element).toBeClosed(); + }); + 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 aba06a3d73..97d67b646c 100644 --- a/src/typeahead/typeahead.js +++ b/src/typeahead/typeahead.js @@ -65,6 +65,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap //expressions used by typeahead var parserResult = typeaheadParser.parse(attrs.typeahead); + var hasFocus; //pop-up element used to display matches var popUpEl = angular.element(''); @@ -100,7 +101,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap //it might happen that several async queries were in progress if a user were typing fast //but we are interested only in responses that correspond to the current view value - if (inputValue === modelCtrl.$viewValue) { + if (inputValue === modelCtrl.$viewValue && hasFocus) { if (matches.length > 0) { scope.activeIdx = 0; @@ -145,6 +146,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap //$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue modelCtrl.$parsers.unshift(function (inputValue) { + hasFocus = true; + if (inputValue && inputValue.length >= minSearch) { if (waitTime > 0) { if (timeoutPromise) { @@ -250,6 +253,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap } }); + element.bind('blur', function (evt) { + hasFocus = false; + }); + // Keep reference to click handler to unbind it. var dismissClickHandler = function (evt) { if (element[0] !== evt.target) {