Tom Lauck’s Deseloper.org

A Simple Modal

author: tom

Updated – Version Available

A Simple Modal – Redux

[See a demo here]

Modal windows seem to be the rage these days and somewhat synonymous with “Web 2.0.” And yes, options exist, whether it be Lightbox, Thickbox, or .NET AJAX — to name a few. Recently, Facebox has emerged as a very promising contender. The aforementioned plugins/widgets have proven their usefulness to many developers during their life course. In fact they one might even go so far as to deem “standard” to the plugin of choice.

Yet, what if a scenario arises where you do not need such full featured capability? After all, most of the plugins out there come with their own CSS along with the JavaScript. This is not to say that CSS wouldn’t be necessary if one were to create a homegrown solution. The fact remains that their is still integration work involved.

Therefore, my aim in this post is to illustrate a simple example of leveraging the jQuery framework to create a simple iFrame modal window. Of course a polished plugin will be more robust, however, robust is at times overkill. It is at that point where simplicity comes into play and thus the forthcoming example.

Defining the Basics

First we create an object in JavaScript to encapsulate some core methods and properties that we could potentially reuse.

var modalWindow = {
	parent:"body",
	windowId:null,
	content:null,
	width:null,
	height:null,
	close:function()
	{
		$(".modal-window").remove();
		$(".modal-overlay").remove();
	},
	open:function()
	{
		var modal = "";
		modal += "<div class=\"modal-overlay\"></div>";
		modal += "<div id=\"" + this.windowId + "\" class=\"modal-window\" style=\"width:" + this.width + "px; height:" + this.height + "px; margin-top:-" + (this.height / 2) + "px; margin-left:-" + (this.width / 2) + "px;\">";
		modal += this.content;
		modal += "</div>";	

		$(this.parent).append(modal);

		$(".modal-window").append("<a class=\"close-window\"></a>");
		$(".close-window").click(function(){modalWindow.close();});
		$(".modal-overlay").click(function(){modalWindow.close();});
	}
};

Notice that only three CSS classes need to be defined, “.modal-window”, “.modal-overlay”, and “.close-window”. Because of the fact that we are trying to keep things simple, I’ve decided not to check to null’s in required properties (windowId, content, width, height).

Basic Design

Next the three classes from above need to be defined. The “.modal-overlay” class is the layer that covers the current view and serves as a backdrop for the modal window. “.modal-window” is obviously the window itself. In this case, the modal-window class is very generic since we will rely on the styling in the transparent iFrame for design. Lastly, I chose to implement a close graphic which is displayed using the “.close-window” class. Again, this is very basic.

.modal-overlay
{
	position:fixed;
	top:0;
	right:0;
	bottom:0;
	left:0;
	height:100%;
	width:100%;
	margin:0;
	padding:0;
	background:#fff;
	opacity:.75;
	filter: alpha(opacity=75);
	-moz-opacity: 0.75;
	z-index:101;
}
.modal-window
{
	position:fixed;
	top:50%;
	left:50%;
	margin:0;
	padding:0;
	z-index:102;
}
.close-window
{
	position:absolute;
	width:32px;
	height:32px;
	right:8px;
	top:8px;
	background:transparent url('/examples/modal-simple/close-button.png') no-repeat scroll right top;
	text-indent:-99999px;
	overflow:hidden;
	cursor:pointer;
	opacity:.5;
	filter: alpha(opacity=50);
	-moz-opacity: 0.5;
}
.close-window:hover
{
	opacity:.99;
	filter: alpha(opacity=99);
	-moz-opacity: 0.99;
}

The Grand Opening

Now that we have set some basic styles and defined our core functionality, we can open a new modal window to display our iframe.

var openMyModal = function(source)
{
	modalWindow.windowId = "myModal";
	modalWindow.width = 480;
	modalWindow.height = 405;
	modalWindow.content = "<iframe width='480' height='405' frameborder='0' scrolling='no' allowtransparency='true' src='" + source + "'></iframe>";
	modalWindow.open();
};

Implement

