Google

28 August 2014

SharePoint 2013 Minimal Download Strategy and JavaScript

SharePoint logoToday I welcome our Lead Developer Jayant Rimza to the blog. He is often researching how to solve different problems that occur during the development process, and here he will share his solution to a common issue in development for SharePoint. The article is primarily intended for other developers: Jayant Rimza photo

SharePoint is growing rapidly, and Microsoft is putting lots of effort in making it faster, better and more user friendly. Minimal Download Strategy (MDS) and Client-Side Rendering (CSR) are big steps to achieve these goals.

Minimal Download Strategy (MDS) reduces data download on each page. When a user requests a page, only the changes are downloaded and not the whole page. It seems that SharePoint is soon going to be a single page application where all your content will load on a single master page.

You can identify MDS by these ugly looking URLs in SharePoint: "https://test684.sharepoint.com/_layouts/15/start.aspx#/Lists/TimeCard_Jayant%20Rimza/DispForm.aspx?ID=12&Source=https%3A%2F%2Ftest684%2Esharepoint%2Ecom%2FLists%2FTimeCard%5FJayant%2520Rimza%2Fcalendar%2Easpx”.

It is possible to enable and disable MDS in SharePoint 2013. For more information on MDS and how to enable and disable it, refer to http://msdn.microsoft.com/en-us/library/office/dn456544(v=office.15).aspx.

Problems in JavaScript
JavaScript logo In SharePoint 2013 I have faced various problems with my old JavaScript code, that was running fine in SharePoint 2010. When MDS is enabled in SharePoint 2013, you will get errors like "object undefined", page load event code is not working etc. This is because the whole page is not loaded but only the required part, so page load events do not occur.

Garbage Collector
The major feature of MDS is that it also works as Garbage Collector for JavaScript. It removes all global “var” definitions from JavaScript, and you get an error: “Object undefined”. It also removes the definition of “var” like this:

var myobject = {
           Version:”1.0.1”,
           Isdebug:false,
          Getname: function(){

}
};

The good thing is that MDS keeps all JavaScript functions. You will also notice that if you refresh the page all these errors will go away, because a page refresh is a full page load when everything is loaded.

Common solution
There are many suggestions available when you search on the internet, and most of them say you should use the “RegisterModuleInit” SharePoint function to register your module to load in MDS case. I hope it will help you, but I am not sure it does. It also requires condition and check if MDS is enabled or not.
http://sharepointannoyances.wordpress.com/2014/04/09/loading-javascript-via-customaction-and-initializing-functions-with-sharepoint-2013s-minimal-download-strategy/.

My solutions
 I would suggest to instead create a universal code that will work on both cases, whether MDS is enabled or not. To take advantage of the fact that the SharePoint MDS does not remove functions but only clears variables, you can create self-executing functions or JQuery like a library. Here are two solutions for global JavaScipt object replacement:

  • JQuery Like JS Library
    This is a good way of writing your own JavaScipt files for shared and global code. JQuery like a library or self-executing functions are always loaded, and SharePoint will not give an “undefined” error. This method is good for big SharePoint applications and many JS files. From this example you can understand how to create such a library.

    (function () {
        // K returns new Library object
        var K = function () {
            return new Library();
        };
        var Library = function () {
            this.version = '1.0.1';
            return this;
        };
        // Extend the Library object.
        K.fn = Library.prototype =
        {
            kSPErrorMode: {
                _errorStatus: false,
                get_ErrorStatus: function () {
                    return this._errorStatus;
                },
                set_ErrorStatus: function (status) {
                    this._errorStatus = status;
                    //return this._errorStatus;
                }
            }
        };
        if (!window.K) {
            window.K = K;
        }
    })();

    To access object code like this: K().set_ErrorStatus(true);

    Now everything in your code is within a function. MDS will not remove things from your JavaScript, and your code will work well with both MDS enabled and MDS disabled sites.

  • Create Object when needed.
    You can create a function that returns an object of properties and a new object when you need it or new it when the object is undefined. This is good for simple or small applications.

    var Person = function () {
        var myObj = {};
        myObj. Name = "";
        myObj.Email = “”;
        myObj.IsAdmin = false;
        return myObj;
    };

    var objPerson = new Person ();

    You can define objPerson globally and when accessing it, just checkif it is undefined or not.  If undefined, then create object:
    if (typeof (objPerson) === "undefined") {
            objPerson = new Person();
        }
  • Take one more step and create a Closures function that will handle both check for object undefined and create objects. By the closures function you can write a whole logic of object undefined check and initialization in it and access properties:

    function MYBigObject() {   
       if (typeof (objPerson) === "undefined") {
           objPerson = new Person();
        }   
        return {
          MYPerson: function () {
                return objPerson;
            }
        };
    };

    To access person object: 
    Var PersonaName = MYBigObject().MYPerson().Name;
    Like Person you can create many objects and make the return type in MyBigObject function.

Summary
Minimal Download Strategy (MDS) only loads changed content.
Minimal Download Strategy (MDS) works as a JavaScript Garbage Collector and removes all global vars.
To solve this issue, use the SharePoint “RegisterModuleInit” function, create a JavaScript like library or use create object instead of direct var.

This article has also been published in the kalmstrom.com Tips section.
Jayant Rimza
Lead Developer
kalmstrom.com Business Solutions

No comments:

Post a Comment