I love JavaScript – people had pronounced this language dead a long time ago. But just like a chicken – which you eat before it’s born and after it’s dead, JavaScript – is being eaten all over the technical world, long after it’s dead! How nice! The coolest thing about JavaScript is that,
- There is no need for separate ActiveX controls, it is part of HTML/Browser
- It can interact with other DOM elements very very naturally
- It’s safe.
- And it’s backwards and future compliant.
It is no surprise thus that a number of libraries have emerged helping us work with JavaScript.
But, JavaScript is not like C#. Notably, it has some biggies missing. For instance,
- No support for events – well, it’s there but it’s icky! You end up writing a lot of spaghetti code.
- You have to worry about browser incompatibilities.
- String concatenation, and version concatenation hell.
- IP issues, minification seems to go against every rule of good higher level programming/architecture you’ve learnt.
- No good support for design patterns, OO etc.
Well each of these, has solutions in JavaScript, so neither of the above is true! :)
I won’t address each of these in a single article – that’s for a book. If you attend my trainings, you will find many of these concepts covered.
ESPECIALLY, the fact that design patterns, such as MVVM cannot be applied to JavaScript.
Because HTML doesn’t have dependency properties like XAML does. So it can’t do WPF like databinding – which is what makes MVVM possible.
Untrue.
They can be applied, using www.knockoutjs.com . But, inside SharePoint 2010, where every single list is exposed over a REST API, this becomes really really compelling. So, I am going to describe to you, step by step, how to do MVVM with JavaScript in SharePoint 2010, while using the REST API. Here goes.
- Create a new custom list as shown below, call it “Songs”

1: <%@ Page Language="C#" MasterPageFile="~masterurl/default.master" %>
2: <%@ Import Namespace="Microsoft.SharePoint" %>
3: <%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
4: <%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
5: <%@ Register TagPrefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
6: <%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
7: <asp:Content ID="Content" ContentPlaceHolderID="PlaceHolderMain" runat="server">
8: <script src="jquery-1.5.2.min.js" type="text/javascript"></script>
9: <script src="jquery.tmpl.min.js" type="text/javascript"></script>
10: <script src="knockout-1.2.0.js" type="text/javascript"></script>
11: <script language="javascript" type="text/javascript">
12: // we're going to write more code here #1
13: </script>
14: // we're going to write more code here #2
15: </asp:Content>
16:
Now, where it says, we’re going to write more code here #1, I am going to execute a JSON call to SharePoint REST API, and craft up my ViewModel -
1: <script language="javascript" type="text/javascript">
2: $(function () {
3: InitForm();
4: });
5: var viewModel;
6: function InitForm() {
7: $.ajax({
8: type: "GET",
9: contentType: "application/json;",
10: url: "/_vti_bin/ListData.svc/Songs",
11: processData: false,
12: dataType: "json",
13: success: function (data) {
14: viewModel = {
15: songs: ko.observableArray(data.d.results),
16: addSong: function () {
17: this.songs.push({ Id: "", Title: "" });
18: },
19: removeSong: function (song) {
20: alert(song.Id);
21: },
22: sortByName: function () {
23: this.items.sort(function (a, b) { return a.Title < b.Title ? -1 : 1; });}
24: };
25: ko.applyBindings(viewModel);
26: }
27: });
28: }
29: </script>
As you can see, my ViewModel is pretty smart – it has behaviors and methods on the business object. Yes this is still javaScript.
I haven’t written save/update/delete implementations – those are just REST calls, I’ve omitted them to keep my code small and understandable – this is a blogpost aferall.
Next, I am going to use jQuery template library to declare my rendering template for an individual song row, as shown below,
1: <script id='songRowTemplate' type='text/html'>
2: <tr>
3: <td><span data-bind='text:Id, uniqueName:true' /></td>
4: <td><input data-bind='value:Title, uniqueName:true' /></td>
5: <td><a href='#' data-bind='text:Id?"Delete":"Save", click: function() { viewModel.removeSong($data) }'></a></td>
6: </tr>
7: </script>
Wow, very interesting! As you can see, I am using standard higher level XAML/C# like concepts such as databinding. Not only that, this is conditional databinding – for instance, in TD#3, I have put a logic that if text Id is blank, the label should say “save”, otherwise “delete” – makes sense! But again, I did this with no spaghetti code, no wiring up logic that eventually becomes unmaintainable in a complex enough form.
Finally, lets go ahead and use this rendering template -
1: <p>You have <span data-bind='text: songs().length'> </span> song(s)</p>
2: <table data-bind='visible: songs().length > 0'>
3: <thead>
4: <tr>
5: <th align=left>Song ID</th>
6: <th align=left>Song Name</th>
7: <th />
8: </tr>
9: </thead>
10: <tbody data-bind='template: { name: "songRowTemplate", foreach: songs }' />
11: </table>
12: <button data-bind='click: addSong'>Add song</button>
13: <button data-bind='click: sortByName, enable: songs().length > 0' type='submit'>Sort</button>
As you can see, I don’t do songs.length calculation – it’s done for me! By the business object, like a dependency property in XAML.
That’s it. Build, deploy, and show in browser -

This is truly an incredible way to write JS code, and it especially makes sense for SharePoint.
And yes, this will work in Sandbox solutions and Office365 too.