Home > Modal Dialog Window, SharePoint 2010 > SharePoint: SPLongOperation inside a Modal Dialog Window

SharePoint: SPLongOperation inside a Modal Dialog Window

September 10th, 2012 Admin Leave a comment Go to comments

    In one of my posts I wrote about using SPLongOperation. When a lengthy operation has been accomplished the usual behavior of the SPLongOperation is to redirect user to another web page. In SharePoint 2010, however, the web page containing long operation could be opened in a Modal Dialog Window. In this case, instead of redirection, we often need to close the dialog right after the long operation is completed.


SPLongOperation.EndScript method

Fortunately, the SPLongOperation class provides us with a new useful method, EndScript, which notifies server that the operation has been completed and sends a specified JavaScript into the user browser. A typical use is presented below:

using (SPLongOperation operation = new SPLongOperation(this.Page))
{
    operation.LeadingHTML  = "Long operation";
    operation.TrailingHTML = "Please wait while the long operation is in progress";

    operation.Begin();

    // the code of the lengthy operation
    ...

    // check if the current page is opened in dialog
    if(SPContext.Current.IsPopUI)
        // signal that the lengthy operation is completed and
        // send a script to close the current dialog
        operation.EndScript("window.frameElement.commitPopup();");
    else
        // signal that the lengthy operation is completed and
        // redirect to another page
        operation.End("anotherPage.aspx");
}

The window.frameElement.commitPopup() script allows to close the dialog and pass SP.UI.DialogResult.OK as the result. The SPContext.Current.IsPopUI flag indicates if the current page is going to be opened in dialog and should be rendered in an appropriate way.


Wrapper around SPLongOperation

In the same old post I demonstrated a handy wrapper around SPLongOperation. Taking into account the dealing with dialogs, the updated version of the wrapper looks as follows:

public class SPLongOperationExecutionParams
{
    public string LeadingHtml  { get; set; }
    public string TrailingHtml { get; set; }
    public string RedirectUrl  { get; set; }
    public bool   CloseDialog  { get; set; }
}

public static void DoInSPLongOperationContext(SPLongOperationExecutionParams executionParams, Action action)
{
    if (HttpContext.Current.CurrentHandler is Page)
    {
        using (SPLongOperation operation = new SPLongOperation(HttpContext.Current.CurrentHandler as Page))
        {
            operation.LeadingHTML  = !string.IsNullOrEmpty(executionParams.LeadingHtml)  ? executionParams.LeadingHtml  : "Long operation";
            operation.TrailingHTML = !string.IsNullOrEmpty(executionParams.TrailingHtml) ? executionParams.TrailingHtml : "Please wait while the long operation is in progress";

            operation.Begin();

            if (action != null)
                action();

            try
            {
                if (executionParams.CloseDialog)
                    operation.EndScript("try { window.frameElement.commitPopup(); } catch (e) {}");
                else
                    operation.End(executionParams.RedirectUrl, SPRedirectFlags.DoNotEndResponse | SPRedirectFlags.Trusted, HttpContext.Current, "");
            }
            catch (ThreadAbortException)
            {
                // This exception is thrown because the SPLongOperation.End
                // calls a Response.End internally
            }
        }
    }
    else
        throw new ApplicationException("Couldn't find a host page!");
}

Below is an example of how to use it:

void startLongOperationButton_Click(object sender, EventArgs e)
{
    SPLongOperationExecutionParams executionParams = new SPLongOperationExecutionParams()
    {
        LeadingHtml  = "Creation of a new list item",
        TrailingHtml = "Please wait while the item is being created",
        CloseDialog  = SPContext.Current.IsPopUI, // if the page is in a dialog, the latter will be closed
        RedirectUrl  = "anotherPage.aspx" // if it's not a dialog, user will be redirected to that page
    };

    DoInSPLongOperationContext(executionParams, delegate()
    {
        // the code of the lengthy operation
        Thread.Sleep(5000);
    });
}
 
  1. Ronen
    May 1st, 2013 at 02:34 | #1

    Hi there hope you can help me , I am using the EndScript method to close a dialog , I tires to redirect after this but can’t figure how to do it… TIA

    • Admin
      May 1st, 2013 at 10:22 | #2

      @Ronen
      I didn’t test this, but try to add one of the following scripts after the window.frameElement.commitPopup():

      window.top.location="some url";
      // OR
      window.parent.location="some url";
      

      I think either of them should work.

  2. Ronen
    May 3rd, 2013 at 04:26 | #3

    thank you very much , I think I tried it but it was ignored… I’ll give it another try

  1. No trackbacks yet.