Tuesday, November 29, 2005

 

Work Around for Javascript Reload Requiring "Retry" Click

Problem

Displayed on my currently opened browser window I have Datagrid / Gridview cotaining a list of editable records, 1 dropdown containing values to filter the data displayed in the grid, and 1 "Go" button to update the grid based on the selected value in the dropdown. When you click the "Edit" hyperlink for that record, a child browser window pops up (using javascript) an editable form populated with the values for that record and a "Save" button. When the "Save" button is clicked, I want the following to occur:

1. Save changes to database.
2. Close open child window containing editable form.
3. Refresh parent browser window containing Datagrid / Gridview so that the changes to the data is displayed without changing the selection in the dropdown filter.

At first glance, this would seem like an easy task. I use a .js file containing a group of javascript functions that handle repeated tasks such as opening and closing pop-up windows. To open the above referenced child window I would call the window.open() method. When closing a child window, if I would like to refresh the parent window, I would normally use code similar to the following:

C#



string script = @"
<script language="
"javascript"">
ClosePage();
</script>;
"
;

Page.ClientScript.RegisterStartupScript(typeof(Page), 'myJScript1', script);



Javascript



<script language="javascript">
// Close parent page.
function ClosePage()
{
if(opener != null)
{
// Redirect parent window to it's current url, giving
// the illusion of a refresh button click.
opener.location.href = opener.location.href;
}
// Close this window.
close();
}
</script>


As you can see the code simply redirects the document to it's current URL. A mock refresh. This works great when all the data you need is in the query string or stored in session variables. Unfortunately, if I 'refresh' in this manner the dropdownlist on the page resets back to the default select value. This breaks above requirement #3 "changes to the data is displayed without changing the selection in the dropdown filter".

I know that if I click the browser's refresh button, after a post-back, the dropdown remains the same. So I do some research and learn that I can call the parent page's javascript reload() method from the child page like so:

opener.location.reload(false);

So now, I replace "opener.location.href = opener.location.href;" with "opener.location.reload(false);" and I test it out. First, I select an item from the dropdown other than the default item. Second, I click the "Go" button. The page now displays a list of result records. Third, I click on one of the records, which opens a new window containing the details of the selected record. I make a small change to the record and click "Save". The detail/child window closes and the parent page begins to refresh. So far, so good. But wait...what is this?

Retry

The dreaded "The page cannot be refreshed without resending the information. Click Retry to send the information again" retry box. This will never do.

Solution

To refresh the data on an opener/parent (hereafter to be called "opener) window without tripping the the "retry box" trap, I used the following solution.

Instead of calling the reload() javascript function, I created a javascript function that calls the opener's submit() function. The child page can call this function after it's own "Save" button has been clicked. This will submit the opener page, rather than reloading it, circumventing the "retry box". The Page_Load event handler checks to see if the submit() function was called and executes the appropriate code to "refresh" the data on the page.

Add the following hidden field to the opener page:



<input id="hdnRefreshData" runat="server" type="hidden" value="0" />


Add the following javascript to the opener page:



<script language="javascript">
function RefreshMyData()
{
//alert('RefreshMyData');
var myHdnRefreshData = document.getElementById(<%= "'" + hdnRefreshData.ClientID + "'" %>);
myHdnRefreshData.value = '1';
window.document.forms[0].submit();
}
</script>


Add the following C# code to the Page_Load event handler of the opener page:



if (IsPostBack)
{
// When the FileTimeEdit.aspx's "Save" button is clicked, it
// calls the RefreshMyData() javascript function on FileTim.ascx
// which sets the value of the hdnRefreshData control and calls this
// form's submit function. I catch the submit request here.
if (hdnRefreshData.Value == "1")
{
// refresh data
FillPagingGrid();
// reset value of hidden field so it is not called when "Go" button
// is clicked.
hdnRefreshData.Value = "0";
}
}


Add this code to the child window's Save button's click event handler:



// Call javascript to close this window and call parent page function to
// refresh it's data, which may have changed with this save.
RegisterScript(@"opener.RefreshMyData();
ClosePage()"
);


I hope this solution works as well for you as it did for me.

Update (04/25/06): Sai pointed out that I make a reference to a function called "RegisterScript()", but I do not provide the code for it. So, here it is:



/// <summary>
/// Method to register javascript on web page.
/// </summary>
/// <param name="method"></param>
public void RegisterScript(string method)
{
string script = @"
<script language="
"javascript"">
<!--
{0};
//-->
</script>
"
;

Page.ClientScript.RegisterStartupScript(typeof(Page), method, string.Format(script, method));

}


Thanks Sai.

Comments:
Hi, in asp.net RegisterScript is not included but it is showing error means overload arguments 1 how to solve this problem urgent plz plz plz friends
 
how to write this 'RegisterScript(@"opener.RefreshMyData();
ClosePage()");
in asp.net code behind
plz help me
 
Oops, my bad. RegisterScript is a function created to add javascript code blocks to the page.

I will add the source to this page, for future reference.
 
Thank you very much for ur kindness to share the code. It worked for me a lot. Keep it up.

Gud luck
Sreenivasulu
 
Post a Comment

Links to this post:

Create a Link



<< Home
Content copyright ©2003-2006 Tod Birdsall