2

When you launch some custom code, e.g. custom create new site and provisioning of this site, you can use SPLongOperation to display a modal dialog box with a green spinning wheel indicating something is progressing in the background.

Does anyone have an idea how you can create a modal dialog window which gives the outcome of some intermediate finished actions? For example:

  • Site creation -> done!
  • Provisioning -> ongoing

It's like the behavior of the dialog box you receive when creating a new search service application (two stages and their status).

1 Answer 1

2

The SPLongOperation class has two properties, LeadingHTML and TrailingHTML, that can be used to set two areas in the default Long Operation modal dialog when the job starts. Unfortunately, although you can change these properties while the job is in progress, the change isn't reflected in the dialog.

This blog post provides a custom SPLongOperation descendant that can make these changes appear on the dialog. Basically, how it works is:

  1. Wrap the initial LeadingHTML and TrailingHTML values in span elements with known IDs.
  2. When the user updates either property, push JavaScript to the client with Response.Write and Response.Flush that replaces the content of the relevant span with the new value.

(Aside: this class calls Write and Flush on the supplied Page parameter's Response property. Because I couldn't figure out what this Page should be, I wrote custom code instead of using the class and used HttpContext.Current.Response instead. This seemed to work, but my updates always seemed to be one update behind, so I had to put in a dummy Write and Flush after each real one.)

You should be able to use this for what you need - either directly use the supplied class in place of your operation, or take a look inside and emulate it yourself.


Also, in SharePoint 2010 (and maybe before, for all I know) there's the SPStatefulLongOperation class. It's not very well documented, but here's an example of how I might be using it.

SPStatefulLongOperation.Begin(
    "Applying theme to sites.",
    "<span id='trailingSpan'></span>",
    (op) =>
    {
        op.Run((state) =>
        {
            foreach (SPWeb web in site.AllWebs)
            {
                state.Status =
                    "<script type='text/javascript'>" +
                     "document.all.item('trailingSpan').innerText = '" +
                     web.Title +
                     "';" + 
                     "</script>";
                selectedTheme.ApplyTo(web, true);
            }
        });

        op.End("ManageFeatures.aspx?Scope=Site");
    });

This works very similarly to the custom method above: every second, the value of state.Status is written to the Response (via HttpContext.Current) and flushed. Thus you want to be sending JavaScript updating your status element, rather than sending the current status. It's less efficient in that it sends the state even when it hasn't changed, but using the ootb code is a lot cleaner.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.