<a href="/example/modal-simple/modal.html" target="_blank" onclick="openMyModal('/example/modal-simple/modal.html'); return false;">Click here to open</a>

Implementation is simple, just make a call to the method created earlier with the source of the modal window.

Beyond Simple ‘Modaling’

As stated at the outset, this post was meant to illustrate a bare bones and simple example of a modal window. If you wanted to extend the functionality for example, it would be quite simple to create more “openMyModal” methods to suit needs. So if Facebox or Thickbox are too much for your application, why not try the simple approach?

Updated – Version Available

A Simple Modal – Redux

56 Responses

date: April 30th, 2008

Demo would be nice.
I’ll give this a shot, thanks

spoken by: Jeremy

date: April 30th, 2008

@jeremy I posted a demo at http://deseloper.org/examples/modal-simple/

Enjoy

spoken by: tom

date: April 30th, 2008

Hi Tom,
First of all congrats for such a nice simple work – infact I am also tired of seeing such heavyweight modal implementations. The only problem is the demo is not working in IE 6.0 – i think the css ‘top:0; right:0; bottom:0; left:0;’ is the problem.

spoken by: Sumanta Ghosh

date: May 1st, 2008

@sumanta Thank you for bringing the ie6 issue to my attention. However, because I hate code bloat, css expressions, and ie6 almost equally, I chose not to include the hack to get everything working in ie6.

To get everything going though, simply add these styles:

* html .modal-overlay
{
	position: absolute;
	height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
}
* html .modal-window
{
	position:absolute;
}

I’ve updated the demo as well.

spoken by: tom

date: August 5th, 2008

Excellent and clean article. Something I don’t see lately.

spoken by: Draco

date: September 10th, 2008

hi,

I have this error $(this.parent).append is not a function.

what can i do?

spoken by: abdala

date: September 16th, 2008

Hi,

The modal script moves the target content outside of the original dom element. This is a issue for me as I am forced to use asp.Net forms.

Using .Net forms there can be only 1 form element on the page. So when the modal content is moved it is moved outside the 1 and only form element, therefore my submits buttons inside the modal don’t work anymore.

I have change the source on line 233 to read
.appendTo(this.dialog.parentNode);

Can you see any issues with this?

Regards,

Mark

spoken by: Mark

date: October 10th, 2008

Hi –
I like this script. My question is, how do I close this window programmatically? I want the user to click on a Continue button, do some work in the background, close the modal window and refresh the parent window. I tried this code:

self.parent.location.reload();
self.close();

Any suggestions?

spoken by: kmitchell

date: October 22nd, 2008

@abdala not sure about that, what version of jQuery are you using? I honestly haven’t looked at this post in some time.

@mark you could also clone your content. there are other advantages to putting the modal content at the end of the dom, depending on what you are doing.

@kmitchell it looks like you are refreshing the location before you are closing the modal window. In the example above, there is a close() method.

spoken by: tom

date: October 31st, 2008

parent.document.location.reload(); it should solve the problem

spoken by: mariusj

date: November 29th, 2008

This is really cool and simple to implement. I’ve tried plenty of jquery modal plugins, but always found them too complex or just too bloated.
This is perfect. thanks!

spoken by: Sand

date: December 23rd, 2008

Great post, this helped me get started on making a custom Modal for one of my projects. I wanted it to be completely controlled with jQuery code so I changed a lot of code.

spoken by: Gorkfu

date: January 7th, 2009

Thanks a lot! That was just what I was looking for.

spoken by: Stjepan

date: January 18th, 2009

Tom, first of all thank you for your article. I had some problems with web based popups and this article solved everything:)
But i have question. At the top-right of the page there is an image that closes the popup. And it is created by close-window css class. Now i want to use a link at the bottom of popup and closes the popup. In your code there is a close function. How can i call that close function from the popup, when user presses my close link?

spoken by: Ararat

date: January 24th, 2009

[...] Download: http://deseloper.org/read/2008/04/a-simple-modal/ [...]

spoken by: Editors Choice» Blog Archive » A Simple Modal

