diff --git a/src/dropdown/dropdown.js b/src/dropdown/dropdown.js
index ab60a2db33..cd15309cf2 100644
--- a/src/dropdown/dropdown.js
+++ b/src/dropdown/dropdown.js
@@ -24,10 +24,7 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
if (openScope === dropdownScope) {
openScope = null;
$document.off('click', closeDropdown);
- var dropdownMenu = dropdownScope.getDropdownElement();
- if (dropdownMenu) {
- dropdownMenu.off('keydown', this.keybindFilter);
- }
+ $document.off('keydown', this.keybindFilter);
}
};
@@ -60,11 +57,15 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
};
this.keybindFilter = function(evt) {
+ var dropdownElement = openScope.getDropdownElement();
+ var toggleElement = openScope.getToggleElement();
+ var dropdownElementTargeted = dropdownElement && dropdownElement[0].contains(evt.target);
+ var toggleElementTargeted = toggleElement && toggleElement[0].contains(evt.target);
if (evt.which === 27) {
evt.stopPropagation();
openScope.focusToggleElement();
closeDropdown();
- } else if (openScope.isKeynavEnabled() && [38, 40].indexOf(evt.which) !== -1 && openScope.isOpen) {
+ } else if (openScope.isKeynavEnabled() && [38, 40].indexOf(evt.which) !== -1 && openScope.isOpen && (dropdownElementTargeted || toggleElementTargeted)) {
evt.preventDefault();
evt.stopPropagation();
openScope.focusDropdownEntry(evt.which);
@@ -256,13 +257,11 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
var newEl = dropdownElement;
self.dropdownMenu.replaceWith(newEl);
self.dropdownMenu = newEl;
- self.dropdownMenu.on('keydown', uibDropdownService.keybindFilter);
+ $document.on('keydown', uibDropdownService.keybindFilter);
});
});
} else {
- if (self.dropdownMenu) {
- self.dropdownMenu.on('keydown', uibDropdownService.keybindFilter);
- }
+ $document.on('keydown', uibDropdownService.keybindFilter);
}
scope.focusToggleElement();
diff --git a/src/dropdown/test/dropdown.spec.js b/src/dropdown/test/dropdown.spec.js
index 7a932f2c37..6f3b99d4e2 100644
--- a/src/dropdown/test/dropdown.spec.js
+++ b/src/dropdown/test/dropdown.spec.js
@@ -550,15 +550,17 @@ describe('uib-dropdown', function() {
function dropdown() {
return $compile('
')($rootScope);
}
+ function getFocusedElement() {
+ return angular.element(document.activeElement);
+ }
beforeEach(function() {
element = dropdown();
});
it('should focus first list element when down arrow pressed', function() {
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
clickDropdownToggle();
- triggerKeyDown(dropdownMenu, 40);
+ triggerKeyDown(getFocusedElement(), 40);
expect(element).toHaveClass(dropdownConfig.openClass);
var optionEl = element.find('ul').eq(0).find('a').eq(0);
@@ -566,9 +568,8 @@ describe('uib-dropdown', function() {
});
it('should not focus first list element when down arrow pressed if closed', function() {
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
- triggerKeyDown(dropdownMenu, 40);
+ triggerKeyDown(getFocusedElement(), 40);
expect(element).not.toHaveClass(dropdownConfig.openClass);
var focusEl = element.find('ul').eq(0).find('a').eq(0);
@@ -576,11 +577,10 @@ describe('uib-dropdown', function() {
});
it('should focus second list element when down arrow pressed twice', function() {
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
clickDropdownToggle();
- triggerKeyDown(dropdownMenu, 40);
- triggerKeyDown(dropdownMenu, 40);
+ triggerKeyDown(getFocusedElement(), 40);
+ triggerKeyDown(getFocusedElement(), 40);
expect(element).toHaveClass(dropdownConfig.openClass);
var focusEl = element.find('ul').eq(0).find('a').eq(1);
@@ -588,21 +588,19 @@ describe('uib-dropdown', function() {
});
it('should not focus first list element when up arrow pressed after dropdown toggled', function() {
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
clickDropdownToggle();
expect(element).toHaveClass(dropdownConfig.openClass);
- triggerKeyDown(dropdownMenu, 38);
+ triggerKeyDown(getFocusedElement(), 38);
var focusEl = element.find('ul').eq(0).find('a').eq(0);
expect(focusEl).not.toHaveFocus();
});
it('should focus last list element when up arrow pressed after dropdown toggled', function() {
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
clickDropdownToggle();
- triggerKeyDown(dropdownMenu, 38);
+ triggerKeyDown(getFocusedElement(), 38);
expect(element).toHaveClass(dropdownConfig.openClass);
var focusEl = element.find('ul').eq(0).find('a').eq(1);
@@ -610,10 +608,9 @@ describe('uib-dropdown', function() {
});
it('should not change focus when other keys are pressed', function() {
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
clickDropdownToggle();
- triggerKeyDown(dropdownMenu, 37);
+ triggerKeyDown(getFocusedElement(), 37);
expect(element).toHaveClass(dropdownConfig.openClass);
var focusEl = element.find('ul').eq(0).find('a');
@@ -622,13 +619,12 @@ describe('uib-dropdown', function() {
});
it('should focus first list element when down arrow pressed 2x and up pressed 1x', function() {
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
clickDropdownToggle();
- triggerKeyDown(dropdownMenu, 40);
- triggerKeyDown(dropdownMenu, 40);
+ triggerKeyDown(getFocusedElement(), 40);
+ triggerKeyDown(getFocusedElement(), 40);
- triggerKeyDown(dropdownMenu, 38);
+ triggerKeyDown(getFocusedElement(), 38);
expect(element).toHaveClass(dropdownConfig.openClass);
var focusEl = element.find('ul').eq(0).find('a').eq(0);
@@ -636,11 +632,10 @@ describe('uib-dropdown', function() {
});
it('should stay focused on final list element if down pressed at list end', function() {
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
clickDropdownToggle();
- triggerKeyDown(dropdownMenu, 40);
- triggerKeyDown(dropdownMenu, 40);
+ triggerKeyDown(getFocusedElement(), 40);
+ triggerKeyDown(getFocusedElement(), 40);
expect(element).toHaveClass(dropdownConfig.openClass);
var focusEl = element.find('ul').eq(0).find('a').eq(1);
@@ -652,23 +647,22 @@ describe('uib-dropdown', function() {
it('should close if esc is pressed while focused', function() {
element = dropdown('disabled');
- var dropdownMenu = element.find('[uib-dropdown-menu]');
$document.find('body').append(element);
clickDropdownToggle();
- triggerKeyDown(dropdownMenu, 40);
+ triggerKeyDown(getFocusedElement(), 40);
expect(element).toHaveClass(dropdownConfig.openClass);
var focusEl = element.find('ul').eq(0).find('a').eq(0);
expect(focusEl).toHaveFocus();
- triggerKeyDown(dropdownMenu, 27);
+ triggerKeyDown(getFocusedElement(), 27);
expect(element).not.toHaveClass(dropdownConfig.openClass);
});
describe('with dropdown-append-to-body', function() {
function dropdown() {
- return $compile('')($rootScope);
+ return $compile('foo')($rootScope);
}
beforeEach(function() {
@@ -676,11 +670,12 @@ describe('uib-dropdown', function() {
});
it('should focus first list element when down arrow pressed', function() {
+ $document.find('body').append(element);
clickDropdownToggle();
var dropdownMenu = $document.find('#dropdown-menu');
- triggerKeyDown(dropdownMenu, 40);
+ triggerKeyDown(getFocusedElement(), 40);
expect(dropdownMenu.parent()).toHaveClass(dropdownConfig.appendToOpenClass);
var focusEl = $document.find('ul').eq(0).find('a');
@@ -688,11 +683,12 @@ describe('uib-dropdown', function() {
});
it('should focus second list element when down arrow pressed twice', function() {
+ $document.find('body').append(element);
clickDropdownToggle();
var dropdownMenu = $document.find('#dropdown-menu');
- triggerKeyDown(dropdownMenu, 40);
- triggerKeyDown(dropdownMenu, 40);
- triggerKeyDown(dropdownMenu, 40);
+ triggerKeyDown(getFocusedElement(), 40);
+ triggerKeyDown(getFocusedElement(), 40);
+ triggerKeyDown(getFocusedElement(), 40);
expect(dropdownMenu.parent()).toHaveClass(dropdownConfig.appendToOpenClass);
var elem1 = $document.find('ul');