Programming is a wonderful mix of art and science; source code is both a poem and a math problem. It should be as simple and elegant as it is functional and fast. This blog is about that (along with whatever else I feel like writing about).

Thursday, January 03, 2008

Modal Dialog Box in Javascript

Occasionally you want to be able to pop up a modal dialog box over your web page, so you can force the user to enter something before they continue. You could just use confirm(), but that's pretty lame and doesn't allow you to exercise much control over the user's input options. Yes/No? Okay/Cancel? Lame.

Well, the way to do it, of course, is with a transparent div! That'd be the background, and then you have another div that you put right in the middle of the screen, mimicking a popup window. You'll be able to see through the background div (kind of), but you can't click through it ... which makes it perfect.

First, you need to throw in the HTML:

<div id="modalBackgroundDiv" class="modalPopupTransparent" style="display: none;"> </div>

<div id="modalWindow" class="modalPopupWindow" style="display: none; width: 560px;">
It's awesome that you can put whatever you want in here.
</div>

Then you need some CSS to make it so they actually work as planned:

div.modalPopupTransparent {
filter: alpha(opacity=75);
-moz-opacity: .75;
background: #CCCCCC;
position: absolute;
top: 0px;
left: 0px;
}

div.modalPopupWindow {
position: absolute;
background-color: #FFFFFF;
border: 2px solid black;
padding: 8px;
text-align: left;
}

The most important thing here is that the background div's style has its opacity set to 75%. It has to be done twice because IE and Firefox use different commands for this. (Typical.) The second most important thing to notice is the absolute positioning. That's what allows them to display on top of everything else. It's not that useful if your transparent div shows up below the page, is it?

It's also not that useful if the modal dialog has no functionality and can't pop up. Which is why we now have to add in the Javascript:

function openModalWindow() {
var div = $('modalWindow');
var bgDiv = $('modalBackgroundDiv');

var docDim = Element.getDimensions(document.body);

//get the size of the window and calculate where the box should be placed
var wDim = getBrowserWindowSize();
var dDim = Element.getDimensions(div);

div.style.top = ((wDim.height - dDim.height*2) / 2) + 'px';
div.style.left = ((wDim.width - dDim.width) / 2) + 'px';

if (docDim.height > wDim.height) {
wDim.height = docDim.height;
}

bgDiv.style.width = wDim.width + 'px';
bgDiv.style.height = wDim.height + 'px';

Element.show(div);
Element.show(bgDiv);
}

function closeModalWindow() {
Element.hide('modalWindow');
Element.hide('modalBackgroundDiv');
}

function getBrowserWindowSize() {
var winW = 630, winH = 460;

if (parseInt(navigator.appVersion)>3) {
if (navigator.appName=="Netscape") {
winW = window.innerWidth;
winH = window.innerHeight;
}
if (navigator.appName.indexOf("Microsoft")!=-1) {
winW = document.body.offsetWidth;
winH = document.body.offsetHeight;
}
}

var rval = {
width: winW,
height: winH
};

return rval;
}

To open the modal window, the first thing we need to do is grab a reference to the window, the background, and the document body. We then determine the size of the visible browser window (using a custom function, shown above) and the size of the modal dialog (using Prototype's handy method).

Since we want the transparent background to cover the entire page (not just what's visible), we set the height of the background to be the height of the document body instead of the browser window -- if necessary. That way the user can't scroll down and click something lower on the page if there's a modal dialog up.

Then we center the popup, make the background as big as it should be, and display them. Simple enough. Similarly, in order to close the window, we just hide both elements.

And there you have it. A nice, simple modal dialog, with a transparent gray background that dims out everything else on the page so the user knows what to focus on. I wouldn't use it too often, but in some cases it can be exactly what you want.

Enjoy!

13 comments:

Anonymous said...

Hi,

I could not use this method to show a dialog.
Can you instruct how to call the function to show the dialog ?

Sean Schulte said...

You need to use the Javascript functions to open/close the window.

In this example, it's the openModalWindow() function. You just need to call that function ... one way to do it would be with a link:

<a href="javascript:openModalWindow();">Click<a>

Bear in mind that these functions use Prototype for some of their DOM manipulation, so you'll have to get that and include the prototype.js file.

Hope that helps!

Unknown said...

In this example what is The Element??

Sean Schulte said...

I may be making an incorrect assumption here, but the Element.show() and Element.hide() stuff is from the Prototype library.

It's the JS framework I use, but you can feel free to substitute jQuery or YUI as you please (note that if you do, you'll have to change a bit of other code in here as necessary).

Ian Spence said...

I have a long page, say 4-5 pages long. If I click on the link to invoke the modal window, it appears on page 1. I would like it to appear on the current view...

any ideas?

Anonymous said...

How can i set the position of the div right of the mouse cursor? Namely i want to click some buttons/images and the new dialog/form appears right there.
Thanks

Anonymous said...

awesome!
i have been looking for a simplest "working" modal dialog for hours ...

your solution is really good ... it could be better without prototype.js

the getBrowserWindowSize() doesn't seem to be working in well in IE ...

thanks a lot!

Hugo Alvarado said...

Hello, I plan to use this code a little bit modified for a production web application, i want to know what kind of license do i need, thanks for this great example.

Sean Schulte said...

Hugo:

Just go ahead and use it. There's no license on this code.

I'd appreciate it if you attributed it to me in the comments, but you don't HAVE to.

Also, send me a link once the web application is live -- I'd be interested to see it in action!

Thanks.

Hugo Alvarado said...

That's really nice of you, i appreciate it and believe me i will give YOU the credits, because i'm a Software Engineer too and i feel the same, nevertheless i think you wont be able to see it cause the app its more like self-employee of a company, so has no public access :( but trust me ;) looks great :) Thank you!

Anonymous said...

hi Sean,
your code is very helpful.
i am using it to display the search results.
For some search results there isnt much of data, so it displays in middle of page, but few results have more data, and it goes beyond the page and upwards, how do i solve this?

And also there are many links on the my page, and wen the modal is diaplayed a few of them are inaccesible, but there are a few which i can still access, even while the dialog is still open, how do i solve this?

Anonymous said...

dear u rocks i searched for many and find diffrent codes for the same thing but u have written the simple way to do that
thanks
a bunch of thanks

Anonymous said...

You saved me! That worked great when a lot of the prototype/jquery versions were giving problems.

Thanks!