date: January 30th, 2009

Love this post, I have been looking for something like this for a really long time now. Thank you.

I have extended your original code slightly: I have changed the URL and function that opens the modal slightly because I find that it was repeating code which makes it complex to edit. Here is the updated link and function:

Open modal

var openAModal = function(source, width, height)
{
modalWindow.windowId = “mailToAFriend”;
modalWindow.width = width;
modalWindow.height = height;
modalWindow.content = “”;
modalWindow.open();
};

You will notice that I added the width and height of the modal window into the URL and I have also taken out the repeating where you duplicated the width and height manually into the iFrame. I have also removed the need to duplicate the URL in the hyperlink by putting a # in the href=”".

I left the base javascript in place as it seems to work quite nicely.

Thanks again. :)

spoken by: theamoeba

date: January 30th, 2009

woops, sorry i see that there is no code filter on this comment module, that Open modal link is not supposed to be there. it is supposed to show:

<a href=”#” target=”_blank” onclick=”openAModal(‘path/to/modal.html’, 480, 405); return false;”>Open modal</a>

spoken by: theamoeba

date: January 30th, 2009

how to remove the overlay window on submit

spoken by: krishna

date: February 6th, 2009

Nice tutorial there!
Im trying to add some “slide” effects to the box once it shows/hide.
No pregress so far though :(

Any idea on how to do this?

Cheers!

spoken by: LimpMan

date: February 6th, 2009

Those of you who have questions, feel free to contact me offline. Please use either this site’s contact form or an option listed on my personal site.

spoken by: tom

date: February 14th, 2009

Tom – First off, your simple modal script is terrific. Very simple to use and does the job really well. One thing… the modal doesn’t vertically center on IE 6 properly. I created a sample page with lots of “Lorem Ipsum” text so the whole page scrolls. If the onclick button or link is located near the top of the page, the modal is severely cut off. I copied your sample page verbatim… just added lots of text. I’m going to play around with the css a little but I was wondering if you knew of any other quick hacks for this. Thanks.

spoken by: brian

date: February 16th, 2009

Very nice piece of work. One simple thing that I added helps the iframe load fresh every time. Iframes tend to stay on the last frame no matter how many times you prompt for a fresh window, so the follwoing ensures a fresh load each time:

under this line:
var modal = function(source) {
put this:
randnum = Math.random();

Then in the iframe bit, put this:

<iframe id=’”+ randnum +”‘ width=’480′

This will load the iframe with a new, randomly named ID each time, thus forcing the iframe to fully refresh.

Great script, great work!

spoken by: Ric

date: February 17th, 2009

Tom, Great job!! I really like your script and I try to make it work for me.
I encountered once thing when using IE6.0 (same as Brian’s above)).

(1) The modal window does not vertically center on IE 6 (horizontally okay)
(2) Select boxes are shining through the overlay

Do you have some nice IE hack in mind which we could mak use of. Thanks a lot in advance.

spoken by: Markus

date: February 17th, 2009

@markus and @brian Have you implemented the CSS expression I posted in a previous comment specific to IE6?

spoken by: tom

date: February 18th, 2009

@Tom, Thanks for feedback! Yes I included your CSS Expression (your post May 1st, 2008) into the example. However, I am still seeing selection boxes shining through and the window is poping up always at the top of the page.
I also tried to apply the ideas which jquery IE-hack “.bgiframe()” is using but up to now I could not solve the IE6.0 issue.
Thanks a lot for your feedback!
Markus

spoken by: Markus

date: February 18th, 2009

I have created the form using the modal window and when submitted the the form disappears but the window closes how to remove that?

spoken by: krishna

date: February 19th, 2009

Tom, first of all thank you for your article. I had some problems with web based popups and this article solved everything:)
But i have question. At the top-right of the page there is an image that closes the popup. And it is created by close-window css class. Now i want to use a link at the bottom of popup and closes the popup. In your code there is a close function. How can i call that close function from the popup, when user presses my close link?

spoken by: Ararat

date: February 19th, 2009

