Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
REST API: Add a plain text file as an attachment to a list item
SharePoint 2013 REST API has been enhanced and extended. The old _vti_bin/listdata.svc is still there, but the new api for working with lists and list items is much more and obviously a part of a bigger api: _api/web/lists Yesterday I saw an interesting question on SharePoint StackExchange:
The instructions in the MSDN resource are not so detailed, the cannot be. The guy who asked the question did as it stood in the examples. But sometimes solutions for SharePoint need some small adjustments :) Here is the simplest code to create an attachment in plain text for a list item 1 in the list called List1 in the root web. That’s it. But it works:
SharePoint Modal Dialog as AngularJS directive
It has already become a series of posts in my blog about the combination of AngularJS and SharePoint:
- AngularJS: prevent form validation in Page Edit Mode
- angular jQuery UI autocomplete
- AngularJS: sync $location.search with an input value
And it will be more. Some of them are a pure angular stuff, some of them are really for SharePoint. In this post post I’ll show how to create a directive for a sharepoint modal dialog (SP.UI.ModalDialog). There is already a modal dialog implementation in the Angular UI project, but it uses the bootstrap modal dialog. But it custom attributes for angular">is not that hard to create an own directive for showing sharepoint modal dialogs. I’ve called the new directive ng-sp-modal (ngSpModal). Here is this:
JavaScript Localization in SharePoint
Yesterday Waldek Mastykarz published a cool post: Globalizing JavaScript in SharePoint 2013. This is a very cool technique to localize your client code in javascript and reuse your resx files in Server Side and Client Side. This is actually not new for SharePoint 2013 despite it has become more needed with the huge client focus in the new SharePoint. I have used this in SharePoint 2010 for a long time. In my blog post: ScriptResx.ashx in SharePoint I told about that technique. What I didn’t know that you can define your javascript namespace directly in the resx file. Waldek wrote in his comment that SP.Publishing.Resources.en-US.resx automatically are SP.Publishing.Resources in javascript. That was not the case for my own localization files. A simple look at SP.Publishing.Resources.en-US.resx helped: 
AngularJS: prevent form validation in Page Edit Mode
I work on a cool project where AngularJS is used for rendering of business data in a SharePoint portal. One of the beautiful parts of AngularJS is the client validation. AngularJS understands the new html5 attributes like “required” and pattern, which makes the markup and javascript concise and semantic. Recently I ran into a problem: The SharePoint webparts which had html forms with required fields were impossible to add to a page in the web browser, neither was it possible to edit the pages with these webparts. When I clicked on “Save”, the page tried to validate and failed. The solution for this is very elegant, like much of the AngularJS. If you don’t show your angular form, it won’t validate. So just use any method to detect the edit mode on a SharePoint page. I created a helper function for that.
angular jQuery UI autocomplete
Angular JS is one of the most developed MVC frameworks in the javascript world. Angular UI is a huge UI-centric extension of AngularJS (it is more or less like jQuery UI to the jQuery). It uses much jQuery UI and Twitter Bootstrap and provides many own components like modal dialogs, maps, tooltips, masked inputs and much more. And all this is easy to implement in your code just by adding a directive:
<input ui-date>Much cleaner than listening on $(document).ready, traversing the DOM and appending the datepicker in your code:
javascript: show only a part of a long string (ellipsis)
Ellipsis (…) is a character which indicates that the content is to wide. There are many solutions to truncate the text and show an ellipsis: in javascript and css. I want to share my humble function which extends the String.prototype:
String.prototype.ellipsize = function (maxLength) {
maxLength = maxLength || 100;
if (this.length <= maxLength) {
return this;
}
var text = this.toString()
.replace(/[\r\n]/g,
""), max = maxLength, min = maxLength - 20,
elipsized, tryExtract = function () {
var regex = new RegExp("^.{" + min + "," + max + "}\\s"),
match = text.match(regex);
if (match) {
elipsized = match[0].replace(/\.?\s$/, '…');
}
else {
//well, there were no \s between min and max
min = min - 20;
tryExtract();
}
};
if (min <= 0) {
return text;
}
tryExtract();
return elipsized || text;
};To use it, just call the function from a string property in your favorite templating engine: Angular, jsRender, Knockout….:
Cool presentation about web performance optimization
by Chris Love [slideshare id=15218139&doc=webperformanceoptimizationformodernwebapplications-121116224847-phpapp01]
AngularJS: sync $location.search with an input value
I have used AngularJS for a while and to me this seems to be the best MVC javascript framework. Today I wanted to implement a search which uses an input and a hash query string like in google. The input value and url have to be synced like:
index.html#?term=somethingTo do this we have to inject $location into our angular control. See the Angular Guide about $location. Then we have to observe both the $scope.term (which is bound to the input value) and $location.search().
Determine if Silverlight is installed (javascript)
For a while ago I needed to provide an alternative solution when Silverlight isn’t installed. I searched for javascript code for this and found this:
- A blog post about that: Piotr Puszkiewicz’s Silverlight Blog. Determining if Silverlight is installed using Javascript.
- A more advanced javascript function which can even determine the version of the Silerlight can be pulled from Silverlight.js library.
I didn’t need to determine the version of Silverlight, so I wrote a simplified js function (but it works in all browsers):
