aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorJörn Zaefferer <joern.zaefferer@gmail.com>2012-10-26 10:59:41 -0400
committerJörn Zaefferer <joern.zaefferer@gmail.com>2012-11-26 10:26:11 +0100
commit8ee8046c029354501bc6d1690b3ac84edf23efd7 (patch)
treed5b2cdeb070ce495d48741746dfad3afd01d6b57 /ui
parent2a887e43213c4dbb21509b670cf5dc8ac2c67573 (diff)
downloadjquery-ui-8ee8046c029354501bc6d1690b3ac84edf23efd7.tar.gz
jquery-ui-8ee8046c029354501bc6d1690b3ac84edf23efd7.zip
Dialog: Keep focus inside modal dialog, by handling focus events on elements outside of it
Diffstat (limited to 'ui')
-rw-r--r--ui/jquery.ui.dialog.js41
1 files changed, 30 insertions, 11 deletions
diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js
index 892dd72b0..ed1e55beb 100644
--- a/ui/jquery.ui.dialog.js
+++ b/ui/jquery.ui.dialog.js
@@ -282,8 +282,7 @@ $.widget("ui.dialog", {
return;
}
- var hasFocus,
- options = this.options,
+ var options = this.options,
uiDialog = this.uiDialog;
this.opener = $( this.document[ 0 ].activeElement );
@@ -294,22 +293,26 @@ $.widget("ui.dialog", {
this.moveToTop( null, true );
this._show( uiDialog, options.show );
+ this._focusTabbable();
+
+ this._isOpen = true;
+ this._trigger( "open" );
+ this._trigger( "focus" );
+
+ return this;
+ },
+
+ _focusTabbable: function() {
// set focus to the first tabbable element in the content area or the first button
// if there are no tabbable elements, set focus on the dialog itself
- hasFocus = this.element.find( ":tabbable" );
+ var hasFocus = this.element.find( ":tabbable" );
if ( !hasFocus.length ) {
hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
if ( !hasFocus.length ) {
- hasFocus = uiDialog;
+ hasFocus = this.uiDialog;
}
}
hasFocus.eq( 0 ).focus();
-
- this._isOpen = true;
- this._trigger( "open" );
- this._trigger( "focus" );
-
- return this;
},
_keepFocus: function( event ) {
@@ -318,7 +321,7 @@ $.widget("ui.dialog", {
isActive = this.uiDialog[ 0 ] === activeElement ||
$.contains( this.uiDialog[ 0 ], activeElement );
if ( !isActive ) {
- this.uiDialog.focus();
+ this._focusTabbable();
}
}
event.preventDefault();
@@ -659,6 +662,22 @@ $.extend( $.ui.dialog.overlay, {
// reuse old instances due to IE memory leak with alpha transparency (see #5185)
oldInstances: [],
create: function( dialog ) {
+ if ( this.instances.length === 0 ) {
+ // prevent use of anchors and inputs
+ // we use a setTimeout in case the overlay is created from an
+ // event that we're going to be cancelling (see #2804)
+ setTimeout(function() {
+ // handle $(el).dialog().dialog('close') (see #4065)
+ if ( $.ui.dialog.overlay.instances.length ) {
+ $( document ).bind( "focusin.dialog-overlay", function( event ) {
+ if ( !$( event.target ).closest( ".ui-dialog").length ) {
+ event.preventDefault();
+ $( ".ui-dialog:visible:last .ui-dialog-content" ).data( "ui-dialog" )._focusTabbable();
+ }
+ });
+ }
+ }, 1 );
+ }
var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay ui-front" ) );