@markus and @brian Give this a try in your style definition for * html .modal-window

* html .modal-window
{
        position:absolute;
        top:expression(document.documentElement.scrollTop + (document.documentElement.clientHeight / 2) + 'px');
}
spoken by: tom

date: February 19th, 2009

@ararat You could do something like this on the onclick

onclick="self.parent.modalWindow.close(); return false;"
spoken by: tom

date: February 20th, 2009

thanks tom, it worked

spoken by: Ararat

date: March 4th, 2009

Is there a way to display a modal window right before the user leaves the page?

spoken by: Kyle

date: March 12th, 2009

is there a way to add a preloader like on thickbox?

spoken by: junu

date: April 2nd, 2009

Thanks Tom!
This is very cool and nice example but problem is that when you click any where out side of iframe window,window disappears.How can we solve this problem ???

Thanks in advance !

spoken by: Ashish

date: April 6th, 2009

Your tutorial was very helpfull, and well explain.

Thanks, for sharing

spoken by: Hector

date: April 10th, 2009

The close()-function needs a little re-work:
In Opera jQuery’s remove() won’t work well.
Instead of $(“.modal-window”).remove(); use somethink like $(“.modal-window”).fadeOut(“fast”,function(){$(‘.modal-window’).unbind().remove();});

spoken by: Heiko

date: April 21st, 2009

Is that possible to allow resize option for the modal window using ui.resizable js?

please let me know how to do this?

regards
pragan

spoken by: pragan

date: May 19th, 2009

Looking for a Modal Window which can slide when its opend and dosen’t close the modal window when clicked on the gry area.

spoken by: padma

date: May 19th, 2009

[...] em Contato</a> Caso você queira saber mais sobre janelas modais, acesse: A Simple Modal JQuery modal dialog [...]

spoken by: Utilizando o plugin SimpleModal Contact Form (SMCF) | Vinícius de Paula

date: June 8th, 2009

How can i implement this if i want the dialog to opens when the page loads. Not triggered by an anchor like in the example??

Thx.

spoken by: Jmc

date: June 17th, 2009

Thanks for the great article, exactly what I was looking for to use in combination with creating a “hulu” light dimming effect for a video site.

Cheers!

spoken by: Chris Robinson

date: July 10th, 2009

I tried implementing both posts for fixing select menus showing through in IE6, but they are still showing through. Has anyone made this successfully work over select menus in IE6?

spoken by: PerfectWeb

date: July 10th, 2009

@perfectweb you would need to insert a fake iframe over the select box’s in IE6. Ex:

if (document.all && document.getElementById) {
	if (document.compatMode && !window.XMLHttpRequest) {
		modal += '<iframe src="BLOCKED SCRIPT\'&lt ;html>&lt ;/html&gt ;\';" scrolling="no" frameborder="0" class="modal-overlay"></iframe>';
	}
}
spoken by: tom

date: September 9th, 2009

Hi Tom, thanks for the lesson.

I’ve made a little ammendment to squeeze every byte out of the code:

Jquery lets one use multiple selectors, separated by a comma. So i’ve replaced the close event with just…

$(“.close-window,.modal-overlay”).click(function(){
$(“.modal-window,.modal-overlay”).remove();
});

Cheers

spoken by: Drew81

date: September 13th, 2009

Demo does not work in IE 6… to bad.. looking for a allround implemention..

spoken by: martijn

date: September 17th, 2009

@martijn – I have included IE6 hacks in the comments to this post. Please look there.

spoken by: tom

date: September 22nd, 2009

Please click on the Mission part of the image. In IE, the modal window somehow appears behind the JW Player being used on the page to play FLVs. It works like a charm in all other browser. It is still being worked on so you do not see the image to close the window.

Is there any way to make it work in IE? So that the modal window is over the FLV player instead of appearing behind it.

spoken by: Akbar Ehsan

date: September 22nd, 2009

Sorry , here is the link:

http://www.ivytech.edu/acceleratinggreatness/

spoken by: Akbar Ehsan

