Add javascript files once to a page – SharePoint Sandbox Solutions

Sandbox Solutions are a new part of SharePoint 2010. They solve the problems presented by using hosted SharePoint not being able to deploy files to the 12/14 hive and bin/GAC, and also help Intranet deployments as Site Collection Owners can now upload Sandbox WSPs. These Sandbox Solutions can be constrained by resource allocation and turned off completely if they have bad code that is breaking things – the good news though is that they can only affect the Site Collection they are deployed within, thus not taking down the whole farm! For a deeper explanation of Sandbox Solutions check out this article by Paul Stubbs:

Developing, Deploying, and Monitoring Sandboxed Solutions in SharePoint 2010.

Problem outline – what to do with javascript?

If we are building a Sandbox Solution we can no longer deploy files to the SharePointRoot (what we used to call the 12 hive, and is now the 14 folder!). What can we do with the files we would normally deploy there such as images, javascript and css? Thankfully each Site Collection within SharePoint has a folder called Site Assets which is to be used for storing this type of content.

So how do we load this content? Well our web part has to be a server control rather than the new ascx based Visual Web Part, so in our web parts RenderContents method we would have something like:

writer.Write(“<script language=’javascript’ type=’text/javascript’ src=’/SiteAssets/MyScript.js’></script>n”);

This is fine if we have a single instance of the web part on our page, but what happens if we have two instances? Unfortunately the script is going to get added to the page twice – may be this is an issue, may be not – certainly if you load jQuery on a page twice and setup event handlers to dom elements weird funky things can start happening!

So the problem is – how can we add javascript files to our page in the RenderContents method, but only if they haven’t been added to the page already?

ASP.NET AjaxLibrary

