ASP.NET ModalDialog with PostBack and return values to Parent Page (read asp.net object in javascript)
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> 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> |
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.