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.
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.
- 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
- Unless you extend the ModalPopupExtender's behavior, you will have to add this script to every page
- 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>
Comments
Hi Matt!
At first, thanks for the good tips you share with us in your posts.
In a website I'm developing, this usability problem doesn't 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 that's true, I can wait.
Thanks for you time :-)
Hi Matt,
Thank you for posting such amazing examples of ASP.NET AJAX controls.
I've 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.
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.
Hi Matt,
I'm 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 I've seen. You're 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!
hello, i find this code can not run in the masterpage.
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...you'll need to replace the ID in the $find line with
$find('')
This gets the ID on the client since contentplaceholders rewrite them.
Thanks a lot, Your code really helped me....
Um.. Matt... why didn't you submit this as an issue on Codeplex?!1
This page may exist, but it is falling upon deaf ears if you don't 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 there's, say, a search textbox on the modal.