The Temple of Fu

code, systems and games

Ajax ModalPopupExtender Postback and Web User Controls

with 12 comments

First off yes, there are a ton of blog posts regarding how to cause a button click inside the ModalPopupExtender to execute server side code and almost all of them tell you correctly to remove the following two attributes, OkControlID and OnOkScript from the ModalPopupExtender declaration.

Where my blog entry differs is by scenario; What if we are dynamically loading user controls into the target panel for the ModalPopupExtender, what about a panel inside a ContentTemplate in a master pages scenario or what if we have an UpdatePanel? Luckily it all is pretty much the same, as long as  there is no OkControlID, OnOkScript or Cancel attributes defined the event will make it back to the server to try and find a delegate with the correct signature.

When you are loading user controls dynamically through the LoadControl() method you need to recreate that control and reload it during the OnInit or PreRender events in order for an event to be registered this also includes modal windows that have user controls within them that trigger events. 

Given the example markup below there is a modal window modalPop that uses panel pnlModalPopUp for it’s PopUpControlID. What you can also see is the TargetControlID is set to the hidden button btnHiddenForModal, this allows the modal window to remain hidden until an event occurs that signals a modal window display.

<asp:Content
    ID="Content2"
    ContentPlaceHolderID="ContentPlaceHolder2"
    Runat="Server">

        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"/>

        <asp:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="100">
                <ProgressTemplate>
                    Loading....
                </ProgressTemplate>
        </asp:UpdateProgress>

        <asp:UpdatePanel ID="upPnlContent" runat="server" UpdateMode="Conditional">

            <ContentTemplate>

                <asp:PlaceHolder runat="server" ID="plContent">
                </asp:PlaceHolder>

                <asp:Panel ID="pnlModalPopup" runat="server"  Style="display:none">
                </asp:Panel>

                <ajax:ModalPopupExtender
                    runat="server"
                    ID="modalPop"
                    PopupControlID="pnlModalPopup"
                    TargetControlID="btnHiddenForModal"
                    BackgroundCssClass="GrayedOut"
                    DropShadow="true">
                </ajax:ModalPopupExtender> 

                <asp:Button ID="btnHiddenForModal" runat="server" Style="display:none" />

            </ContentTemplate> 

        </asp:UpdatePanel>

</asp:Content>

Now we load a control into the  panel pnlModalPopup using code behind.

 

// Control to be used inside the panel for the modal window

UserControl modalContent;

modalContent = new UserControl();

modalContent = (UserControl)LoadControl("PathToControl");

modalContent.ID = "modalControlID"

pnlModalPopup.Controls.Clear();

pnlModalPopup.Controls.Add(modalContent);

modalPop.Show();

HttpContext.Current.Session["CurrentModalControl"] = “yes”;

 

Imagine that the control modalContent contains buttons whose click event you want to catch server side to execute some sort of business logic. In order for this to happen you need to do reload the modal window into the panel again in order for the buttons event to make it to the server to be processed.

 

 protected override void OnInit(EventArgs e)

{

  if (HttpContext.Current.Session["CurrentModalControl"] == "yes")  {

// Control to be used inside the panel for the modal window

UserControl modalContent;

modalContent = new UserControl();

modalContent = (UserControl)LoadControl("PathToControl");

modalContent.ID = "modalControlID"

pnlModalPopup.Controls.Clear();

pnlModalPopup.Controls.Add(modalContent);

modalPop.Show();

}

}

And then within the user control that you are loading into the panel.

protected void btnOK_Click(object sender, EventArgs e)

{

  // Execute your server side code now that the buttons event signature can be found

}

 

 

Hope this helps someone!

Written by lordfu

February 23, 2010 at 12:27 am

12 Responses

Subscribe to comments with RSS.

  1. Hello,

    I am trying to implement the same functionality. The difference is i am also creating modal popup dynamically. It depends upon which button the user has clicked. The purpose is to use same modal popup for all the buttons. If I use the approach as you have suggested, I will need to create the modal popup also.In that case, what will be the TargetControlID in Init()? If the target control id is not given, it does not show the pop up. Can you please help?

    Regards,

    AjaxUser

    March 22, 2011 at 9:49 am

    • The one thing I do is assign my id’s manually when creating controls dynamically. So that I can always reference the control by id within the code as required.

      I will try an post an example here shortly.

      Hope that helps.

      lordfu

      March 22, 2011 at 10:26 am

      • Actually have you tried the same approach just making sure that you [re]create the modal window first?

        lordfu

        March 22, 2011 at 10:34 am

  2. Hi, great article

    I have the following case. I’m dynamically loading user controls into gridview ItemTemplate, but I cannot get these control to do the postback. Any idea how to sort this out?

    Thanks

    sreckoo

    March 26, 2011 at 8:51 am

    • Hi sreckoo,

      Never tried that before but I would think as long as you [re]create controls, [re]assign id’s on each post back this method should work also.

      Can you hit a breakpoint on init()? Do your controls actually cause a postback?

      lordfu

      March 26, 2011 at 9:56 am

      • Hi lordfu,

        Yes, the control causes postback, I believe. Let’s say I have a ascx file which should update something to the DB based on the “ID” (which it gets from a gridview row). So I did test without gridview in “empty” aspx page, of course setting “ID” manualy and tried to postback some data to the DB, which worked.

        In real life I have different ascx files which are loaded to the gridview, depending on the row value.

        Do you mean hitting a breakpoint on Page_Load()? I’ll try that…

        Thanks

        sreckoo

        March 26, 2011 at 3:56 pm

      • Forgot to mention ascx controls are loaded on RowDataBound. Somehow I tried to do RowDataBound with OnInit as in your example but I cannot get it work.

        sreckoo

        March 26, 2011 at 4:05 pm

  3. Hi Lordfu,
    I don’t get the line:
    protected void btnOK_Click(object sender, EventArgs e)
    {
    // Execute your server side code now that the buttons event signature can be found
    }

    espacially the comment “now that the buttons event signature can be found”. Where can the event signature be found? How can I call Methods in the Class that loads the UserControl into the ModalPopupPanel from the btnOK_Click – Event?

    sry, I’m far away from expert of asp.net 😉

    SweatDiver

    July 10, 2012 at 5:29 am

    • Hi there.

      What I mean by that comment is that even though in the modal window we have our button with the ID btnOk. When the user clicked this the event was never fired because it was not properly registered with the server (the control that is) that is what this means.

      “When you are loading user controls dynamically through the LoadControl() method you need to recreate that control and reload it during the OnInit or PreRender events in order for an event to be registered this also includes modal windows that have user controls within them that trigger events. ”

      In order for your user control to call methods on another class those class methods need to be marked public or your control and class need to inherit from the same base class.

      Hope this helps.

      lordfu

      July 10, 2012 at 9:25 am

  4. thanks a lot your code has useful to me

    Harshini

    August 10, 2012 at 7:46 am

  5. I am trying to use this for my site and it works great other than I do not know how to hide the form after I have submitted my btnOK. btnOK does fire, but only after OnInit. I tried setting Session(“CurrentModalControl”) = String.Empty, but since the OnInit fires first, the Session has not been updated. Any ideas how to remove the control?

    Kyle

    August 12, 2013 at 1:14 pm


Leave a reply to lordfu Cancel reply