Wednesday, December 28, 2005

ASP.NET : Trigger an Event in the Parent Page from within a Page inside IFrame

Web Applications have started dominating the traditional Windows based applications and in the process, the requirements are ever increasing and in many situations we find that too many functionalities need to come as part of a single page.

At this point we resolve to break down each of these functionalities as separate pages and try to call these pages inside an IFrame. This will ensure that the page does not become too heavy and also easy maintainability.

The problem starts when an event has to be triggered in the parent page after an event occurs inside the IFrame. Now let us take an example before I explain how this can be accomplished.

Let us say we have a page that contains Product information. I have some ten list of options like adding categories of a Product, Viewing Product information, etc.

Now for all these I want to give a singly entry system, with my Parent page where I show up all the products in a list box. On top of this I have all the ten options specified. All the other functionalities are taken to ten different pages. I keep an IFrame beside my ListBox that calls the 10 different pages.The aspx page for the Parent Page (say ProductHome.aspx) will have this code:

<table class="table" height="60%" width="80%" align="center" border="0">
<tr>
<td width="20%" height="100%">
<asp:linkbutton id="lnkAddProduct" CssClass="sublink" Runat="server" text="Add a New Product"></asp:linkbutton>
<asp:listbox id="lstProducts" CssClass="textbox" Runat="server" width="100%" Rows="10" AutoPostBack="True" ></asp:listbox></td>
<td width="80%" height="100%"><iframe id="MyFrame" style="WIDTH: 100%; HEIGHT: 100%" name="main" src="" frameBorder="0" scrolling="yes" height="100%" runat="server"></iframe>
</td>
</tr>
</table>


On click of every product I show up the page that displays Product information. Another page is for creating a new Product. Whenever I create a new Product in a page inside an IFrame, I must be able to add that product to the ListBox in the Parent page.

For this to happen, all I need to do is just a few lines of code in the code behind of the child page that contains the new Product information (let us call it AddProduct.aspx). In the Button Click Event (say btnSave_Click), after saving the information to the database:

Session["BindProducts"] = "true";
Session["Page"] = "AddProduct.aspx";
Session["ShowMessage"] = "The Product was added successfully";
Page.RegisterStartupScript("RefreshParent","<script language='javascript'>RefreshParent()</script>");


All that the above code does is to refresh the parent page after setting a few Session variables.

Now in the aspx page of the child page, add the following script block:

<script language="javascript">
function RefreshParent()
{
window.parent.location.href = "ParentPage.aspx";
}
</script>


So now when the Parent Page refreshes, you must bind the ListBox again with the new Product added. For this to happen, add the following code in Page_Load event of Parent Page (ProductHome.aspx):

if(Session["BindProducts"] != null)
{
if(Session["BindProducts"].ToString() == "true")
{
//Call the function to Bind the Products list box again
BindProducts();
}
}

And now remember to set the IFrame's src attribute to your child Page with a message displaying that the Product was added successfully. This will give the end user a feeling that he is only working with the one single page. Add the following code in Page_Load event of ProductHome.aspx to set the URL of the IFrame:


#region Set URL of IFrame
if(Session["Page"] != null)
{
string url = Session["Page"].ToString();
HtmlControl MyFrame = (HtmlControl)this.FindControl("MyFrame");
MyFrame.Attributes["src"] = url;
Session["Page"] = null;
}
#endregion


Now as a last step, display the message that the Product was added in the Child Page. Add the following code in Page_Load event of the Child Page (AddProduct.aspx):

if(Session["ShowMessage"] != null)
{
lblVisitsAdded.Text = Session["ShowMessage"].ToString();
Session["ShowMessage"] = null;
}

The above steps can be repeated for all the other functionalities.

2 comments:

Vijay Karla said...

Hi..
I'm afraid that the method may not work on firefox, preferably with parent page in one domain and iframe page in other domain. Usually it results in 'access denied' error. Any suggestions are welcome.

rinki said...

Page.RegisterStartupScript("RefreshParent","script language='javascript'>RefreshParent()RefreshParentbut it does not refresh the page