diff --git a/src/modal/modal.js b/src/modal/modal.js
index 356299da8b..23e81007dd 100644
--- a/src/modal/modal.js
+++ b/src/modal/modal.js
@@ -261,9 +261,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p
var previousTopOpenedModal = null;
//Modal focus behavior
- var tabableSelector = 'a[href], area[href], input:not([disabled]), ' +
- 'button:not([disabled]),select:not([disabled]), textarea:not([disabled]), ' +
- 'iframe, object, embed, *[tabindex], *[contenteditable=true]';
+ var tabbableSelector = 'a[href], area[href], input:not([disabled]):not([tabindex=\'-1\']), ' +
+ 'button:not([disabled]):not([tabindex=\'-1\']),select:not([disabled]):not([tabindex=\'-1\']), textarea:not([disabled]):not([tabindex=\'-1\']), ' +
+ 'iframe, object, embed, *[tabindex]:not([tabindex=\'-1\']), *[contenteditable=true]';
var scrollbarPadding;
function isVisible(element) {
@@ -599,7 +599,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p
if (modalWindow) {
var modalDomE1 = modalWindow.value.modalDomEl;
if (modalDomE1 && modalDomE1.length) {
- var elements = modalDomE1[0].querySelectorAll(tabableSelector);
+ var elements = modalDomE1[0].querySelectorAll(tabbableSelector);
return elements ?
Array.prototype.filter.call(elements, function(element) {
return isVisible(element);
diff --git a/src/modal/test/modal.spec.js b/src/modal/test/modal.spec.js
index 1e43b037d2..dff247e966 100644
--- a/src/modal/test/modal.spec.js
+++ b/src/modal/test/modal.spec.js
@@ -807,6 +807,52 @@ describe('$uibModal', function() {
initialPage.remove();
});
+
+ it('should change focus to next tabbable element when tab is pressed', function() {
+ var initialPage = angular.element('Outland link');
+ angular.element(document.body).append(initialPage);
+ initialPage.focus();
+
+ open({
+ template:'a' +
+ 'bc' +
+ '',
+ keyboard: false
+ });
+ $rootScope.$digest();
+ expect($document).toHaveModalsOpen(1);
+
+ $('#tab-focus-link3').focus();
+ expect(document.activeElement.getAttribute('id')).toBe('tab-focus-link3');
+
+ triggerKeyDown(angular.element(document.activeElement), 9, false);
+ expect(document.activeElement.getAttribute('id')).toBe('tab-focus-link1');
+
+ initialPage.remove();
+ });
+
+ it('should change focus to previous tabbable element when shift+tab is pressed', function() {
+ var initialPage = angular.element('Outland link');
+ angular.element(document.body).append(initialPage);
+ initialPage.focus();
+
+ open({
+ template:'a' +
+ 'bc' +
+ '',
+ keyboard: false
+ });
+ $rootScope.$digest();
+ expect($document).toHaveModalsOpen(1);
+
+ $('#tab-focus-link1').focus();
+ expect(document.activeElement.getAttribute('id')).toBe('tab-focus-link1');
+
+ triggerKeyDown(angular.element(document.activeElement), 9, true);
+ expect(document.activeElement.getAttribute('id')).toBe('tab-focus-link3');
+
+ initialPage.remove();
+ });
});
describe('default options can be changed in a provider', function() {