2014-09-09

In this example I will modify jQuery to work correctly with Scripts on Demand, Minimal Download Service, Client Side Rendering, and to be compliant with SharePoint best practices.

Over Demanding Scripts
Scripts on demand requires some preparation, before files can properly be registered.

The requirements are:

  • Code should not be in the Global Namespace
  • Code should not be embedded in pages, and/or controls
  • Code should be registered inside a Namespace to protect against garbage collection
  • Code should be marked to be used with MDS/CSR if required

The Global Namespace
To modify JQuery and all additional libraries to be in the SharePoint namespace.

The global namespace is registered using syntax that can be picked up by SOD (Scripts on Demand) when the file is loaded, the pattern of which matches the Registered namespace name.

To work, the filename, SOD key, and init wrapper, must follow the same naming convention.

Filename: jQuery.js

Code:

 

Type.RegisterNamespace("jQuery");
    // Example for JQuery, replace jquery with your library name
    function $_global_jquery() {
        // Original jQuery library code goes here
        SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs("jQuery");
    }
    $_global_jquery();

This will ensure correct On Demand loading and it won’t break the MDS feature.

But why does this work? When a script is registered as a Namespace, it prevents a) collisions in the global namespace and b) the built in garbage collection from destroying your variables and methods.

My page is ready and loaded

Remove jQuery.Ready() from all your SharePoint context code!

The reason is that it doesn’t work with pages in 2013 properly. SharePoint has an asynchronous loading technique called MDS that partially loads pages, and because of this it has a custom event that fires when the page is ready.

In order to register your scripts properly you should use:

    if (typeof(_spBodyOnLoadCalled) == 'undefined' || _spBodyOnLoadCalled)
    {
        window.setTimeout(Hugh.MyUberJavaScriptLibrary.init, 0);
    }
     _spBodyOnLoadFunctionNames.push("Hugh.MyUberJavaScriptLibrary.init");

This will ensure the code is run, even if this code is run after the page has loaded.

Adding to your choice of master page
Add into the masterpage the GLOBAL scripts only. Local scripts should be in the components themselves and script linked using script manager. (Code side)

    <!-- Master page addition -->
    <SharePoint:ScriptLink language="javascript" name="~sitecollection/assets/js/jquery.js" runat="server" OnDemand="False" LoadAfterUI="True" />

Make sure to remove all dashes and extra dots from the script name, as this can conflict

As you can see, JQuery here is set to load with the page and after the UI, we are pointing it to an assets folder in the site collection, which houses JS, but in reality this depends on your design.

If you are using on demand then set to false and omit the LoadAfterUI tag.

You should now have a fully registered JQuery library, initialise this from anther js file that is loaded in sequence AFTER your JQuery library.

NEVER embed JS into the page as best practice, and if you do make sure you do not include JS code on the same line as the <Script> tag as this can also break page rendering controls in 2013.

    <script> (function(){ alert("This is bad practice!"); })(); </script>

    <script>
        (function(){ alert("This is acceptable but still not good practice, as alerts are bad usability!"); })();
    </script>

From http://www.martinhatch.com/2013/08/jslink-and-display-templates-part-1.html
a list of the valid token references to use

  •         ~site – reference to the current SharePoint site (or “Web”)
  •         ~sitecollection – reference to the current SharePoint site collection (or “Site”)
  •        ~layouts – version specific reference to the web application Layouts folder (so it will automatically swap out /_layouts/14 or /_layouts/15 for you)
  •        ~sitecollectionlayouts – reference to the layouts folder in the current site collection (e.g. /sites/team/_layouts/15)
  •         ~sitelayouts – reference to the layouts folder in the current site (e.g. /sites/teams/subsite/_layouts/15)

Minification
I would recommend following Microsoft convention, and minify files are filename.js non minified version are filename.debug.js. No dashes no other multiple periods in the name.

A further note: Normally for optimisation you would combine JS files, however in SP2013 it is best to keep them separate and load when required (i.e. on demand)

Default Master Pages
Really you should be using the design manager to create you a master page, in site settings from a html file, however if you want to create one based off a default page, the default master page layouts however are oslo and seattle.

Also new ones are on the way!

AND FINALLY
If you think I have missed something, or you need more detail, please reply below and ask, or grab me in the main chat and I can update this!

About the author 

Hugh Wood

​From 14 years of development experience I can bring to the table much more than just a developer. I have in-depth experience of over 9 programming languages, project management and systems analysis with qualifications in each area. On top of this I have worked on many web projects receiving HTML (Including HTML 5), CSS2 & 3, JavaScript and SEO training. So anything from a network application built in C++, high performance engines built in an assembly language or website or web interface, I have the experience and the expertise to lend to any company.