Click here to Skip to main content
Click here to Skip to main content

Dialog Opener that Fires Server Event on Main Form when Closed

By , 1 Dec 2004
Rate this:
Please Sign up or sign in to vote.

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:

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:

<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.

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:

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:

<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:

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

About the Author

Nigel Shaw
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 PinmemberLocusta7417-Jul-09 11:48 
GeneralModal Dialog problem Pinmemberch_char5-Sep-05 15:56 
GeneralPostback problem PinmemberTango_ElTurco16-Aug-05 5:12 
QuestionServer Side Validation BEFORE opening dialog? PinmembertheBear0831-May-05 20:12 
GeneralDialogOpener Pinmembertaloca20-Jan-05 21:05 
GeneralRe: DialogOpener Pinmemberdloendorf24-Jan-05 7:54 
GeneralRe: DialogOpener PinmemberSam Fung17-Mar-05 13:03 
GeneralRe: DialogOpener PinmemberHugo V Garcia Razera27-Apr-06 10:43 
GeneralDoesn't raise PostBackEvent Pinmemberanni330-Dec-04 7:23 
GeneralRe: Doesn't raise PostBackEvent Pinmemberanni330-Dec-04 23:29 
GeneralError when closing PinmemberDannemannen21-Dec-04 2:25 
GeneralRe: Error when closing PinmemberDannemannen27-Dec-04 3:27 
GeneralRe: Error when closing PinmemberNigel Shaw3-Jan-05 2:12 
GeneralRe: Error when closing Pinmembersam fung17-Mar-05 13:02 
GeneralDialog Closed Event Pinmemberncsol18-Dec-04 7:16 
GeneralExcelent Work - some impruvements Pinmembertopce9-Dec-04 21:22 
GeneralRe: Excelent Work - some impruvements PinmemberNigel Shaw11-Dec-04 2:56 
GeneralRe: Excelent Work - some impruvements PinmemberNigel Shaw11-Dec-04 2:56 
GeneralRe: Excelent Work - some impruvements Pinmembertopce12-Dec-04 21:35 
GeneralRe: Excelent Work - some impruvements PinmemberNigel Shaw13-Dec-04 0:51 
Generalunregister event PinmemberUrs Enzler8-Dec-04 23:29 
GeneralRe: unregister event PinmemberNigel Shaw9-Dec-04 0:41 
GeneralNo opendialog button Pinmemberoworld7-Dec-04 20:06 
GeneralRe: No opendialog button PinmemberNigel Shaw8-Dec-04 0:40 
GeneralRe: No opendialog button Pinmemberrichhildyard11-Dec-04 0:36 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 1 Dec 2004
Article Copyright 2004 by Nigel Shaw
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid