How To: Dismiss a ModalPopup using the Escape Key

The web application I am currently developing has a handful of cases where modal windows are used to gather user input.  Lately, I have been considering replacing these modal windows with an asp:Panel that is displayed as a modal popup using the AjaxControlToolkit's ModalPopupExtender control.  In the process I noticed a small usability issue with the ModalPopupExtender's behavior.  Unlike other modal windows, the popup is not dismissed when the user presses the 'Esc' key.  I am one of those users that relies heavily on the keyboard and only uses the mouse as a last resort - so I find this rather annoying.

Live Demo | Download

Hopefully, this functionality will make it into the toolkit one day.  Until then, you can add it to your pages by including a small amount of JavaScript.  In the sample page I created for this demo, I attached a handler to the document's onkeydown event.  In the handler I check to see if the key pressed was the 'esc' key, if so I find the ModalPopup component and hide it.

function pageLoad(sender, args){
    if(!args.get_isPartialLoad()){
        //  add our handler to the document's
        //  keydown event
        $addHandler(document, "keydown", onKeyDown);
    }
}

function onKeyDown(e){
    if(e && e.keyCode == Sys.UI.Key.esc){
        // if the key pressed is the escape key, dismiss the dialog
        $find('mdlPopupExtender').hide();
    }
} 

Although this is pretty straight forward, there are a few items to consider.

  1. The ModalPopupExtender client side API doesn't support a way for determining if the popup is currently visible.  Because of this you will have to call hide everytime the escape key is pressed, regardless if the popup is currently being displayed or not
  2. Unless you extend the ModalPopupExtender's behavior, you will have to add this script to every page
  3. The ModalPopupExtender supports providing a script that can be run when the user clicks the Cancel button (specified by using the CancelControlID and OnCancelScript properties).  Dismissing the control by pressing escape will not run the OnCancelScript 

Below is the complete listing for the sample page.  As usual, you can download the complete source if you are interested. 

That's it.  Enjoy!

<%@ Page Language="C#" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="head" runat="server">
    <title>Untitled Page</title>
    <style>
    .modalBackground {
        background-color:Gray;
        filter:alpha(opacity=70);
        opacity:0.7;
    }
    </style>
</head>
<body>
    <form id="frm" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <script type="text/javascript">

        function pageLoad(sender, args){
            if(!args.get_isPartialLoad()){
                //  add our handler to the document's
                //  keydown event
                $addHandler(document, "keydown", onKeyDown);
            }
        }

        function onKeyDown(e){
            if(e && e.keyCode == Sys.UI.Key.esc){
                // if the key pressed is the escape key, dismiss the dialog
                $find('mdlPopupExtender').hide();
            }
        } 
        
        </script>

        <div style="font-family:Tahoma; font-size:smaller">
            <p style="background-color:AliceBlue">
            Example page where a modal popup can only be dismissed by pressing the escape key
            </p>
            <asp:Button ID="btnShowModal" runat="server" Text="Click to Make the Page Modal" />
            <asp:Panel ID="pnlModalPanel" runat="server" Style="display: none">
                The only way to close this is to press the 'esc' key.
            </asp:Panel>
            <ajaxToolkit:ModalPopupExtender 
                ID="mdlPopupExtender" runat="server" 
                BackgroundCssClass="modalBackground"
                TargetControlID="btnShowModal" 
                PopupControlID="pnlModalPanel"  />
        </div>
    </form>
</body>
</html>

TrackBack

TrackBack URL for this entry:
http://mattberseth.com/blog-mt/mt-tb.fcgi/59

Comments


Hi Matt!
At first, thanks for the good tips you share with us in your posts.
In a website Im developing, this usability problem doesnt hurts, but it will be fine to have it solved.
When you say "Hopefully, this functionality will make it into the toolkit one day" are you saying that this will be into the next release?
If thats true, I can wait.

Thanks for you time :-)

Posted by: Hitesh Jain on August 20, 2007 12:00 AM

Hi Matt,

Thank you for posting such amazing examples of ASP.NET AJAX controls.

Ive noted that you implement most of your code (javascript/C#) with inline style. When I try to implement the same code as code-behind style, some of the samples causes error. It would be real nice, if you can provide both the style.

Thank you and keep up the great work.

Hitesh Jain


@penyaskito:

Thanks for the feedback.

I honestly have no idea when or if this will be included in the toolkit. From what I understand there are a number other features and bugs that are being worked on and I am not sure where this particular item would rank ...

Matt.


@Hitesh Jain:

Thanks for the feedback.

I will keep this in mind when I create future posts. Also, my goal is to have all of my examples compatible with visual web developer (just open the folder as a web site). If you find you are unable to do this, let me know and I will fix what I am doing wrong.

Matt.

Posted by: Ryan Martin on August 27, 2007 12:00 AM

Thanks for the great demos and code. I ran into an issue with the PopupControlExtender sticking open also. I was hoping your javascript would file this issue also, but it did not. Right now the user has to click on the GridView again to hide the popup which is lame. Any ideas on this?


@Ryan -

Would you mind sharing the code so I could take a look?

Thanks,
Matt

Hi Matt,

thanks for the good tips you share with us in your posts.

Posted by: Mesut demir on October 18, 2007 12:00 AM

Hi Matt,

Im starter in .NET so I google to find a solution or try to learn new things. I can tell you that your site is the most significant site Ive seen. Youre sharing the tools and source codes. This is not only good for the .Net developpers but also a good sample for Humanity. This is what I always say: Unshared knowledge is not a knowledge. Because no one knows it, thanks again for the good tips and sharing your knowledge with us.

mesut

if i have many ModalPopupExtender controls.
and these controls in different web page!
their ID all differ!
what i do?
thanks
my email:micenote@gmail.com

my english too bad!
sorry!

Posted by: ct on December 23, 2007 12:00 AM

hello, i find this code can not run in the masterpage.

Posted by: Raghavendra Shanbhag on January 11, 2008 12:00 AM

hey its really awesome piece of code...Great Job

One and only excellent site i have ever seen... Congrats Matt !!!!

Hey. For people that are using this with master pages...youll need to replace the ID in the $find line with
$find()
This gets the ID on the client since contentplaceholders rewrite them.

Posted by: Chandramouli on March 5, 2008 12:00 AM

Thanks a lot, Your code really helped me....

Posted by: Ivan on May 2, 2008 12:00 AM

Um.. Matt... why didnt you submit this as an issue on Codeplex?!1

This page may exist, but it is falling upon deaf ears if you dont submit an issue about it!!!

My biggest gripe is the fact that they used the Enter key to cancel or ok the modal popup. All my users are used to hitting the enter key to submit a form, and this causes issues if theres, say, a search textbox on the modal.

@Ivan -
You can just use the DefaultButton property of the panel control to make the enter key submit whatever is on your modal. If you need to do something special it should be do-able using some JS which I've been doing a lot of lately...let me know if you need any code examples

Posted by: Ed Zaron on August 21, 2008 04:28 PM

Matt,
I appreciate your site. Not knowing the $find command I tried to use getElementById which fails. Of course using $find works fine. I've tried to get info on the $find command but no luck. Maybe the $ is causing searches to fail?? Do you have a link?
Thanks again, you've helped me a number of times.
Best Regards,
Ed Zaron

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Consulting Services

Yep - I also offer consulting services. And heck, I'll do just about anything. If you enjoy my blog just drop me an email describing the work you need done.

Recent Comments

  • Ed Zaron wrote: Matt, I appreciate your site. Not knowing the $find command I tried to use getElementById which fail...
  • Sanjay wrote: @Ivan - You can just use the DefaultButton property of the panel control to make the enter key subm...
  • Ivan wrote: Um.. Matt... why didnt you submit this as an issue on Codeplex?!1 This page may exist, but it is fa...
  • Chandramouli wrote: Thanks a lot, Your code really helped me.... ...
  • fh wrote: Hey. For people that are using this with master pages...youll need to replace the ID in the $find li...
  • Saji Nair wrote: One and only excellent site i have ever seen... Congrats Matt !!!! ...
  • Raghavendra Shanbhag wrote: hey its really awesome piece of code...Great Job ...
  • ct wrote: hello, i find this code can not run in the masterpage. ...