Controls in Modal Pop Extender Causing Postback

Last week someone came up with a problem of a button on a modal pop up extender causing a postback and thereby hiding the modal up itself. Consider the situation where you have some asp.net controls on a modal pop up say a Texbox, Label, and a button control. Onclick of the button you want to display the message on the label. What happens is when you click the button it causes the postback thereby causing your modal popup to hide.

So with the following solution I determine which control caused the postback, depending on which I show my modal pop up back again. Here is the code:

   1: <asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" />
   2:        <asp:Button ID="Button1" runat="server" Text="Open Modal" />
   3:        <asp:ModalPopupExtender ID="ModalPopupExtender1" runat="server" BehaviorID="modal" TargetControlID="Button1" PopupControlID="Panel1"
   4:        BackgroundCssClass="modalBackground" CancelControlID="btnCancel">
   5:        </asp:ModalPopupExtender>
   6:  
   7:       <asp:Panel ID="Panel1" runat="server" CssClass="modalpopup" style="display:none">
   8:                <div class="container">
   9:                    <div class="header">
  10:                        <asp:Label ID="lblText" runat="server" CssClass="msg" Text="Enter value and press save" />
  11:                    </div>
  12:                    <div class="body">
  13:                        <asp:TextBox ID="TextBox1" runat="server" />
  14:                        <asp:Label ID="lblMessage" runat="server" Text="Saved" Visible="false" ForeColor="Red" />
  15:                        <br />
  16:                        <asp:DropDownList ID="DropdDownList1" runat="server" OnSelectedIndexChanged="DropdDownList1_SelectedIndexChanged" AutoPostBack="true">
  17:                            <asp:ListItem>Item1</asp:ListItem>
  18:                            <asp:ListItem>Item2</asp:ListItem>
  19:                        </asp:DropDownList>
  20:                    </div>
  21:                    <div class="footer">
  22:                        <asp:Button ID="btnSave" OnClick="btnSave_Click" runat="server" Text="Save" Width="50px" />
  23:                        <asp:Button ID="btnCancel" runat="server" Text="Cancel" Width="60px" />
  24:                    </div>                                                
  25:                </div>
  26:            </asp:Panel>

In the above Aspx markup I am using a ModalPopupExentender to show a Panel containing a Textbox, Label, DropDownList and a Button. Onclick of the Button the label would show a message. I am also using some css classes above, here are those classes:

   1: .modalpopup
   2: {
   3:     font-family: arial,helvetica,clean,sans-serif;
   4:     font-size: small;
   5:     padding: 2px 3px;
   6:     display: block;
   7:     position: absolute;
   8: }
   9:  
  10: .container
  11: {
  12:     width: 300px;
  13:     border: solid 1px #808080;
  14:     border-width: 1px 0px;
  15: } 
  16:  
  17: .header
  18: {
  19:     color: #000;    
  20:     border-color: #808080 #808080 #ccc;
  21:     border-style: solid;
  22:     border-width: 0px 1px 1px;
  23:     padding: 3px 10px;
  24: } 
  25:  
  26: .header .msg
  27: {
  28:     font-weight: bold;
  29: }         
  30:  
  31: .body
  32: {
  33:     background-color: #f2f2f2;
  34:     border-color: #808080;
  35:     border-style: solid;
  36:     border-width: 0px 1px;
  37:     padding-top: 10px;
  38:     padding-left: 10px;
  39:     padding-bottom: 30px;
  40: } 
  41: .footer
  42: {
  43:     background-color: #f2f2f2;
  44:     border-color: #808080;
  45:     border-style: none solid;
  46:     border-width: 0px 1px;
  47:     text-align:right;
  48:     padding-bottom: 8px;
  49:     padding-right: 8px;
  50: } 
  51: .modalBackground 
  52: {
  53:     background-color:Gray;
  54:     filter:alpha(opacity=50);
  55:     opacity:0.5;
  56: } 

A Small javascript function I use to close the modal pop up:

   1: <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
   1:  
   2: <script type="text/javascript">
   3:     function ClosePopup() {
   4:         $find('modal').hide(); 
   5:         return false;
   6:     }
</script>

Here is the entire code behind:

   1: protected void Page_Load(object sender, EventArgs e)
   2:  {
   3:      if (!IsPostBack)
   4:      {
   5:    
   6:      }
   7:      else
   8:      {
   9:          string postBackControlName = GetPostBackControlName(this.Page);
  10:          if (postBackControlName == "btnSave" || postBackControlName == "DropdDownList1")
  11:          {
  12:              ModalPopupExtender1.Show();
  13:          }
  14:      }
  15:  }
  16:  
  17:  protected void btnSave_Click(object sender, EventArgs e)
  18:  {
  19:      if (Page.IsValid)
  20:      {
  21:          lblMessage.Visible = true;
  22:      }
  23:  }
  24:  protected void DropdDownList1_SelectedIndexChanged(object sender, EventArgs e)
  25:  {
  26:  
  27:  }
  28:  
  29:  public static string GetPostBackControlName(Page page)
  30:  {
  31:      string strControlName = "";
  32:      Control control = null;
  33:      //first we will check the "__EVENTTARGET" because if post back made by the controls
  34:      //which used "_doPostBack" function also available in Request.Form collection.
  35:      string ctrlname = page.Request.Params["__EVENTTARGET"]; if (ctrlname != null && ctrlname != String.Empty)
  36:      {
  37:          control = page.FindControl(ctrlname);
  38:      }
  39:       // if __EVENTTARGET is null, the control is a button type and we need to
  40:       // iterate over the form collection to find it
  41:      else
  42:      {
  43:          string ctrlStr = String.Empty;
  44:  
  45:          Control c = null;
  46:          foreach (string ctl in page.Request.Form)
  47:          {
  48:              //handle ImageButton they having an additional "quasi-property" in their Id which identifies
  49:              //mouse x and y coordinates
  50:              if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
  51:              {
  52:                  ctrlStr = ctl.Substring(0, ctl.Length - 2);
  53:                  c = page.FindControl(ctrlStr);
  54:              }
  55:              else
  56:              {
  57:                  c = page.FindControl(ctl);
  58:              }
  59:              if (c is System.Web.UI.WebControls.Button)
  60:              {
  61:                  control = c;
  62:                  break;
  63:              }
  64:          }
  65:      }
  66:      if (control != null)
  67:          strControlName = control.ID;
  68:    
  69:      return strControlName;
  70:  
  71:  }

In the above code the method GetPostBackControlName returns the name of the control that caused the postback. This method has been taken from the following post: http://geekswithblogs.net/mahesh/archive/2006/06/27/83264.aspx so all credits (if its original) to that poster for that code. You could find more explanation of the that method in that link.

How to above code works is like this: So when you run the above code, it would show a button, on click of that button I am showing a modal popup with some controls. When you hit save or you change the dropdownlist (autopostback=true), the page hits the page load event where in I check if the page is postback, if it is I find the name of the control which caused the postback and show the modal pop up and thus the modal pop up stays instead of hiding.

Hope this helps.

2 Comments

  • I worked on one project where we had quite a bit of interactivity in the "modal" extender's "window": To deal with this, we created a version that loads an iframe with another page in it. This let us do a variety of things in the "modal" without messing up the "main window"

  • Controls in modal pop causing postback.. Tiptop :)

Comments have been disabled for this content.