Skip to main content

Cloud

SharePoint 2010: Closing a ModalDialog Manually from Code (C# and JavaScript)

Situation

If you’ve worked with SharePoint 2010 at all, I’m sure you’ve seen a ModalDialog popup at some point. This popup most often occurs when you’re creating or editing a list item. The item’s edit or create form is displayed by ModalDialog in an HTML iFrame. This frame allows for the nifty, AJAX-like popup, but it also means that the form code is segregated from the rest of the page. This isn’t really a problem with out-of-the-box forms, which use the Dialog master page. The dialog master page provides Save and Cancel buttons in the ribbon, among others. But what if you don’t want to or can’t use the Dialog master page?
If you’re using the default master page, whatever that may be, it typically does not provide Save/OK and Cancel buttons for a dialog. It does, however, clear away most navigation elements and just displays the ContentPlaceHolderID named PlaceHolderMain when IsDlg=1 is in the query string. What this means for you is your buttons need to be in PlaceHolderMain or they might not be rendered. Anyway, regardless of which master page your page actually uses, it can’t communicate with the underlying page that opened it as a dialog.
To facilitate the communication, you’ll need SP.UI.ModalDialog. This is provided as part of the SharePoint JavaScript Object Model and is how SharePoint opens a ModalDialog (via the showModalDialog function). I’m going to skip over opening a ModalDialog because that’s relatively easy, with examples all over the web. What is hard to find are examples for closing a ModalDialog. While it’s true that you’re just calling commonModalDialogClose, how do you call it and, more importantly, where do you call it.
Once your page POSTs back correctly and whatever you needed to do is done, if you don’t close the ModalDialog that your page is in, the user can’t return to work automatically. This breaks the flow of the application and can be rather frustrating for the user. After all, it’s easy for the user to close the ModalDialog, why wasn’t it easy for the developer?

Solution

Fortunately, it is incredibly easy for the developer to close a ModalDialog in SharePoint, once you know where to close it. The correct place is after the page has posted back via a registered startup script. This startup script will simply call commonModalDialogClose with the correct parameters. These parameters are important because SharePoint uses them to determine which callbacks to execute when the dialog is closed. CommonModalDialogClose takes two arguments: dialogResult and returnVal. The first indicates whether the ModalDialog either succeeded or failed and the second is a value passed into the callback methods.
I won’t go into detail with what you can do with callback methods, but the simplest action is to display the result in the SharePoint status bar. The status bar appears right below the ribbon when there is a message in it and can be either red, green, or yellow in color. This is the subject of a future blog post.
Where I prefer to put my code for closing the page is inside the callbacks for the buttons I have on the page. Every page usually has an OK and (usually) a Cancel button. These are the prefect place to place RegisterStartupScript calls. Before we get there, however, my page looks like the following (with all of the Assembly references removed):

 1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AddDeleteWorkflow.aspx.cs"
 2:     Inherits="PB.SharePoint.Layouts.PB.SharePoint.AddDeleteWorkflow"
 3:     DynamicMasterPageFile="~masterurl/default.master" %>
 4:
 5: <asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
 6: </asp:Content>
 7: <asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
 8:     <asp:Button runat="server" Text="Ok" ID="ButtonOk" OnClick="ButtonOk_Click" />
 9:     <asp:Button runat="server" Text="Cancel" ID="ButtonCancel" OnClick="ButtonCancel_Click" />
 10: </asp:Content>
 11: <asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
 12:     Title
 13: </asp:Content>
 14: <asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea"
 15:     runat="server">
 16:     Title
 17: </asp:Content>

The important functions here are ButtonOk_Click and ButtonCancel_Click. These check that the IsDlg parameter is set and then register a startup script to close the dialog. Importantly, although the first parameter of commonModalDialogClose is of SP.UI.DialogResult type, this type may not be loaded by the time your startup script executes. To get around that, use the integer values for the enumeration names instead (0, 1, and –1).

 1: protected void ButtonOk_Click(object sender, EventArgs e)
 2: {
 3:     string isDlg = this.Request.QueryString.GetValues("IsDlg");
 4:     if (!String.IsNullOrEmpty(isDlg) && isDlg == "1")
 5:     {
 6:         this.Page.ClientScript.RegisterStartupScript(this.GetType(), "PopupScript", "SP.UI.ModalDialog.commonModalDialogClose(1, 1);", true);
 7:     }
 8: }
 9:
 10: protected void ButtonCancel_Click(object sender, EventArgs e)
 11: {
 12:     string isDlg = this.Request.QueryString.GetValues("IsDlg");
 13:     if (!String.IsNullOrEmpty(isDlg) && isDlg == "1")
 14:     {
 15:         this.Page.ClientScript.RegisterStartupScript(this.GetType(), "PopupScript", "SP.UI.ModalDialog.commonModalDialogClose(0, 0);", true);
 16:     }
 17: }

Now that you know how to close a ModalDialog, you should be able to make your page much more AJAX-y! Cheers!

Thoughts on “SharePoint 2010: Closing a ModalDialog Manually from Code (C# and JavaScript)”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Andrew Schwenker

Andrew Schwenker is a Sr. Technical Consultant within Perficient’s Microsoft National Business Unit East's SharePoint practice. Andrew has nearly 2 years of experience in consulting and has participated in projects that have touched nearly every aspect of SharePoint 2010. Andrew earned his Bachelor’s degree in Computer Science as well as Master’s degrees in Computer Science and Information Systems from Indiana University. He’s interested in creating winning solutions to generate business innovation using SharePoint. Prior to starting at Perficient, Andrew completed internships with General Electric, ExactTarget, and Great American Financial Resources. During his studies, he actively participated in Alpha Phi Omega National Service Fraternity and competed in the first annual Cluster Challenge at SC07 in Reno, NV. Andrew was a part of the dynamic PointBridge team that was acquired by Perficient.

More from this Author

Follow Us