Tuesday, 21 August 2012

RegisterClientScriptBlock for SharePoint Sandbox Solutions

So we had this requirement where we had to check if a script was already loaded on the page before we push it. So my natural choice was to use the RegisterClientScriptBlock method. But this being a Sandbox solution, like always, things were much more difficult than they initially appeared.

The code executed without throwing any error so I thought I was good to go but the script was not getting registered and also the IsClientScriptBlockRegistered method was not doing its job. So after some searching around, I found the following page which explained my scenario:
http://blog.a-dahl.dk/post/Sharepointe28093Where-is-my-Page-object.aspx

So turns out that sandbox solutions runs in a "sandbox" mode with separate context and no access to the rest of the page. So to my huge disappointment, the ClientScriptManager class was out of bounds. Now it was up to me to figure out a workaround for this issue.

So I thought, why not push some good old JavaScript to the page to check the loading of the script? The challenge before me was that since I was pushing the script from server side to the page, the code would be executed before my DOM was loaded. Also, I could not use any jQuery here because it was included in my script which was to be checked and  loaded. So 1) I had to make sure that my code would get executed only after the page was loaded and  2) I had to do it using pure JavaScript.

The first problem could have been solved by using window.load = function( ) {} but due to the function's browser incompatibility, I decided against it. Thankfully, SharePoint provides an Out of the Box mechanism called _spBodyOnLoadFunctionNames in which we can push functions to be executed when the body tag of the document completes loading.
Being using jQuery very heavily in the past, using pure JavaScript was also an exciting challenge which was fun to do. So after about an hour of fiddling with this issue, I managed to put together a function which would check if a script with the particular id was loaded and if not, then only load it on the page. Here is my SandboxRegisterClientScriptBlock function:

3 comments:

Anonymous said...

Good one...

-"T"

Vardhaman Deshpande said...

Thanks "T"!

Saikiran Sheshagiri said...

Nice one. I have been through the same issue. I used similar approach but in a different way. So I used to write all the script that is required directly on the .ascx page in a function.

Place a asp:label on the page. And call the function using this script. i.e. say if we want to call the function in a button click event then write down the script tag with the javascript function call and add it to the text property of the label.

A quick another trick... :)