Click here to Skip to main content
15,885,871 members
Articles / Web Development / ASP.NET
Article

Dialog Opener that Fires Server Event on Main Form when Closed

Rate me:
Please Sign up or sign in to vote.
4.74/5 (14 votes)
1 Dec 20043 min read 130.4K   802   50   31
A pair of server controls, DialogOpener and DialogCloser, that you can drop on a web form to enable you to open a dialog, and when the dialog is closed, cause a server event of your choice to fire on the main form.

Introduction

Often when programming in ASP.NET, you want to pop up a dialog window that requests some kind of user input. When the user is finished with the dialog and closes it, you want the main form to fire a server event that performs some kind of refresh or other actions. Surprisingly, this task is not as easy as it seems, and a Google search turns up lots of confusing information. You can easily end up writing much more code than you need to. After some experimenting, I think I found a reasonably neat and tidy way to accomplish this, and so that I never have to do it again, I wrapped the code for opening and closing the dialog into a pair of server controls.

This article presents a pair of server controls, DialogOpener and DialogCloser, that enable you to quickly set up a dialog that opens, receives user input, closes, and fires an event of your choice on the main form.

DialogOpener

Here is the code for the DialogOpener control:

C#
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web;

namespace ExWebCtlLib
{
 [DefaultProperty("Text"), ToolboxData("<ExWebCtlLib:DialogOpener 
    runat=server></WebCtlLib:DialogOpener>")]
 public class DialogOpener : System.Web.UI.WebControls.WebControl, 
    IPostBackEventHandler  
 {

  [Bindable(true)]
  public event EventHandler DialogClosed
  {
   add
   {
    dialogClosed += value;
   }
   remove
   {
    dialogClosed += value;
   }
  }
  private event EventHandler dialogClosed;

  [Bindable(true), Category("Appearance"), DefaultValue("")] 
  public string Text
  {
   get
   {
    return text;
   }

   set
   {
    text = value;
   }
  }
  private string text = "Open Dialog";

  [Bindable(true), Category("Appearance"), DefaultValue("")] 
  public string DialogName
  {
   get
   {
    return dialogname;
   }

   set
   {
    dialogname = value;
   }
  }
  private string dialogname = "Dialog";


  [Bindable(true), Category("Appearance"), DefaultValue(true)] 
  public bool Scrollbars
  {
   get
   {
    return scrollbars;
   }

   set
   {
    scrollbars = value;
   }
  }
  private bool scrollbars = true;

  [Bindable(true), Category("Appearance"), DefaultValue("")] 
  public string DialogPagePath
  {
   get
   {
    return dialogPagePath;
   }

   set
   {
    dialogPagePath = value;
   }
  }
  private string dialogPagePath = "";

  [Bindable(true), Category("Appearance"), DefaultValue("")] 
  public string DialogParam
  {
   get
   {
    if( ViewState[ this.ID + "DialogParam" ] == null )
     return dialogParam;
    else
     return (string)ViewState[ this.ID + "DialogParam" ];
   }

   set
   {
    dialogParam = value;
    ViewState[ this.ID + "DialogParam" ] = value;
   }
  }
  private string dialogParam = "-1";

  
  protected override void Render(HtmlTextWriter output)
  {
   string url = HttpContext.Current.Request.ApplicationPath + "/" + 
    DialogPagePath + @"?PostBackEventReference=" + 
    Page.Server.UrlEncode( Page.GetPostBackEventReference(this) ).Replace(
    "'", "%27" ) + @"&DialogParam=" + DialogParam;
   string height = Height.Value.ToString();
   string width = Width.Value.ToString();
   string scrollbars = Scrollbars ? "yes" : "no";

   output.Write( @"<input id=""ExFxDialogOpener"" type=""button"" 
    value=""" + Text + @""" class=""" + CssClass + @""" 
    onclick=""javascript:OpenDialog('" + url + "', '" + 
    DialogName + "', " + height + ", " + width + ", '" + 
    scrollbars + "' " + @" );"">" );
  }

  public void RaisePostBackEvent(string eventArgument)
  {
   if( dialogClosed != null )
    dialogClosed( this, new EventArgs() );
  }

 }
}

The code is mostly very straightforward, just some simple properties with getters and setters. The interesting property is the DialogClosed event property. This event will fire on the form when the dialog is closed. Now look at the construction of the URL, specifically the PostBackEventReference param. The HTML that gets generated by the control looks something like this, depending on the exact settings of the control:

ASP.NET
<input id="ExFxDialogOpener" type="button" value="Image Gallery" 
  class="Button" onclick="javascript:OpenDialog(
  '/html/Forms/Fx/ImageGallery.aspx?PostBackEventReference=
  __doPostBack(%27_ctl15%24ImageGalleryOpener%27%2c%27%27)
  &DialogParam=SelectImage', 'Dialog', 456, 580, 'yes' );">

The PostBackEventReference is passed as a URL param to the dialog. We'll use that information in the dialog to fire the server event on closing.

The script calls the JavaScript function OpenDialog(...). You'll need to ensure that the OpenDialog script is in your page by using RegisterClientScript to register it in your main form, or modify the control to call window.open directly. Here's the script for OpenDialog.

JavaScript
function OpenDialog( url, name, height, width, scrollbars ) 
{
    if( scrollbars == null )
      scrollbars = "yes";
      var top = (screen.height - height) / 2;
      var left = (screen.width - width) / 2;
      window.open( url, name, "width = " + width + ", 
        height = " + height + ", menubar = no, 
        scrollbars = " + scrollbars + ", toolbar = no, 
        location = no, directories = no, resizable = no, 
        top = " + top + ", left = " + left );

(Since we have standard JavaScript registration templates in our shop, OpenDialog is always available on our pages, which is why it's not included in the DialogOpener code.)

DialogCloser

The DialogCloser control generates the necessary JavaScript to close the dialog and fire the server event on the main form. It does this by reading the PostBackEventReference that we passed in the URL using DialogOpener and constructing the required JavaScript.

Here's the code for DialogCloser:

C#
public class DialogCloser : System.Web.UI.WebControls.WebControl
{
  public void Close()
  {
    if( HttpContext.Current.Request[ "PostBackEventReference" ] == null )
      Page.RegisterStartupScript("__close", "<script>window.close();</script>"); 
    else
    {
      string script = String.Format("<script>window.opener.{0}; 
        window.close();</script>", HttpContext.Current.Request[ 
        "PostBackEventReference" ] );
      Page.RegisterStartupScript( "__close", script ); 
    }

  }
}

Here's an example of the JavaScript that gets registered when DialogCloser.Close is called:

JavaScript
<script>
  window.opener.__doPostBack('_ctl15$ImageGalleryOpener',''); 
  window.close();
</script>

Compiling the Controls

To compile the controls, just create a couple of new server control classes in your own server control library. If you don't have a server control library, create a new project of type "Class Library", drop in the code, compile, then right click on your toolbox, click Add/Remove Items and browse to the .dll you just created. Click OK and the two controls will appear on your toolbox.

Using the Controls

Using the controls is easy. Create two aspx pages. One will be the main form and the other will be the dialog. Drop the DialogOpener onto the main form and open the Properties sheet. Set the DialogPagePath property to the path and name of the dialog page. Double-click the DialogClosed event and write the code you want to run when the dialog closes.

Drop the DialogCloser control onto the dialog form. Somewhere in the dialog code, when you want the dialog to close, write the following line:

C#
DialogCloser.close();

Run the main form. Click on the DialogOpener button. Close the dialog. The DialogClosed event will be called on the main form and your event handler code will run.

Conclusion

This short article has shown you how to create a pair of useful server controls that you can drop on a pair of forms to handle dialog opening and closing, and calling a server event on the main form when the dialog closes. I hope this saves you some headache searching for the answer like I did!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
President Exia Corp.
Canada Canada
I grew up in a small town outside Montreal, Canada, where I grew to appreciate the Francophone culture, the hospitality of rural Quebec and the awesome skiing of the Eastern Townships. I studied Computer Science at the University of Waterloo, Classical Guitar at the University of Toronto, Electrical Engineering at the University of Ottawa, and earned an MBA at Queen's University.

I'm a partner in Exia Corp, developers of The Exia Process for better software project management.

Comments and Discussions

 
GeneralYou are my hero Pin
Locusta7417-Jul-09 11:48
Locusta7417-Jul-09 11:48 
GeneralModal Dialog problem Pin
ch_char5-Sep-05 15:56
ch_char5-Sep-05 15:56 
GeneralPostback problem Pin
Tango_ElTurco16-Aug-05 5:12
Tango_ElTurco16-Aug-05 5:12 
QuestionServer Side Validation BEFORE opening dialog? Pin
theBear0831-May-05 20:12
theBear0831-May-05 20:12 
GeneralDialogOpener Pin
taloca20-Jan-05 21:05
taloca20-Jan-05 21:05 
GeneralRe: DialogOpener Pin
dloendorf24-Jan-05 7:54
dloendorf24-Jan-05 7:54 
GeneralRe: DialogOpener Pin
Sam Fung17-Mar-05 13:03
Sam Fung17-Mar-05 13:03 
GeneralRe: DialogOpener Pin
Hugo V Garcia Razera27-Apr-06 10:43
Hugo V Garcia Razera27-Apr-06 10:43 
GeneralDoesn't raise PostBackEvent Pin
anni330-Dec-04 7:23
anni330-Dec-04 7:23 
GeneralRe: Doesn't raise PostBackEvent Pin
anni330-Dec-04 23:29
anni330-Dec-04 23:29 
GeneralError when closing Pin
Dannemannen21-Dec-04 2:25
Dannemannen21-Dec-04 2:25 
Hi,

I would really like to get this control up and running because it could be very useful in the project I'm working with for the moment, especially when implementing the suggestion of how to recieve a result back from the dialog.
It works like a charm to open the window with dialogopener.

The thing is though that I get the following error when calling dialogcloser1.close in the dialog webform.
Microsoft JScript runtime error: Object doesn't support this property or method
when running the following line:
<script>window.opener.__doPostBack('Dialogopener1',''); window.close();
as you can see the script end tag is missing as well.

Am I doing something wrong?
GeneralRe: Error when closing Pin
Dannemannen27-Dec-04 3:27
Dannemannen27-Dec-04 3:27 
GeneralRe: Error when closing Pin
Nigel Shaw3-Jan-05 2:12
Nigel Shaw3-Jan-05 2:12 
GeneralRe: Error when closing Pin
Sam Fung17-Mar-05 13:02
Sam Fung17-Mar-05 13:02 
GeneralDialog Closed Event Pin
ncsol18-Dec-04 7:16
ncsol18-Dec-04 7:16 
GeneralExcelent Work - some impruvements Pin
topce9-Dec-04 21:22
topce9-Dec-04 21:22 
GeneralRe: Excelent Work - some impruvements Pin
Nigel Shaw11-Dec-04 2:56
Nigel Shaw11-Dec-04 2:56 
GeneralRe: Excelent Work - some impruvements Pin
Nigel Shaw11-Dec-04 2:56
Nigel Shaw11-Dec-04 2:56 
GeneralRe: Excelent Work - some impruvements Pin
topce12-Dec-04 21:35
topce12-Dec-04 21:35 
GeneralRe: Excelent Work - some impruvements Pin
Nigel Shaw13-Dec-04 0:51
Nigel Shaw13-Dec-04 0:51 
Generalunregister event Pin
Urs Enzler8-Dec-04 23:29
Urs Enzler8-Dec-04 23:29 
GeneralRe: unregister event Pin
Nigel Shaw9-Dec-04 0:41
Nigel Shaw9-Dec-04 0:41 
GeneralNo opendialog button Pin
oworld7-Dec-04 20:06
oworld7-Dec-04 20:06 
GeneralRe: No opendialog button Pin
Nigel Shaw8-Dec-04 0:40
Nigel Shaw8-Dec-04 0:40 
GeneralRe: No opendialog button Pin
richhildyard11-Dec-04 0:36
richhildyard11-Dec-04 0:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.