The ASP.NET Ajax Library (http://www.asp.net/ajaxlibrary/) was released into beta last month at PDC 09. Now forget about ASP.NET 3.5 and ASP.NET 4.0, the ASP.NET Ajax Library is an ajax library from the ASP.NET team that will have it’s own out of bounds release. I think the naming of it is very confusing – everyone I have told about it has presumed it is something to do with ASP.NET 4.0, but it’s not – so get over it 🙂 No doubt it will be included in the upcoming release of ASP.NET 4.0, but for us SharePoint developers we can use it as a separate thing. Which is great as SharePoint 2010 is based on .NET 3.5 and the plans for .NET 4.0 support haven’t been announced yet.

Checkout the Ajax Script Loader part of the Ajax Library

http://www.asp.net/ajaxlibrary/Ajax%20Script%20Loader.ashx

This is really cool and helps us out an awful lot! We can use it to load our custom scripts:

http://www.asp.net/ajaxlibrary/HOW%20TO%20Load%20a%20Custom%20Script.ashx

Load jQuery and other javascript from the Microsoft Content Delivery Network (CDN)

http://www.asp.net/ajaxlibrary/HOW%20TO%20Load%20jQuery.ashx

Before the Ajax Script Loader actually adds the referenced js file to the page, it checks to see if the page already has a link to it. This is exactly the behavior we want as we do not want the same script being added multiple times when we have multiple instances of a web part on the page.

Lets build a Sandbox Solution web part and test this out…

Building a test Sandbox Solution

1, Download the ASP.NET Ajax Library from here:

http://ajax.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35895

I’m using Beta 0911.Get the zip file and extract it to a memorable location.

2, Open up Visual Studio 2010 beta 2 and create a new Empty SharePoint Project called SandboxTest.

3, When the SharePoint Customization Wizard pops up make sure you select your project to be a Sandbox Solution and enter the url of the SharePoint web application that you’d like to use to deploy and test against

image

Click the Finish button and Visual Studio will go and create the project for us.

4, As you can see in the solution explorer our Sandbox Solution is pretty empty right now. Lets add a web part, right click on the Project item in Solution Explorer and from the drop down menu pick Add New Item

image

5, Pick to add a new Web Part from the Add New Item box. NOTE : Do not add a new Visual Web Part as these do not work for Sandbox Solutions!

6, This will create our Web Part SharePoint Project Items and the necessary Feature files. For good practice lets just rename the Feature to SandBoxWebPart by selecting the Feature folder and using the Properties window

image

7, Now we need to be able to add our javascript files to the solution to be deployed in the Site Assets library. Right click on our SharePoint project again and chose to Add New Item. Pick Module from the choices and give it a name of Assets

image

This will create an Assets folder in our project with Elements.xml and Sample.txt file. Ideally this folder name should be so
mething unique (eg the name of your project) because if someone uses the same asset folder name as you and deploys their project, your site assets run the risk of being replaced if they’ve used the same folder name. This is the same kind of rule as the Layouts folder/12 hive in 2007.

image

Double click on the Elements.xml file. While this is in view in Visual Studio, delete the Sample.txt file from the Solution Explorer – see how Elements.xml dynamically changes for you as you add and remove files?! Pretty cool huh!

8, Now lets add our javascript files. Right click on the Assets folder and Add New Item. Select a JScript File from the Web templates section and call it sandbox.js. Now right click on the Assets folder again and this time Add Existing Item. Browse to where you unzipped the ASP.NET Ajax Library and in the Scripts folder select Start.js. Our Assets folder should now look like this:

image

9, Open up Elements.xml, we need to make a small addition by adding Url=”SiteAssets” to the Module element

image

10, Now lets do some programming! Open up WebPart1.cs and add to the RenderContents method

writer.Write(“<script language=’javascript’ type=’text/javascript’ src=’/SiteAssets/Assets/Start.js’></script>”);
writer.Write(“<script language=’javascript’ type=’text/javascript’>Sys.loadScripts(‘/SiteAssets/Assets/sandbox.js’);</script>”);
writer.Write(“<a class=’tada’ href=’#’>Click me</a>”);

The first line will simply link the Start.js javascript file to our page. Start.js is the only file we need to add from the Ajax Library because if we want to use any of the other functionality we can use Sys.require to get the required Ajax Library files from the Microsoft CDN.

The second line uses Sys.loadScripts to add sandbox.js to our page. This is where the clever stuff happens as Sys.loadScripts will check whether the page already has a reference to sandbox.js. If it has, it does nothing – if it doesn’t it will add the link. This is how we stop multiple web parts adding multiple links to the same javascript file.

The third line simply adds a hyperlink that we will make use of shortly.

11, Open up sandbox.js and add the following javascript

function domReady() {
$(‘.tada’).click(function () { alert(‘hello’) });
}

Sys.require(Sys.scripts.jQuery, domReady);

The really interesting line is the bottom one. Sys.require(Sys.scripts.jQuery, domReady); will load jQuery from the Microsoft CDN if jQuery is not already on the page. Once it has been loaded and the DOM is ready to be interacted with the function domReady will be called. In domReady we are using jQuery to hook up a click event to the HyperLink we added to our web part in RenderContents, but we use Sys.require as we do not want this to happen until jQuery is succesfully loaded from the CDN. Sys.require will also stop jQuery being added to the page multiple times if multiple web parts are used.

12, Now we should be able to test our Sandbox web part out so press F5 to compile and deploy it so SharePoint.

Visual Studio will go and activate the Sandbox Solution for you as well – if you now go and add the web part to your page, and click the hyperlink displayed in our web part you will get the alert pop up that we hooked together using jQuery

image

13, Now the really interesting thing happens when you add two of the same web part onto the page

image

When you have this scenario you have the two links and they are clickable and display ‘hello’

Hopefully you are still debugging in Visual Studio 2010. If you switch to Visual Studio then you’ll see all the references added into the page

image

I’ve highlighted the interesting bits.

Start.js – this is loaded twice, once for each web part. There are no technical issues with loading this twice, a slight waste of resources, but as Start.js will be downloaded and cached client side it’s not a huge issue (compared to the problems we are solving!)

sandbox.js – as we are using Sys.loadScripts sandbox.js is only referenced once! Although we tried to add it twice!

jquery-1.3.2.min.js – again only referenced once! Hurrah!

Overall conclusion

So this technique is using two beta products right now – ASP.NET Ajax Library and SharePoint 2010 beta 2. So it can’t be recommended as a best practice yet, but it does address a difficult problem when you are developing Sandbox Solutions web parts and you want to use javascript.

In some future posts we’ll be showing you how you can do some more cool stuff with Sandbox Solutions and the ASP.NET Ajax Library!

<nick/>

[The information contained above is correct as of 06th December 2009. As of writing we are currently working with beta products and although we will do our best to update this post where necessary please note that by the time you are reading this some things will have changed]

Leave a comment