date: September 23rd, 2009

Great job!

Although, a few notices and improvements:

1) any version of IE crashes on Windows 7 x64 if I click on an overlay-window to close the modal window. It crashes in the close() function on the following line of code:
$(“.modal-overlay”).remove();
It seems that it crashes because remove() function also removes all event handlers for selected entity and at the same time we are executing the code inside Click event handler of that entity.
So, I changed this line to:
setTimeout(function() { $(“.modal-overlay”).remove(); }, 0);
and now it works fine.

2) If you want modal dialog to fade in, you can add the following code after $(this.parent).append(modal); line:

$(“.modal-overlay”).css({opacity: 0}).animate({opacity: 0.75});
$(“.modal-window”).hide().fadeIn();

But there is one problem: the Close button will flash when fading in. Maybe it’s better to remove it or disable fading in for a modal-window.

3) If you see that modal-window is scrolled when you scroll the page in IE (for example if you scroll main page down, modal-window goes up) it means that you forgot to add DOCTYPE for you page, so add it:

4) If you want to add a possibility to close the modal window by pressing escape key, add Keyup event handler for a document object:

$(document).keyup(function(e)
{
if(e.keyCode == 27 && shown)
{
modalWindow.close();
}
});

you can see that I’ve added the “shown” variable to prevent meaningless calls to modalWindow.close() method if modal window is already removed. Initially it’s false, it’s set to true in the open() function and it’s set to false in the close() function.

spoken by: Pavel

date: September 23rd, 2009

Ok, let’s continue :)
5) In opera, if page content is less than the browser window, then, after modal window is closed, part of overlay is left on the bottom of the browser window (where is no content). I think that to see it you need to set color other than white for the overlay. To get rid of this nasty problem, we need to make browser repaint the page. I don’t know another way to do it, but to use this hack:

function runRepaintHack()
{
$(“body”).append(“”);
$(“#helper”).css({height: $(document).height(), width: $(document).width()});
$(“#helper”).remove();
}

#helper {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: -10;
}

and we need to call runRepaintHack() in the end of the close() function. As you can understand we create a div which fills the whole browser window and then we remove it. It makes browser to repaint the page.

6) In IE6 the overlay only covers content part of the page, so, again, if content is less than the browser window, part of the browser window stays “uncovered”. Again, I think that to see it you need to set color other than white for the overlay.
If you want to fix it, here is one solution:

if($.browser.msie && $.browser.version < 7)
{
modalOverlay.css({height: $(document).height()})
}

spoken by: Pavel

date: October 16th, 2009

@pavel Thanks for the improvements. I think you encapsulated the purpose in the post – providing a base for readers to build on and adapt to their needs. For instance, is was not my intent to acomodate Opera or IE6, fade ins/outs, escape key, etc but rather let the reader do that – for sometimes those features will add extra weight due to individual needs.

Although, I’m running Win 7 x64 RTM and have found no crashing issues as you have described. Perhaps you have a conflicting browser plugin installed.

spoken by: tom

date: November 23rd, 2009

Hi Tom, thanks a lot. i tried it its fine but I have 1 issue. If I scroll my mouse up or down then in IE6 the modal window is also moving. In mozilla and chrome its fine. I want the same effect in IE6. the Modal window Should not move. It should stick in center of the page like mozilla.

Thanks again Tom

spoken by: abhik

date: November 24th, 2009

[...] Simple Modal Window Example built on jQuery [...]

spoken by: 網站製作學習誌 » [Web] 連結分享

date: December 22nd, 2009

Is there any way to drag the iframe now it’s fixt in the center..

spoken by: Ab

date: January 2nd, 2010

hi tom, is there a way to call parent page javascript function from popup before close event.

spoken by: ararat

date: January 13th, 2010

This is a great script. Simple and elegant. Also I managed to reload the parent page like this :
Thanks

spoken by: UndoCreations

date: June 4th, 2010

Still fighting with

$(this.parent) is null
in modal-window.js row: 20

spoken by: Tomas

Leave a Reply

Apr 25 2008