Using jQuery Templates with SharePoint List Data
The new jQuery Templates plugin for the jQuery library offers a way to create data-driven HTML in client-side code. The concept is similar to the idea behind ASP.NET templates only implemented on the client instead of on the server. A jQuery template is an HTML snippet with placeholders that identify fields in bound data. When the template renders on a page, the Templates plugin loops through the data and inserts field values where the placeholders indicate they should go.
For a good getting-started article, see Introducing jQuery Templates. For API documentation and example code, see Templates on the jQuery website.
Both jQuery and the Templates plugin are powerful client-side tools for building user interfaces in SharePoint. In this blog post, I walk through a short example that is written in JavaScript and deployed on a simple Content Editor Web Part. My example scarcely scratches the surface of what is possible with these tools, but it may give you a few ideas about how you can put them to work.
Preparation
For the purpose of this demonstration, I have used the Contacts list template to create a list named Contacts on my development instance of SharePoint 2010. I have also created a new Web Part Page and added it to the Site Pages library. In one of the columns on the page I have inserted a Content Editor Web Part (CEWP).
Rather than struggle with the CEWP's editor, I like to use the Content Link to point to a content file that I have uploaded to the Site Assets library. My Site Assets library has a folder named JavaScript. Permissions on the folder give Full Control to Creator/Owner and Read permission to everyone else. This folder is where I upload the file that the Content Link points to.
Linking to the jQuery Library and the Templates Plugin
Before you can work with the Templates plugin, your page needs to have a script reference that loads the jQuery library. In addition, while the Templates plugin is in beta, your page needs to reference the plugin as a separate file. Eventually, the final plugin code will merge with the jQuery library and you will need a link to just one file. For now, your page needs two script references.
My development website has Internet access, so I link to the libraries on the Microsoft Ajax Content Delivery Network using the following markup:
<!-- Link to the jQuery library -->
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js" type="text/javascript"></script>
<!-- Link to the Templates plugin -->
<script src="https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js" type="text/javascript"></script>
If you prefer not to link to an external source, you could download the libraries and deploy them on SharePoint either by uploading them to Site Assets or by creating a SharePoint Feature with a module that deploys the libraries as shared resources.
How jQuery Templates Work (Short Version)
jQuery templates are HTML snippets that have embedded template tags. They are similar to the templates that you can pass to the String.Format method in the .NET Framework. For example, you could write the following C# code:
string template = "It was {0} degrees in {1} on {2).";
string output = string.Format(template, 54, "Seattle", DateTime.Now.DayOfWeek);
In the code, embedded variables that are defined within a format string act as substitution placeholders that get filled in at run time. A comparable jQuery template could look like this:
<script id="weatherTemplate" type="text/x-jquery-tmpl"> 1:
2: <li>It was ${ Degrees } degrees in ${ City } on ${ DayOfWeek }.</li>
3:
</script>
This particular jQuery template is designed to render the following data:
var weatherData = [
{ City: "Seattle", Degrees: 54, DayOfWeek: "Monday" },
{ City: "San Francisco", Degrees: 64, DayOfWeek: "Monday" },
{ City: "Los Angeles", Degrees: 84, DayOfWeek: "Monday" }
];
You create a jQuery template by placing an HTML snippet inside a script tag that has the type attribute set to "text/x-x-jquery-tmpl". The example template uses several ${ } tags as placeholders for the names of fields on the current data item. When the template is rendered, a copy of the HTML snippet is matched up with each item in the data set, and specific values are filled in. Other tags are available, some with more complex logic. For a complete list, see Template Tags.
In addition to defining a template, you must also identify an element in the DOM where jQuery can render the output. For example, you might instruct jQuery to append output from the weather template to the list defined by this element:
<ul id="weatherContainer></ul>
Okay. You have data, a template to format the data, and an HTML element to receive the output. All that is left now is to write JavaScript that calls the jQuery Template plugin and instructs it to use the template to render the data in the output container. You can do that with a single jQuery chain:
$("#weatherTemplate").tmpl(weatherData).appendTo("#weatherContainer");
How jQuery Templates Work with SharePoint
The most interesting data on a SharePoint website can be found in the fields of the items on a list. For example, let's suppose that you are writing a Web Part that reformats data taken from a Contacts list. What you want, in this hypothetical example, is to render a list with abbreviated contact information, and you want the contacts ordered by company. Let's say that you want the output to look like Figure 1.
Figure 1: An Abbreviated Contacts List
To create the list, you define an output container and a jQuery template as follows:
<!-- Template Container -->
<div id="contactsContainer"></div>
<!-- Template -->
<script id="contactTemplate" type="text/x-jquery-tmpl"> 1:
2: <p><strong>${ Company }</strong><br/>
3: ${ FirstName } ${ LastName }
4: {{if BusinessPhone}}
5: | ${ BusinessPhone }
6: {{/if}}
7: {{if EMailAddress }}
8: | <a href="mailto:${ EMailAddress }">${ EMailAddress }</a>
9: {{/if}}
10: </p>
</script>
The first three placeholders in the template are straightforward ${} tags that specify fields in a Contact list item. The formats for BusinessPhone and EMailAddress data are wrapped by {{if}} tags, specifying conditional display, because these are not required fields on the list. Some items might not contain data in those fields.
To get data to fill in the template, all that is needed is a call to the jQuery library's Ajax shorthand method jQuery.getJSON(). This method accepts the URL for a service that will provide data and a callback function to act on the data.
For a service, we can use the list service that is provided by the SharePoint Foundation REST Interface. For example, to get JSON data for the Contacts list and to ask for the data in company name order, we can use the following relative URL:
"../_vti_bin/ListData.svc/Contacts?$orderby=Company"
And, since what we want to do with the response is simply to render the data in the template, we can pass as a callback a function literal that does nothing more than bind our template to the data and append the output to our container.
<!-- Data -->
<script type="text/javascript"> 1:
2: $(document).ready(function () {
3:
4: // Get the list data.
5: $.getJSON(
6: '../_vti_bin/ListData.svc/Contacts?$orderby=Company',
7: function(data) {
8:
9: $('#contactTemplate') // Select the template.
10: .tmpl(data.d.results) // Bind it to the data.
11: .appendTo('#contactsContainer'); // Render the output.
12: }
13: );
14: });
15:
</script>
Complete Code and Markup
What follows is the complete code and markup that I uploaded to my Site Assets library and then linked to a Content Editor Web Part in order to produce the output shown in Figure 1.
<!-- Link to the jQuery library -->
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js" type="text/javascript"></script>
<!-- Link to the Templates plugin -->
<script src="https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js" type="text/javascript"></script>
<!-- Template Container -->
<div id="contactsContainer"></div>
<!-- Template -->
<script id="contactTemplate" type="text/x-jquery-tmpl"> 1:
2: <p><strong>${ Company }</strong><br/>
3: ${ FirstName } ${ LastName }
4: {{if BusinessPhone}}
5: | ${ BusinessPhone }
6: {{/if}}
7: {{if EMailAddress }}
8: | <a href="mailto:${ EMailAddress }">${ EMailAddress }</a>
9: {{/if}}
10: </p>
</script>
<!-- Data -->
<script type="text/javascript"> 1:
2: $(document).ready(function () {
3:
4: // Get the list data.
5: $.getJSON(
6: '../_vti_bin/ListData.svc/Contacts?$orderby=Company',
7: function(data) {
8:
9: $('#contactTemplate') // Select the template.
10: .tmpl(data.d.results) // Bind it to the data.
11: .appendTo('#contactsContainer'); // Render the output.
12: }
13: );
14: });
</script>
Comments
Anonymous
July 02, 2011
"the final plugin code will merge with the jQuery library": I thought the jQuery team made it clear that it would remain a separate plugin...Anonymous
July 24, 2011
Nice article, btb how to pass User Credential to JSON data list service. thxAnonymous
February 11, 2013
www.sharepointfront.com/javascript-template-manager-its-all-on-the-client-side is another approach almost the simular to reach the same result BUT to keep the HTML in the HTML and not in the JavaScript