Eden Ridgway's Blog

.Net and Web Development Information

  Home :: Contact :: Syndication  :: Login
  105 Posts :: 1 Stories :: 78 Comments :: 3 Trackbacks

Search

Article Categories

Archives

Post Categories

Development

General

/SubText/Images the site is broken and don't bother paying attention to the popup blocker telling them that a popup has just just been blocked. One of our client's asked us to find a solution that would reduce this support overhead.

My initial thoughts were that we could simply check to see if we got a null reference back when doing a window.open or window.showModalDialog call and then display a JavaScript alert telling users to switch off the popup blocker. I had however come across an ASP.Net Modal Panel Control solution by Brendan Tompkins a while ago that I thought might also be useful. The thing about this control however is that it is not modal at all. So I decided to whip up my own proof of concept solution using a similar idea to Tompkins (albeit not implement a .Net control just yet).

Another problem that the control will experience, like any absolutely positioned div, is that select lists still render over the element. To stop this from happening, developers often place the content they are trying to display in an iframe. This is a little messy since you either need to use scripting to inject the contents into the iframe or create another page that is hosted in the Iframe. There is another solution however that still uses an Iframe, but your content need not be in it. If you absolutely position your iframe and make it transparent using a directX filter you can hide the select list automatically.

In order to create a modal popup panel, all I need to do then is create an absolutely positioned div and an iframe that displays over the whole page that effectively blocks interaction with it. So I first created the style for the Iframe for the modal greyed out effect, like this:

<style>
.PopupPanelModalArea
{
left
: 0;
top
: 0;
height
: 100%;
width
: 100%;
position
: absolute;
background-color
:silver;
filter
: progid: DXImageTransform.Microsoft.Alpha(opacity=60);
z-index
: 99;
-moz-opacity
: 0.60;
}
</
style>

I then defined the popup with the Iframe nested inside of it so that I could easily toggle the modal popup on and off:

<div id="PopupPanel">
<iframe class="PopupPanelModalArea" frameborder="0" id="PopupPanelModalArea"></iframe>

<div class="PopupPanel" style="height:200px; width:400px">

<p class="TitleBar">
Popup Panel Title Bar
</p>

<p class="ContentArea">
Even though the underlying page is disabled you can use the controls in this area
<br/>
<input type="Button" value="Close Popup Panel" onclick="TogglePopupPanel()" />
</
p>
</div>
</div>

There is however one problem with this approach, you can still get around the Iframe using the keyboard. To solve this when the popup is displayed, you set focus to the modal Iframe and ensure that whenever the underlying page receives focus that focus is shifted back on to the iframe. The logic to do this is placed in the TogglePopupPanel function:

<script language="JavaScript">
function TogglePopupPanel()
{
var panelContainer = document.getElementById("PopupPanel");

if
(panelContainer.style.display == "none")
{
panelContainer.style.display
= "";
document
.getElementById('PopupPanelModalArea').focus();
document
.body.onfocus = function() { document.getElementById('PopupPanelModalArea').focus(); };
}
else
{
panelContainer.style.display
= "none";
document
.body.onfocus = function() { return true; };
}
}
</script>

The one problem with this at the moment is back tabbing still allows focus back on to the page. I'm currently looking at an elegant solution for this and I'm sure I'll have something for this shortly. The solutions I want to avoid are:

  1. Looping through all the controls and applying an onfocus script
  2. Setting the TabIndexes of the controls to a negative value.

Here is the current version in action: PanelPopupDemo.htm (works in FireFox too)

posted on Saturday, September 24, 2005 8:21 AM
Comments have been closed on this topic.