I would like to accept William Niu's answer, but there is a flaw that prevents it from working in my web application. If the first or last element in the dialog is a radio button, then this code won't work in IE. The browser will tab to the radio button group one time.
If the selected radio button is one that the browser highlights when the user tabs to the radio button group, then this code will work. However, the selected radio button is not the one the browser highlights when the user tabs to the radio button group, then the focus will be lost from the dialog.
Here is some code I've written that solves this problem:
function _bindTabKeyForDialog(dialogId) {
var tabbable = $('#' + dialogId).find(':tabbable');
var firstElement = $(tabbable).filter(':first');
var lastElement = $(tabbable).filter(':last');
var firstGroup = (firstElement[0].type !== 'radio') ?
firstElement :
tabbable.filter("[name='" + firstElement[0].name + "']");
var lastGroup = (lastElement[0].type !== 'radio') ?
lastElement :
tabbable.filter("[name='" + lastElement[0].name + "']");
$(document).unbind('keydown.' + dialogId);
$(document).bind('keydown.' + dialogId, function (e) {
if (e.keyCode == 9) {
if ($(e.target).is(lastGroup) && !e.shiftKey) {
firstGroup.first().focus();
e.preventDefault();
}
else if ($(e.target).is(firstGroup) && e.shiftKey) {
lastGroup.first().focus();
e.preventDefault();
}
}
});
} // end _bindTabKeyForDialog
As you can see, I change William's first
and last
variables to groups of elements. If the first or last tabbable element in the dialog is a radio button, then it will include all radio buttons with the same name.
Otherwise, this code functions the same as William's code.