diff options
author | Jörn Zaefferer <joern.zaefferer@gmail.com> | 2012-10-26 10:59:41 -0400 |
---|---|---|
committer | Jörn Zaefferer <joern.zaefferer@gmail.com> | 2012-11-26 10:26:11 +0100 |
commit | 8ee8046c029354501bc6d1690b3ac84edf23efd7 (patch) | |
tree | d5b2cdeb070ce495d48741746dfad3afd01d6b57 /ui | |
parent | 2a887e43213c4dbb21509b670cf5dc8ac2c67573 (diff) | |
download | jquery-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.js | 41 |
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" ) ); |