Getting Started with jQuery Templates and SharePoint 2010
Yesterday evening Scott Guthrie announced that Microsoft’s contributions to the jQuery Javascript library were accepted as Official jQuery plugins. One of those contributions is the jQuery Template plugin that allows you to do (up to a certain level) something like data binding similar to the approach we know from Silverlight. The idea is to create a template (think HTML snippet with elements bound to data properties) and data bind that template with an array of objects. You can find the API documentation over here, or you can check out Boris Moore’s excellent Getting Started guide.
So how can we leverage this in SharePoint 2010? Well jQuery Templates are a great match for either the SharePoint 2010 ECMAScript/Javascript Client Object Model, or the SharePoint 2010 REST API. The following example shows how to quickly display a list of Tasks on a page, by only using jQuery and the REST API in SharePoint 2010. Let’s start with a very basic Site Page that puts an empty ul element in the PlaceHolderMain Content control (notice the ul element gets a specific id set):
<%@ Page MasterPageFile="~masterurl/default.master" %>
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
<ul id="tasksUL"></ul>
</asp:Content>
Next, we need to put some script references in the PlaceHolderAdditionalPageHead Content control to load both the jQuery library and the jQuery Templates plugin. For now this plugin is a separate .js file, in the next release of jQuery this plugin becomes a part of jQuery itself. (The demo code assumes that both .js files are deployed to the same location as the Site Page.)
<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="jquery.tmpl.js" type="text/javascript"></script>
</asp:Content>
After the script references (also in the PlaceHolderAdditionalPageHead Content control), we need to define our template, also using a script element that has the type attribute set to text/x-jquery-xml. This template is just an HTML snippet that gets created for every object of the array that gets “data bound”. In the template it’s possible to use references to those object’s properties by using template tags. For example ${Title} will get the value of the Title property of the object that gets “data bound”. In the sample below, I’m defining a template that’s basically an li element which displays some properties of a SharePoint Task item. Notice that to display the Description of the Task, I’m using the {{html}} Template Tag, because Description is a Rich Text Field thus it contains HTML itself.
<script id="tasktemplate" type="text/x-jquery-tmpl">
<li>
<b class="ms-rteFontSize-4">${Title}</b> - ${StatusValue}
<div>{{html Description}}</div>
</li>
</script>
Finally, in a new normal script element (once again in the PlaceHolderAdditionalPageHead Content control), we can use jQuery’s getJSON function to make an async call to the REST API. The getJSON function takes as a parameter a URL to call, which will be the URL of the listdata.svc (= REST API end point) that fetches all Tasks that are not yet completed. The last parameter of the getJSON function is a callback function that will use the jQuery Templates mechanism to build a new li element for every retrieved Task item, based on the template we defined above. This is accomplished by using the new tmpl function, called on the template. The return value is an array of DOM elements, which are added to the empty ul element, defined above.
<script type="text/javascript">
$(document).ready(function () {
$.getJSON(
"../_vti_bin/listdata.svc/Tasks?$filter=StatusValue ne 'Completed'", null,
function (data) {
$("#tasktemplate").tmpl(data.d.results).appendTo("#tasksUL");
});
});
</script>
Once the Site Page is deployed, the result will look as follows:
If you’re interested, I’ve created a (slightly enhanced) sample Visual Studio project that’s a Sandboxed Solution (download here, including source code). This project provisions the required .js files, and the Site Page. On the demo Site Page I’ve used the following template:
<script id="tasktemplate" type="text/x-jquery-tmpl">
<li>
<b class="ms-rteFontSize-4" style="cursor:pointer;">
${Title}</b> - ${StatusValue}
<div style="display:none">{{html Description}}</div>
</li>
</script>
Notice that the div element that shows the Description value, is using the style display:none; so initially the Description value is not being displayed. In the callback function, after the li items are built, I’m using jQuery’s toggle function to show and hide the Description div when the corresponding Title is clicked.
$("#tasktemplate").tmpl(data.d.results).appendTo("#tasksUL");
$("#tasksUL li").toggle(
function () {
$(">div", $(this)).show("fast");
},
function () {
$(">div", $(this)).hide("fast");
}
);
When the Sandboxed Solution is deployed and activated, just navigate to the demo page using the URL http://yoursite/TemplateDemoAssets/demopage.aspx. You’ll see a nicely animated list of Tasks that are not yet completed!