Skip Ribbon Commands
Skip to main content

Point2Share | Daniel McPherson's SharePoint Blog

:

The zevenseas Community > Blogs > Point2Share | Daniel McPherson's SharePoint Blog > Posts > How to bootstrap JQuery on every SharePoint page, even in the Sandbox
July 06
How to bootstrap JQuery on every SharePoint page, even in the Sandbox

I’ve been doing a lot of work in the sandbox over the last few days, not all of it stress-free, but that is for another post. Something I wanted to be able to do was bootstrap a javascript library, for example JQuery, onto every page in the site. Outside the sandbox of course, there are a few ways to do this, however inside it your options are limited.

After much research, help from Wouter van Vugt (and SharePoint Overflow) I have the solution and now, the blog post too.

Solution

First, as described by Jan Tielens over here, outside the sandbox there are a number of ways of achieving this, specifically:

  • Adding a Script reference to the Master Page

    Not a solution for me because I didn’t want to overwrite the MasterPage as part of my feature activation.

  • Use a Delegate Control (e.g. the AdditionalPageHead)

    Not a solution for me because Delegate Controls are not permitted in the Sandbox.

  • Dynamically through code, e.g. in a Web Part

    Not a solution for me because I wanted the script library available on ALL pages.

    With SharePoint 2010 there one more technique at your disposal, thanks Wouter for pointing it out to me. This hint then led me to Jan’s post. Its a new type of “CustomAction” that can be included inside a feature along with a “ScriptSrc” attribute which can point to a Javascript library. Eureka! I yelled, and then fell back to earth when I discovered that it pre-appends the SharePoint Hive path to all locations you configure, making it no use to me inside the Sandbox.

    Reading Wouters comment more carefully on SharePoint Overflow, I noted that he actually suggested a variation of this custom action, one that allows you to insert a script block instead. I shouted Eureka! again.

    Not content with just being able to add my own snippet of Javascript this way, I was sure there would be a way to adapt this to dynamically adding a reference to JQuery. There was, and here it goes:

    1. First, create your new SharePoint project, and set it to deploy to the Sandbox.

    image

    2. Add a new module to the project, this is where your CustomAction will be created. If you want to deploy your own JS library you can replace the Sample.Txt file with your *.JS and deploy it to the site. Otherwise you can delete it and reference any other JS Library.

    image

    3. Now we need to insert the ScriptBlock which is where all the magic happens. I have added comments to describe what happens. This script should be inserted immediately below the:

     

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

     

    <CustomAction
        Location="ScriptLink"
        ScriptBlock="
            //Function that Dynamically Loads the Javascript
            function loadScript(scriptSrc, callbackFunction) {
              //Gets a reference to the Head section, where the Script tage will be inserted
              var headSection = document.getElementsByTagName('head')[0];
     
              //Creates a new Script tag
              var script = document.createElement('script');
              script.type = 'text/javascript';
     
              //Sets the source for the script tag to our external library
              script.src = scriptSrc;
     
              // most browsers
              script.onload = callbackFunction;
     
              // Fix to ensure support for IE 6-7
              script.onreadystatechange = function() {
                  if (this.readyState == 'complete') {
                    callbackFunction();
                  }
              }
     
              //Adds the section to the header
              headSection.appendChild(script);
            }
     
            //Function to test that JQuery has loaded successfully
            //This should be replaced with your own function calls
            function runScript() {
                $(document).ready(function() {  
                alert('jQuery is loaded!!'); });
            }
     
            //Important, this ensure the scripts execute after SharePoint has done everything it needs to. 
            _spBodyOnLoadFunctionNames.push('loadScript(\'http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js\', runScript)'); 
        " Sequence="101">
    </CustomAction>


    In this example we are inserting JQuery from http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js

    3) After completing the above step, you are ready to go. You now simply need to deploy your solution, and then refresh your home page. If everything worked correctly you should get something like the below.

    image

    I have packaged up my complete solution, and its available for you to download, grab it from here:
    http://www.zevenseas.com/go.aspx?ScriptInTheSandbox=Download

     

  • Comments

    Boris Gomiunik

    Neat!
    System Account on 07/07/2010 12:49

    Nick Hadlee

    Nice work indeed. This is going to be a real gem for the client OM and sandbox developers!
    System Account on 08/07/2010 23:31

    Locally hosted Jquery

    Hi there. Thanks for this great post. Everything Works 100%

    Just something to add. Most companies dont like referencing the Jquery files if they are hosted somewhere (MS, GoogleAPIs), so most people end up hosting it locally.

    I managed to get that working by adding a Sharepoint Mapped Folder for Layouts\JqueryInclude and then replacing your Sharepoint Body onload function with this :

    _spBodyOnLoadFunctionNames.push('loadScript(\'/_layouts/JqueryInclude/jquery-1.4.2.min.js\', runScript)');

    This works 100% for me.

    Thanks

    Wicus van den Berg
     on 17/09/2010 01:24

    this.readyState

    Hey Daniel!
    Isnt the check for this.readyState supposed to also check for 'loaded' as well as 'complete'?
     on 02/11/2010 23:11

    Hey Dan

    I did try your method, but what i found is that ScriptBlock's emit their code somewhere in the "body".
    If you try to use the standard $(document).ready() calls, they sometimes work and sometimes dont, depending on if jQuery is loaded or not.
    I made a sandbox solution that loads jQuery (from either a document library, google or microsoft) in the "head", allowing you to use the standard "ready"calls.

    Regards
    djeeg
     on 14/12/2010 03:55

    testing if jqeury script loaded ?

    Hi, I use your technique to add the jQuery files to all pages... that seems to work, but how can I know if the script is yet added to the header ?

    more precicely, in in a custom webpart, if I add :


    function SetupClosableBehavior() {
    jQuery(document).ready(function () {
    // do the job
    });
    }
    debugger;
    _spBodyOnLoadFunctionNames.push("SetupClosableBehavior");

    it hangs on jQuery(document) telling me jQuery is undefined. I believe this is because the method is called before the script is fully loaded...

    any idea ?

     on 27/06/2011 03:19
     

     Statistics

     
    Views: 5993
    Comments: 5
    Tags:
    Published:1519 Days Ago