in

ASP.NET Weblogs

Casey Roach

Dismiss the ModalPopupExtender with Esc or Enter key

I have a ModalPopupExtender attached to a button on one of the pages I'm working on.  The extender targets a Panel defined here:

    1 <asp:Panel ID="CaseNumberPanel" runat="server" style="display:none;" CssClass="modalPopup">

    2     <asp:Panel ID="CaseNumberHeader" runat="server" Style="cursor: move; background-color: #DDD;

    3         border: solid 1px Gray;">

    4         <div style="text-align:center;">

    5             Enter the Case Number

    6         </div>

    7     </asp:Panel>

    8     <div>

    9         <asp:TextBox ID="CaseNum" runat="server" Width="169px" style="text-transform:uppercase;" MaxLength="20"></asp:TextBox>

   10         <ajax:MaskedEditExtender ID="CaseNumMask" runat="server" TargetControlID="CaseNum" ClearMaskOnLostFocus="false"

   11             Mask="LL-99-9999999999" ></ajax:MaskedEditExtender>

   12 

   13         <ajax:MaskedEditValidator ID="CaseNumValidator" runat="server" SetFocusOnError="true" ControlToValidate="CaseNum"

   14                     ControlExtender="CaseNumMask" Display="dynamic" ClientValidationFunction="ValidateCaseNumber"

   15                     EmptyValueMessage="Case Number required" IsValidEmpty="false" ValidationGroup="CaseNum"

   16                     InvalidValueMessage="Invalid Case Number"></ajax:MaskedEditValidator>

   17         <div style="text-align: center;">

   18             <asp:Button ID="CaseNumberOk" runat="server" Width="50px" Text="OK" CssClass="NewButton" />

   19             <asp:Button ID="CaseNumberCancel" runat="server" Width="50px" Text="Cancel" CssClass="NewButton" />

   20         </div>

   21     </div>

   22 </asp:Panel>

As you can see, I'm using the ModalPopupExtender solely to ensure the correct user input before being redirected to another page.  The input here is the main focus for everything that happens in the next page.

I wanted the focus to be on the TextBox when the popup was shown, but couldn't find anything that helped.  So, instead, I pored over the source of the toolkit and found the event handler I needed in the ModalPopupBehavior.js file.  Basically, you want to hook into the 'shown' event.  You would do this in the pageLoad event in javascript like this:

    1 function pageLoad(sender,e)

    2 {

    3     $find('CaseNumberModal').add_shown(OnModalPopup);

    4     var caseBox = $get('<%= CaseNum.ClientID %>');

    5     $addHandler(caseBox, 'keydown', CaseNumKeyDown);

    6     $addHandler(document, 'keydown',CaseNumKeyDown);

    7 }

You can alse see here that I'm hooking into the keydown events that are focused on the TextBox or anywhere else in the document.  From what I understand, you have to hook into this event and not the 'keypress' event, since some browsers don't fire that event for the Esc or Enter keys.

Now the we have hooked into our events, we can define the handlers.

    1 function CaseNumKeyDown(e)

    2 {

    3     if(e.keyCode == Sys.UI.Key.enter)

    4     {

    5         // Trap the enter key so we can trigger validation

    6         // and the okScript code for the extender

    7         e.preventDefault();

    8         e.stopPropagation();

    9         $common.tryFireEvent($get('<%= CaseNum.ClientID %>'), 'change');

   10         ValidatorOnSubmit();           

   11         if(Page_IsValid)

   12             $find('CaseNumberModal')._onOk(e);

   13         return false;

   14     }

   15     else if(e.keyCode == Sys.UI.Key.esc)

   16     {

   17         // Trap the esc key so we can trigger the cancelScript action

   18         var ext = $find('CaseNumberModal');

   19         ext._onCancel(e);

   20         e.stopPropagation();

   21     }

   22 }

   23 function OnModalPopup(e)

   24 {

   25     $get('<%= CaseNum.ClientID %>').focus();

   26 }

The focus for the TextBox is easy.  Once we hook into the 'shown' event of the ModalPopupExtender, we can find the TextBox and focus control on it.

The KeyDown event was a little bit trickier to figure out.  The behavior I wanted was for the Esc key to perform the same operation as the cancel button and the Enter key to perform the same operation as the OK button.  Unfortunately, you can't just say $get('MyOkButton').click().  While the page will Post Back, validation and any OkScript defined in the ModalPopupExtender are not happening.  This is the same with the cancel button.

So I had perform any validation, and then call an scripts defined in the OK/cancel events.  First, we'll focus on the Enter key press handling.  Looking at the markup of a page, I found the javascript function ValidatorOnSubmit().  This ensures that any client-side validation is occurring before anything posts back to the server.  This wasn't enough, though.  The validation I had tied to the TextBox was not occurring.  I reasoned that the TextBox probably couldn't fire the 'change' event before I started looking at the key-presses.  The only logical thing to do then was to fire the 'change' event on the TextBox in order to trigger the client-side validation behavior, then call the ValidatorOnSubmit() function.  I then fire the ok event of the ModalPopupExtender and let it take care of itself..  If you've never seen the 'Page_IsValid' variable before, then you should know that it's defined by ASP.NET and allows you to get/set whether a page is valid at any given point.

If the user hits the Esc key, then I want to trigger the cancel script defined in my ModalPopupExtender.  In both cases, you have to stop the propagation of the event so that any DefaultButtons defined in the form aren't clicked.

I hope this helps.

Comments

No Comments

Leave a Comment

(required)  
(optional)
(required)  
Add