ASP.NET ModalDialog with PostBack and Return Values to Parent Page

By Peter Bromberg

We get a lot of posts asking how to create Modal Dialogs and return the entered values back to the spawning page when the window is closed. In addition, people are sometimes confused into believing that a Modal Dialog window cannot handle ASP.NET Postbacks. This is not true.

A Modal Dialog is just a type of HTML page that won't let you return to the page that created it until you close the window. Otherwise, except for a few minor "gotchas", it's no different than any other HTML page. It can certainly be an ASP.NET page, there is no great hangup with that.

There must be two dozen solutions to this issue, some are elegant, some are complex, but here is one that I like. This was originally shown to me by Jonathan Goodyear. Since then, I've modified, simplified and enhanced it, and even though I've used other solutions including some of my own invention, I still like this one the best, because it combines the best of both server- side and client-side coding, can return any number of values to the spawning page, doesn't require AJAX, supports postbacks in the modal page, and is extensible. At a minimum, it can serve as the basis for further experimentation. In addition, showModalDialog is now supported by both Firefox and Google Chrome, although not all features are the same.

First, in our "parent page", we will need a button or any other HTML widget to which we can attach an onclick event. This is what is used to spawn the modal dialog. I like to do this from the server side because its easier to make it portable, and easier to encapsulate - you can even put it into a server control or a utility library that will emit the script. The script injection is all done in the Page_Load handler:

private void Page_Load(object sender, System.EventArgs e)
  {
   if(IsPostBack)
   {
    this.lblMessage.Text="Posted Back!";
    lblMessage.Text+="<BR/>"+Request.Form["txtUserId"].ToString();
         lblMessage.Text+="<BR/>"+Request.Form["txtLayer"].ToString();
  }    
   // set up client script to handle  modalDialog
   if (!Page.IsClientScriptBlockRegistered("Dlg"))
   {  
    string title="Test Title";
    string userId= "123";
    string layer="2";
    string parameters="&userId=" +userId +"&layer=" +layer;
    string height="400";
    string width="400";  
    string page ="dlgModalSample1.aspx";
    
    // use next line for direct with <base target="_self"> between <Head> and </HEAD>
    string scrp="<script>var rc = new Array(0,0);function doIt(){rc=
           window.showModalDialog('dlgModalSample1.aspx?Title="+title + "&page="
            + page + "&userId=" +  userId + "&layer=" +layer +"','','dialogHeight:"+height+" px;dialogWidth:"+width+" px;');"+"\n";
    scrp+="if(rc[0]!=null){document.getElementById('txtUserId').innerText=rc[0];
                 document.getElementById('txtLayer').innerText=rc[1];__doPostBack('','');}}</script>";

    Page.RegisterStartupScript("Dlg",scrp);  
    btnRecur.Attributes.Add("onClick","doIt();");
   }
  }

What we are doing above is just setting some variables that will be passed on the querystring with the showModalDialog Javascript function. We also set up the script to capture the return value as a Javascript ARRAY. This means we can have as many elements as we want. Finally, I've shown that we cause the Parent page to issue a Postback when the child window is closed. All this in one short script.
Now, on to the child page. This one I just put the script into the aspx HTML page the "old fashioned" way:

<script type="text/javascript">
  function Done()
  {
  
  var uid=document.getElementById('txtUserId').value;
  var lay=document.getElementById('txtLayer').value;
  var ret=new Array( uid,lay) ;
  window.returnValue=ret;  
  window.close();  
  }  
</script>

And In the codebehind for the child page:

private void Page_Load(object sender, System.EventArgs e)
  {
   this.txtUserId.Text=Request.Params["userId"].ToString();
   this.txtLayer.Text=Request.Params["layer"].ToString();
   this.btnDone.Attributes.Add("OnClick","Done();");
   this.hdnReturnCode.Value ="changed";
  }


I have 2 buttons on the child page, one that does a postback, and one that is client - side that runs the "Done" function. Here is the code for the postback button:

private void Button1_Click(object sender, System.EventArgs e)
  {
   this.txtUserId.Text= Request.Params["txtUserId"]+"_PostedBack";
      this.txtLayer.Text =Request.Params["txtLayer"]+"_PostedBack";
}

You can see, it's just a proof of concept, changing the values that were passed in (plus whatever you have changed) and adding "_PostedBack" to the text.

When you click the "DONE" button is where we do this:

var uid=document.getElementById('txtUserId').value;
var lay=document.getElementById('txtLayer').value;
var ret=new Array( uid,lay) ; window.returnValue=ret; window.close();

All we are doing is creating an array and stuffing it with our posted back values, and assigning the ARRAY to the window.returnValue object. This then gets passed back to the parent page when we issue our window.close() call, and the parent page posts back also. That's all there is to it, except for the directive:

<base target="_self">

that needs to be put in the child page between the <HEAD> and </HEAD> tags. This prevents a postback from opening a new window, a common problem that people gripe about.

The downloadable solution below has a complete implementation you can use "out of the box". Enjoy.


Download the working Visual Studio 2010 Demo Solution




Popularity  (10153 Views)
Picture
Biography - Peter Bromberg
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking, financial and telephony for over 20 years. Pete focuses exclusively on the .NET Platform, and currently develops SOA and other .NET applications for a Fortune 500 clientele. Peter enjoys producing digital photo collage with Maya,playing jazz flute, the beach, and fine wines. You can view Peter's UnBlog and IttyUrl sites. Follow Microsoft MVP
Create New Account
Article Discussion: ASP.NET ModalDialog with PostBack and Return Values to Parent Page
Peter Bromberg posted at Wednesday, April 20, 2011 11:58 AM
reply
Lonnie King replied to Peter Bromberg at Wednesday, April 20, 2011 4:38 PM
I ran across your article while trying to solve an issue getting values to return to the parent page from a modal window.  My code works in IE, but does not post the value back to the parent page in Chrome, FF or Safari.  

I found the same issue with your code (thanks for the download!) in Chrome and Safari but haven't tested it in FF.

Can you shed any light on why this might be happening and what can be done to make it work in those browsers?

Thanks
reply
Peter Bromberg replied to Lonnie King at Wednesday, April 20, 2011 4:38 PM
The way I understand it, even though showModalDialog is supported in Chrome, FF and Safari, there are still some issues with it. You may need to go with a window.open instead.
reply
Lonnie King replied to Peter Bromberg at Wednesday, April 20, 2011 4:38 PM
I'll give that a shot.  Thanks for the speedy reply!
reply