Search code examples
c#asp.netevent-handlingupdatepanelmodalpopupextender

Modalpopup extender in an update panel, whos controls events not firing


I know this is similar to many other questions on S.O. but none of them seem to apply to this situation, nor do they resolve the problem. The issue is I have one Modal Popup Control into which I pass other controls on an as needed basis. So when a user clicks one button on my UI he could get that modal with one set of content, then when clicking another button he would get different content. Everything was working fine until I tried to get events to fire from content that was added to the modal popup. It would not be entirely accurate to say I have tried everything to resolve this problem, but I have attempted quite a bit. I am becoming convinced that this either can not be done, or I have some how set it up incorrectly.

This is this code for the update panel

<input id="dummy" type="button" style="display: none" runat="server" />
<asp:ModalPopupExtender CancelControlID="Close" runat="server" ID="mpeThePopup" TargetControlID="dummy" PopupControlID="pnlModalPopUpPanel" BackgroundCssClass="modalBackground" PopupDragHandleControlID="Title" />
<asp:Panel ID="pnlModalPopUpPanel" runat="server" CssClass="modalPopup" Width="400px" Height="600px">
    <asp:UpdatePanel ID="udpInnerUpdatePanel" runat="Server">
        <ContentTemplate>
            <table id="ContentTableTag" runat="server" cellpadding="0" cellspacing="0" style="width: 100%;
                height: 100%;">
                <tr>
                    <td id="Title" runat="server" style="background-color: rgb(79,82,90); text-align: left;
                        height: 28px; width: 90%; color: White;" nowrap="nowrap">
                        <h4 style="margin: 0px 0px 0px 5px;">
                            <asp:Label ID="LblSectionTitle" runat="server" Text="Modal"></asp:Label>
                        </h4>
                    </td>
                    <td id="Close" runat="server" style="background-color: rgb(79,82,90); text-align: right;
                        height: 28px; width: 10%" nowrap="nowrap">
                        <asp:ImageButton ID="ibClose" runat="server" Style="margin-right: 5px;" ImageUrl="~/WLImages/MLS/button_close.png"
                            ToolTip="Close" />
                    </td>
                </tr>
                <tr>
                    <td id="MainContentHolder" colspan="2" align="left" style="top: 0px; bottom: 100%;
                        vertical-align: top; width: 100%; height: 100%" />
                </tr>
            </table>
        </ContentTemplate>
    </asp:UpdatePanel>
</asp:Panel>

This is the code for the user control that I am adding to the modal popup, in its background are two event triggers, one for when the calendar changes its date, and one for when on of the check box items are checked.

<table id="mainContent" runat="server" visible="false" width="350" height="300">
    <tr>
        <td>
            <asp:label ForeColor="White" runat="server" Text="Exam Date:" />
        </td>
        <td>
            <asp:TextBox ID="txtDate" runat="server" Width="127" ForeColor="Black" 
                readonly="true" ontextchanged="txtDate_TextChanged"/>
            <asp:CalendarExtender ID="CalendarExtender" runat="server" 
                PopupButtonID="ibtnCalendar" OnClientDateSelectionChanged="checkDate" 
                TargetControlID="txtDate" onload="LoadCalendar" />
        </td>
        <td>
            <asp:ImageButton ID="ibtnCalendar" ImageUrl="../imgs/btn_calendar.png" Width="20px" runat="server" />
        </td>
    </tr>
    <tr>
        <td style="vertical-align: top; padding-top:5px">
            <asp:label ForeColor="White" runat="server" Text="Study Days:" />
        </td>
        <td colspan="2" style="vertical-align: top; padding-top:5px">
            <asp:CheckBoxList ID="WeekCheckBox" runat="server" ForeColor="White" 
                onselectedindexchanged="WeekCheckBox_SelectedIndexChanged">
                <asp:ListItem Text="Monday" Value="1" />
                <asp:ListItem Text="Tuesday" Value="2" />
                <asp:ListItem Text="Wednesday" Value="3" />
                <asp:ListItem Text="Thursday" Value="4" />
                <asp:ListItem Text="Friday" Value="5" />
                <asp:ListItem Text="Saturday" Value="6" />
                <asp:ListItem Text="Sunday" Value="7" />
            </asp:CheckBoxList>
        </td>
    </tr>
    <tr>
        <td>
            <asp:label ForeColor="White" runat="server" Text="Study hours per day:" />
        </td>
        <td colspan="2">
            <asp:TextBox ForeColor="Black" ID="tbStudyHours" runat="server" Width="127px" ReadOnly="true" />
        </td>
    </tr>
</table>

Finally this is how I attach the control to the modal.

private void GenerateCalendarPopup(ExamDateSelector eds)
    {
        pnlModalPopUpPanel.BackColor = GUI.Instance.GUIColorElement(GUIElements.color_main);
        LblSectionTitle.Text = "Exam Date";
        pnlModalPopUpPanel.Height = eds.ControlHeight + 40;
        pnlModalPopUpPanel.Width = eds.ControlWidth + 25;
        eds.ShowControl = true;
        MainContentHolder.Controls.Add(eds);
    }

Thank you for any help.


Solution

  • Though this may not be the “right” way to deal with the situation I have created for myself by attempting to copy the flow and style of our windows product for the web, I did find a way to resolve the issue of events not firing from this control when presented in a modal popup; though in a roundabout way. First I wrote a function in javascript, the function does the bulk of the math that I would have put in the events of the control; essentially it calculates the amount of study time left between now and a specific date taking into account the days of the week the user has selected as study days. I then pass the information that I am saving to the database through the use of a webmethod.

    function calculateStudyTime() {
        //do some math
        …
        PageMethods.SaveModalExamDateChangesToDB(datesString, selectedDate);
    }
    

    I attach the script to each of the controls that I want to trigger a calculation in my codebehind. In my case I want to recalculate the study time when ever one of the checkboxes representing a day of the week is toggled. So I attached the script to the ListItem controls. I did it this way because a ListItem control does not actually have an onclick attribute accessible through the designer, but one can be added this way.

    protected void LoadCalendar(object sender, EventArgs e)
    {
    
       …
       foreach (ListItem item in WeekCheckBox.Items)
       {
          item.Attributes.Add("onclick", "calculateStudyTime()");
       }
          …
    }
    

    Finally in the base page from which all of the modal popup’s are being called I create a static reference to that base page, and the adorned function to be called from the javascript file. The static reference to itself is needed so I can access the members of the base page (in this case my context) from the static web method.

    Static Dashboard thisPage;
    protected void Page_Load(object sender, EventArgs e)
    {
       …
       thisref = this;
       …
    }
    
    [WebMethod]
    [ScriptMethod]
    public static void SaveModalExamDateChangesToDB(string days, string date)
    {
       thisPage.UserSession.UserCourse.ExamDate = DateTime.Parse(date);
       thisPage.UserSession.UserCourse.StudyDays = days;
       thisPage.UserSession.UserCourse.Save();
    }
    

    Like I said it is not ideal, but it works.