Opening a Modal Dialog on Page Load from Server-Side Code? Don’t Forget This Sweet (and Totally Critical) Function Call

Posted: Jon | Comments: 0 | November 1st, 2011
Nov 01

As my esteemed colleague Eric has previously detailed for us, SharePoint 2010 comes equipped with a snappy little API for working with modal popup dialogs, entirely based in client-side script. In fact, the following is really all the JavaScript you would need to get your dialog off the ground:

function openMySweetModalDialog(id) {
    var options = SP.UI.$create_DialogOptions();
    options.width = 500;
    options.height = 250;
    options.url = "/_layouts/SharePointModalDialog/SweetDialogPage.aspx?id=" + id;
    options.dialogReturnValueCallback =
        Function.createDelegate(null, whenMyModalDialogCloses);
    SP.UI.ModalDialog.showModalDialog(options);
}

function whenMyModalDialogCloses() {
    alert('That was totally sweet.');
}

But this is SharePoint—which means (for us developer types, at least) that we’re couched firmly in the world of ASP.NET WebForms. The ECMAScript we sling around here tends to get put there by server-side code, especially if it calls for a touch of dynamism.

And a modal dialog is, by nature, a dynamic element—if you are using it right, there will likely be some parameters to pass in. An item’s ID number, for example.

So launching our dialog from the code-behind in just such a case should be a simple matter of formatting a JavaScript string with our parameter value, and then using the page’s ClientScript control to register us up some startup action:

public partial class MySweetAppPage : LayoutsPageBase
{
    protected void Page_Load(object sender, EventArgs e)
    {
        OpenMySweetModalDialog(5);
    }

    protected void OpenMySweetModalDialog(int id)
    {
        // create ECMAScript to call the dialog function and pass the id
        var script = string.Format(@"openMySweetModalDialog('{0}'); ", id);

        // emit script to run on page load
        Page.ClientScript.RegisterStartupScript(
            typeof(LayoutsPageBase), Guid.NewGuid().ToString(), script, true);
    }
}

Well that was easy. In fact, I have half a mind to check that in untested, I feel so very positive about it. What’s that, you say?

Don’t go into that dark basement?

Fine. I’ll run it once. You know, just to underscore the excellence of my l33t 5k1llz and give myself a warm, high-fivey sort of feeling.

Please stand by. A totally sweet dialog will be opening any second now.

Figure 1. Crickets.

Here’s The Charlie Brown Football-Kicking Part

So now I’m laid out on my back, the wind knocked clean from my lungs, a foaming anger brewing over what a cruel mistress SharePoint is to have yanked this football away from me. Halfway through actualizing my happy place and realigning my nerd chakra, I decide that this mystery warrants a little DOM sniffing.

First, some good news. The sky is still blue, and still firmly above our heads: the RegisterStartupScript call works, because our humble line of script has been rendered to the markup in all its glory:

image

Still further good news. The SharePoint Modal Dialog Framework is not a lie that our parents have us wash down with warm milk and a hug—calling our function from the JavaScript console actually does invoke the popup as intended:

image

Then what manner of pigskin-yanking tomfoolery stands in the way of our function landing the punt while the page is loading?

Order Up

Did you know? Before our page can call upon a modal dialog framework to, say, create a modal dialog, our page has to have loaded said modal dialog framework.

It also turns out that this framework is defined in SharePoint’s aptly-named sp.ui.dialog.js file. Pray tell, then, O scriptacious gods of portal app pop-upage: how can we ensure that the execution of our dialog invocation is delayed until this fine script file is duly at the ready?

image

Oh, how they do provide.

How Sweet It Is

So, when we put that little nugget to work for us, the official right way to invoke a SharePoint dialog from server-side code looks something like this:

protected void OpenMySweetModalDialog(int id)
{
    // wrap our call in a parameter-less function, and  
    // delay its execution until sp.ui.dialog.js is loaded
    var script = string.Format(
        @"function reallyOpenDialogForRealYouGuys() {{ 
            openMySweetModalDialog('{0}'); 
        }}; 
        SP.SOD.executeOrDelayUntilScriptLoaded(reallyOpenDialogForRealYouGuys, 'sp.ui.dialog.js'); ",
        id);

    // emit script to run on page load
    Page.ClientScript.RegisterStartupScript(
        typeof(LayoutsPageBase), Guid.NewGuid().ToString(), script, true);
}

A press of my well-worn F5 key, and:

image

There. How you like me now, webpage?

image

Leave a Comment