We want to create a dialog box with jQuery but we want to make it accessible to browsers that don't support
JavaScript. So we embed our dialog box in the markup, just before the closing body
tag:
<div id="dialog"> <h2>Dialog title <a href="#">Close</a></h2> <form action="#" method="post"> <p>Are you sure that jQuery is cool?</p> <div> <input type="submit" value="Yes" name="yes" id="yes" /> <input type="submit" value="No" name="no" id="no" /> </div> </form> </div>
Then we add some styles to our dialog box:
/* Dialog box */ #dialog { width: 250px; margin: 0; border: 4px solid #999; background: #ffc; } #dialog h2 { margin: 0; font-size: 1.3em; background: #666; color: #fff; text-transform: uppercase; text-align: center; padding: 6px; height: 100%; } #dialog h2 a:link, #dialog h2 a:visited, #dialog h2 a:hover { font-size: small; color: #fff; text-transform: lowercase; position: relative; left: 40px; } #dialog form { margin: 0 auto; width: 80%; } #dialog form p { margin: 0; padding: 0.5em 0; font-weight: bold; } #dialog form div { height: 100%; text-align: center; padding-bottom: 0.5em; } #dialog form div input { background: #666; color: #fff; font: bold 1em Arial, sans-serif; border-color: #999; margin-right: 5px; }
We want the dialog box appear just under the link used as a trigger. We want also that when the dialog box appear, the whole page gets a grey shadow all over its contents except for the dialog box itself. To achieve this effect, we need some more styles:
/* JavaScript styles */ .hidden { position: absolute; top: -1000em; left: -1000em; } #overlay { background: #000; position: absolute; top: 0; left: 0; }
You might wonder why I didn't use the hide()
method to hide our dialog box. Well, the reason is
pretty simple: this method uses display: none
to hide an element and most screen readers won't read
the contents of an element with such a declaration. So it's safer to use negative absolute positioning. Now let's
add jQuery:
$(document).ready(function() { $('#dialog').addClass('hidden'); var triggerPosition = $('#dialog-trigger').position(); var winWidth = $(window).width(); var winHeight = $(window).height(); var overlay = $('<div id="overlay"></div>').css( { width: winWidth, height: winHeight, opacity: 0.5 }); $('#dialog-trigger').click(function() { overlay.insertBefore('#dialog'); $('#dialog').css({ top: triggerPosition.top + 20, left: triggerPosition.left }); return false; }); $('#dialog h2 a:first-child').click(function() { $('#dialog').css({'top': '-1000em', 'left': '-1000em'}); $('#overlay').remove(); return false; }); $('#dialog form').submit(function() { $('#dialog').css({'top': '-1000em', 'left': '-1000em'}); $('#overlay').remove(); }); });
First, we hide our dialog box by adding to it the .hidden
CSS class. Then we get the coordinates of
our trigger link, the width and the height of the browser window and we store them for later use. As a next step,
we create our extra layer and set its opacity to 50% (0.5) so that the contents of the page will shine through.
This layer will also have its width and height set to the same values of the browser window. Then we trigger a
click
event on our target link. In the function used here, we insert our extra layer on the page just
before our dialog box, we absolutely position our dialog box using the coordinates of our trigger link and we remove
the default action of the link itself. Of course we want allow the user to close the dialog box, so we trigger another
click
event on the link contained within our dialog box and we hide our dialog box again together with the
extra layer. Finally, when an user submits the form, the dialog box should disappear. To accomplish this task, we bind
a submit
event to the form contained in the dialog box and we perform the same actions we did for the
closing link.
You can see the final result here.