Hybrid View
-
19 Jun 2007 10:44 PM #1
[2.0] Modal dialogs can be bypassed
[2.0] Modal dialogs can be bypassed
Not sure if this has been covered already but modal dialogs can be bypassed by simply using the tab key to cycle through all the underlying links, linked images and form elements on the page. For example, if you open a modal dialog on top of a form, you can press tab until you can access the elements behind the modal dialog/mask.
This behavior has been replicated on FF2 and IE7 using 1.1b1 on Windows.
-
20 Jun 2007 12:26 AM #2
"modal" dialogs are just divs which have an opaque div placed under them that masks underlying elements from mouse events.
Can you think of a workaround?
Perhaps this before show:
and this after hide:Code:this.reEnable = []; Ext.fly(document.body).select("input select a button").each(function(el) { if (!el.dom.disabled) { el.dom.disabled = true; reEnable.push(el.dom); } });
?Code:Ext.each(this.reEnable, function(el) { el.disabled = false; });
Might be a bit of a performance hit finding and disabling every <input>, <a>, <select> and <button>.
Should <map>/<area> be added to the DomQuery selector?
Perhaps it could be added but made optional?
-
20 Jun 2007 1:44 AM #3
Thanks, Animal. I haven't deeply pondered on a workaround yet, as I was half-hoping that this issue has already been addressed. Your workaround seems feasible and sure worth the try, though it might indeed have some performance degradation on complex layouts/forms in the background, and also complications in nested modal windows. What I was pondering on was to listen for tab key presses and allow focus switching only within the elements of the current modal window (dialog or message box).
-
20 Jun 2007 9:45 AM #4
If you wanted to try something like this, you'd want to preserve the original disabled state of each element, rather than simply enabling them all after hide.
-
20 Jun 2007 1:51 PM #5
I think you'd also want to run that first chunk of code *after* show (rather than before) so that even if there is a delay in disabling all the elements, the user will not notice it.
-
20 Jun 2007 2:00 PM #6
Yeah, and this might cause some complications in nested modal windows if not done right.
I'm still leaning towards simply listening for tab key presses and limit the focus cycling/switching within the elements of the current modal window.
A real modal window shouldn't be circumvented like this since this can actually break the application. I'm actually surprised that this issue hasn't been addressed or escalated.
-
20 Jun 2007 2:05 PM #7
A "real modal window" would also not be a div inside a page

-
27 Jun 2007 3:22 AM #8
The code I posted only re-enables those items that were disabled on dialog show.
I'd say that's the best way to do it. It is basically what's needed. All input items under the mask to be disabled.
Another option is a document keydown handler enabled when a modal dialog is shown (perhaps by the DialogManager) which stops any keydown event if the target is not within an element of selector ".x-dlg#" + topMostDialog.id
Where the DialogManager knows which is the topmost Dialog.
Code:if (!Ext.fly(event.getTarget()).findParent(".x-dlg#" + topmostDialog.id, document.body)) { event.stopEvent(); }
-
27 Jun 2007 3:35 AM #9
Right you are. That's what I get for skimming

I was looking at Element.mask -- I think a truly generic solution should block the keyboard for any section of the DOM that is masked, not just beneath a dialog/window. One complication is that different areas within the source do masking in slightly different ways (not everything goes through Element.mask, some components create their own masks manually). The selector filtering approach might work if you can filter for anything beneath the mask el, but I haven't studied the code enough yet to know how that would work.
-
12 Mar 2008 6:44 AM #10
[2.0.1] link to thread in 2.0 bug forum


Reply With Quote