Friday, February 13, 2009

Using 'esc' to close dynamic modal dialogs

In my previous post I described how to get a reference to a behavior when you know the target control (speaking in terms of the Ajax Control Toolkit extenders) of the extender. This is necessary to be able to call the hide() method of the ModalPopupExtender when the 'esc' key is pressed.

With this knowledge and jQuery we can get a handle on each of the ModalPopupExtender behaviors in a databound repeating control (such as GridView or Accordion.)

jQuery can be used to get a set of DOM objects by class. I want to get the set of DOM objects that represent the target controls of all the ModalPopupExtenders in the page. In order to facilitate this, I set the CssClass property of all the target controls to "mpeTarget". It's important to remember that it's possible to set multiple classes for the same element by separating them with a space, so if your target control already has a class assigned to it you can still add "mpeTarget". Your class or CssClass property would then look like CssClass="myExistingClass mpeTarget"

Now that all the target controls have been given a CssClass to distinguish them, we are ready to write some javascript.

        function pageLoad(sender, args) {
            if (!args.get_isPartialLoad()) {
                $addHandler(document, "keydown", onKeyDown);
            }
        }


This sets up the document to respond to the "keydown" event by calling a function named "onKeyDown" which is shown here:

        function onKeyDown(e) {
            if (e && e.keyCode == Sys.UI.Key.esc) {
                $(".mpeTarget").each(function() {
                    var mpe = Sys.UI.Behavior.getBehaviorsByType(this, AjaxControlToolkit.ModalPopupBehavior);                    
                    if (mpe.length > 0)
                        mpe[0].hide();
                });
            }
        }


This method checks to see if the pressed key is the 'esc' key. If it is, jQuery is used to iterate through all the DOM objects with css class "mpeTarget". Each of those DOM objects is used in a call to getBehaviorsByType() to get the behavior object and then call its hide() method.

Thursday, February 12, 2009

Getting a reference to a behavior

For my work I use databound repeating controls extensively. Of course, when using a repeating server control, child control ids are mangled by asp.net to prevent naming conflicts. To facilitate client side interaction I have begun using jQuery to get a reference to DOM elements whose names have been mangled by asp.net.

I wanted to be able to dismiss ModalPopupExtenders on my pages by pressing the escape key and the first obvious problem that manifested was that in order to call the hide() method of the ModalPopupExtender behavior, I had to have a reference to it. But because the ModalPopupExtender is a Component and not a DOM object, I cannot use jQuery to select it.

In my next post I'll demonstrate how I ultimately implemented the functionality I desired, but for now I merely wish to describe a couple of ways to get a reference to a behavior.

I used the Sys.UI.Behavior.getBehaviorsByType() method which works like this:

var mpeArray = Sys.UI.Behavior.getBehaviorsByType($get("btnCausePopup"), 
            AjaxControlToolkit.ModalPopupBehavior);


getBehaviorsByType() returns an array of behaviors. The first parameter it takes is the TargetControlID of the Ajax Control Toolkit control, or in other words, the control that is being extended by the behavior. Here's what my ModalPopupExtender looks like:

 <ajaxToolkit:ModalPopupExtender runat="server" ID="mpePopup" TargetControlID="btnCausePopup"
        PopupControlID="pnlPopup" />


The second parameter is the type of the Sys.UI.Behavior objects to find. Be sure to include the AjaxControlToolkit namespace. In this case the type is "AjaxControlToolkit.ModalPopupBehavior," not "AjaxControlToolkit.ModalPopupExtender." If you are not sure what the type is for the control you are using, one way to find it is to view the source of the page from the browser and search for the value of the TargetControlID. You will find something that looks something like this:

Sys.Application.add_init(function() {
    $create(AjaxControlToolkit.ModalPopupBehavior, {"PopupControlID":"pnlPopup","id":"mpePopup"},
       null, null, $get("btnCausePopup"));


Here, the bold text indicates the Type. Once you have the array of behaviors, iterate through the array to access each individual behavior, setting properties or calling methods at your leisure.

Another useful method in this regard is Sys.UI.Behavior.getBehaviorByName(). Its first parameter is the same as getBehaviorsByType. The second parameter is the name property of the behavior.

Wednesday, February 11, 2009

$get and $find - documented

Bookmark these links! The $get and $find client side APIs are notoriously difficult to find documentation for because their names do not lend well to googling due to the initial '$'. Here are direct links to their official documentation:

$get

$find

Also worth bookmarking is the main page of the asp.net client side reference