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

Commit

Permalink
fix(typeahead): don't show matches if an element is not focused
Browse files Browse the repository at this point in the history
Closes #964
  • Loading branch information
pkozlowski-opensource committed Sep 22, 2013
1 parent c6ba8d7 commit d1f9453
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
24 changes: 22 additions & 2 deletions 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'));
Expand All @@ -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 = [
Expand All @@ -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);
Expand Down Expand Up @@ -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("<div><input ng-model='result' typeahead='item for item in items($viewValue)'></div>");
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("<div><input ng-model='result' typeahead='item for item in source | filter:$viewValue'></div>");
var inputEl = findInput(element);
Expand Down
9 changes: 8 additions & 1 deletion src/typeahead/typeahead.js
Expand Up @@ -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('<typeahead-popup></typeahead-popup>');
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit d1f9453

Please sign in to comment.