Loading Script in SharePoint 2010 (Dallas Tester)
SharePoint 2010 ships with a large EcmaScript-based object model. In order to alleviate downloading all of the script at one time, there is a system built into the object model called Script on Demand. Script on Demand is a publicly available script loading mechanism. It contains methods for loading script, registering script dependencies, executing methods within a loaded file, and event notification. I'll describe the methods and show a short example for some of them.
SP.SOD class
All of the public OM can be accessed using the SP.SOD class. This class is defined in the init.js file on the Web front end. You may have seen examples out there that access these methods without the class specified, but you should always use the class in order to ensure compatibility with future versions of SharePoint. On to the APIs!
SP.SOD.execute(key, functionName, args)
Executes the function functionName in the file identified by key with the arguments specified. This will also load the script if it hasn't been loaded.
SP.SOD.executeFunc(key, functionName, fn)
Ensures that the key file that defines function functionName is loaded and then runs the callback function fn. This will also load the script if it hasn't been loaded.
Registers the file at url with the key key. This has a server-side equivalent--ScriptLink.RegisterOnDemand.
SP.SOD.registerSodDep(key, dep)
Registers the file with key dep as a dependency of file with key key.
SP.SOD.executeOrDelayUntilScriptLoaded(func, depScriptFileName)
If the referenced function func is loaded, execute it now. Otherwise, execute after the script depScriptFileName has been loaded. Does not actually load the script.
SP.SOD.executeOrDelayUntilEventNotified(func, eventName)
If the referenced event eventName has happened already, execute the function func now. Otherwise, execute the function when the event happens.
Tip: This expects a function and not a function name. I ran into an error the first time I used this because I put my function in single quotes. As you might guess, a string isn't a function. :)
SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs(scriptFileName)
Notify that the referenced script scriptFileName has loaded and then execute all the things that are waiting for that script. Note that this must be the last line of any JS file that’s registered for use in the SOD system.
SP.SOD.notifyEventAndExecuteWaitingJobs(eventName)
Notify that the referenced event eventName has happened and then execute all the things that are waiting for that event.
Code Sample
The following code sample shows some of these APIs work together. Since I'm the Server ribbon guy, I'm going to put these customizations into the ribbon. For brevity, I'm going to omit a big chunk of the ribbon code. For more information on customizing the ribbon, check it out in the SDK at Declarative Customization of the Ribbon.
Here are my Command UI Handlers for the ribbon customization. Note that I've broken the code into multiple lines for the sake of readability. You may have to put the code on a single line.
<CommandUIHandler
Command="RegisterScript"
CommandAction="javascript:
SP.SOD.registerSod('MySODTest',
'/SiteAssets/JavascriptDeploy/MySODTest.js');" />
<CommandUIHandler
Command="DisplayAlert"
CommandAction="javascript:
SP.SOD.execute('MySODTest',
'displayAlertFromSOD', 'Hello, world!');" />
<CommandUIHandler
Command="AddNotification"
CommandAction="javascript:
SP.SOD.executeOrDelayUntilEventNotified(displayNotificationFromSOD,
'ReadyForNotifications');" />
<CommandUIHandler
Command="NotifyEvent"
CommandAction="javascript:
SP.SOD.notifyEventAndExecuteWaitingJobs('ReadyForNotifications');" />
<CommandUIHandler
Command="DisplayDialog"
CommandAction="javascript:
SP.SOD.executeOrDelayUntilScriptLoaded(showDialogFromSOD,
'mysodtest.js');" />
Here is the code inside of MySODTest.js:
function displayAlertFromSOD(message) { alert(message); } function showDialogFromSOD() { var options = { title: "Created in an SOD Call", width: 400, height: 600, url: "/_layouts/settings.aspx" }; SP.UI.ModalDialog.showModalDialog(options); } function displayNotificationFromSOD() { SP.UI.Notify.addNotification('Hello, world!', false); } SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs('mysodtest.js');
A few things to note here:
- You must always call registerSod before you use the other functions. In the best case (execute), nothing will happen.. In the worst case (everything else), you'll get a script error.
- After calling registerSod, you must load the script using either execute or executeFunc. This is important because you will run into similar errors as stated above.
- You must always put the call to notifyScriptLoadedAndExecuteWaitingJobs at the end of the JS file. I put that in the notes above, but I wanted to call it out again. :)
Happy coding!
Comments
Anonymous
January 27, 2011
Great post! Keep em coming AND please update MSDN with this information as well :)Anonymous
January 27, 2011
Thanks, Wictor! We're trying to keep the blog fresh and updated as well as incorporate this all back into the SDK. If you have any ideas for blog posts, please let us know! :) -DallasAnonymous
January 27, 2011
Dallas, you could do a post (similar to this one) on the Cmd UI functions, such as RefreshCmdUI(). I've seen a lot of confusion on these...Anonymous
January 28, 2011
Thanks for the idea! I actually have a similar post brewing, so you should see that in February. :) It only covers RefreshCommandUI. Are there other interesting functions that you've tried to use?Anonymous
January 30, 2011
I'll second Wictor, this information is very useful, as were several posts on this blog in the past few months. Are there any publicly available methods to work with calendars? For example in SP 2007, I was able to display next month's calendar on a page, because each month had a specific URL. I am wondering how this could be done in SP 2010. "Dallas Tester", will you attend SharePoint Fest Dallas?Anonymous
January 31, 2011
Christophe, Glad you enjoy the content! I'll look into the calendar APIs and see what I can find out. Alas, I'm based out of Redmond, so I won't be attending SharePoint Fest Dallas. It's also kind of confusing (and amusing) to travel through Dallas with the name Dallas Tester. Everyone gives you a double-take when you hand over your credit card. One of the PMs here thought my office was a landing spot for a tester from Dallas until we met in a meeting. I imagine it was a Twilight Zone moment. :) Take care, Dallas