88 articles and 350 comments as of Wednesday, April 4th, 2012

Wednesday, May 12, 2010

Client Side AJAX Applications in SharePoint 2010 – Part 3: ASP.Net AJAX Templating 101

Guest Author: Lee Richardson
http://rapidapplicationdevelopment.blogspot.com/

As I’ve described in Part One and particularly Part Two of this series, WCF Data Services is an extremely compelling element of SharePoint 2010.  However, as powerful as it is, programming against it directly would still be somewhat painful.  Fortunately, a new related technology – ASP.Net AJAX Templating – integrates beautifully with WCF Data Services and allows for quickly building pretty, maintainable and responsive AJAX applications.

In this part in the series I’ll describe ASP.Net AJAX Templating, give a tutorial of building a simple application page in Visual Studio 2010, and then build out a very simple page using ASP.Net AJAX Templating that displays SharePoint 2010 list data exposed as JSON by WCF Data Services.

What Isn’t Templating?

It’s probably easier to describe ASP.Net AJAX Templating in terms of how you would solve a problem without the technology.  If SharePoint handed you an array of JSON objects in JavaScript today, how would you convert that into HTML? 

The most common answer seems to be JQuery .append()statements.  Probably something like this:

for (var i = 0; i < userStories.length; i++) {
$("#userStories").append("<div class='userStoryCard'>" +
userStories[i].Title + "</div>");
}

The problem with this type of solution, or really anything that doesn’t use a templating engine, is that it fails to cleanly separate presentation from data access logic.  In fact you’re likely to very quickly end up with a classic Active Server Pages style, non-maintainable mess.  It gets even messier when we try to address persisting data back to SharePoint (which I’ll address in the next post in the series).

The goal of Templating is to allow you to instead write something like this:

<div class="userStoryCard">{{ Title }}</div>

Nice and tidy.  Ideally templating provides a solution that:

  • Minimizes plumbing code
  • Cleanly separates presentation from data access logic
  • Simplifies saving data back to the server
  • And has no ViewState!

Past, Present and Future of ASP.Net AJAX Templating

If you’ve read Scott Guthrie’s recent blog post on the jQuery templating engine, or you’re having difficulty finding accurate documentation you may be wondering about how ASP.Net AJAX templating fits in with Microsoft’s vision of building client side AJAX applications.

First of all it used to live in the main ASP.Net AJAX project when it was in beta.  When ASP.Net AJAX 4.0 moved from beta to release, the templating JavaScript files were moved into the AJAX Control Toolkit CodePlex project (and the syntax changed slightly).  This is why most examples you’ll find on the Internet today are slightly out of date.

As far as the jQuery templating engine, according to Stephen Walther, the Project Manager of the ASP.Net MVC team they “won’t be investing into [ASP.Net AJAX Templating] in the future” because they will be focusing on the jQuery templating engine.  So why bother learning a technology that won’t be moving forward?  For one thing the jQuery templating engine is still extremely young (a prototype as of this writing) while ASP.Net AJAX Templating is released and ready to use in production today.  For another thing the syntaxes appear to be close enough that an upgrade won’t be a major undertaking (theoretically).

Visual Studio 2010 and SharePoint 2010

Before jumping right into templating let’s take a quick detour and give a tutorial of how to build an application page in Visual Studio 2010 that will provide a foundation for all of the future code in this series.  As I mentioned in part 1 you can reproduce everything in this series in a content editor web part.  However, Visual Studio provides better intellisense and debugging support, so everything going forward will be in an application page.

To build a simple application page in Visual Studio 2010 select “new project” and navigate to SharePoint then 2010 to select the template.  Notice the large number of SharePoint templates now out of the box in Visual Studio.  Select “Empty SharePoint Project”.


When you Click OK Visual Studio opens up the SharePoint Customization Wizard:


This screen asks you to select the site you’d like to use for debugging.  It’s asking because when you hit F5 (“Start Debugging”), Visual Studio 2010 will package up your wsp file, deploy it to the URL you enter here, attach to the w3wp process, and open a browser into SharePoint, and you’re immediately in debug mode!

If you aren’t deeply impressed then you probably haven’t developed much in WSS 3.0 – but trust me this saves us an enormous amount of effort.  While we won’t write any server side code in this series, it’s still extremely impressive how much work Microsoft has put into making SharePoint 2010 a first class citizen.

Once Visual Studio generates an initial project select Project -> Add New Item and select Application Page.


Visual Studio then generates a page that’s 100% ready to go including the correct Content controls for the SharePoint master page:

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ApplicationPage1.aspx.cs" Inherits="MyAppPage.Layouts.MyAppPage.ApplicationPage1" DynamicMasterPageFile="~masterurl/default.master" %>

<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">

</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
Hello World!
</asp:Content>

<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
Application Page
</asp:Content>

<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
My Application Page
</asp:Content>

(“Hello World!” is custom).  Now if you hit F5 or click Build -> “Deploy Solution” then Visual Studio packages up the application page into a wsp file and deployes it out to SharePoint. And if you navigate to the application page (e.g. http://localhost/mysite/_layouts/MyAppPage/ApplicationPage1.aspx) then you should see something like this:


Impressed?  You really should be.  We didn’t write a line of verbose, duplicative, error prone CAML, didn’t have to write any DOS (or PowerShell) scripts, didn’t have to deploy to the GAC, we probably didn’t even notice that a feature.xml file was created behind the scenes. Yet already we’re deployed!

Installing ASP.Net AJAX Templating

ASP.Net AJAX Templating is a little tricky to install.  To get it first download the source version of the latest release of the AJAX Control Toolkit on CodePlex (it should look something like AjaxControlToolkit.Binary.NET4.zip).  Extract and build the project in Visual Studio (it has both Visual Studio 2008 and 2010 versions).  Then either copy the JavaScript files directly into the SharePoint layouts directory:

  • Copy
    • AjaxControlToolkit.Source\SampleWebSites\AjaxClientWebSite\Scripts; to
    • C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\ \14\TEMPLATE\LAYOUTS\Scripts
  • And
    • AjaxControlToolkit.Source\Client\MicrosoftAjax\Templates; to
    • C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\ \14\TEMPLATE\LAYOUTS\Scripts

Or better yet to do it the more correct and repeatable way, copy the files into a Scripts folder under Layouts in your Visual Studio project.

Show Me the Code

Once we’ve made the JavaScript files that we need available we can write the following, which is about the simplest templaing page you can write:

<asp:content id="PageHead" contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">
<STYLE type="text/css">
.sys-template {
display: none;
}
</STYLE>

<script
src="../Scripts/MicrosoftAjax/jQueryStart.js"
type="text/javascript"></script>
<script
src="../Scripts/MicrosoftAjax/MicrosoftAjax.js"
type="text/javascript"></script>

<script type="text/javascript">
Sys.require([
Sys.components.dataView,
Sys.components.openDataServiceProxy
Sys.scripts.jQuery,
]);

Sys.onReady(function () {
var dataSource = $.openDataServiceProxy(
'/PreDemo/_vti_bin/ListData.svc'
);

$("#userStoriesList").dataView({
dataProvider: dataSource,
fetchOperation: "UserStories",
fetchParameters: { orderby: 'Title' },
autoFetch: "true"
});
});
</script>
</asp:content> 

<asp:content id="Main" contentplaceholderid="PlaceHolderMain" runat="server">
<ul id="userStoriesList" class="sys-template" >
<li>{{ Title }}</li>
</ul>
</asp:content>

Skip over the JavaScript for now and notice unordered list named userStoriesList in the Main content section.  Inside of the li elements is an interesting notation: {{ Title }}.  This specifies a binding to the Title field in a SharePoint ListItem.  We could also have put in “PriorityValue” or any of the other columns shown in Part 2, or we could also put in JavaScript like {{ String.format("{0:M/d/yyyy}", Modified) }}.

Now notice the script references in the PageHead.  The MicrosoftAjax.js reference gets us the core ASP.Net AJAX functionality.  And jQueryStart.js enables the Sys.require function which can import additional JavaScript dependencies.

So far we haven’t imported enough JavaScript files to provide templating capabilities.  It’s the Sys.require statement that brings in 1. the dataView object, which does the main templating work;  2. openDataServiceProxy that knows how to speak to SharePoint’s ADO.Net Data Services; and 3. jQuery.  If you watch the page load in FireBug you’ll notice that the Sys.require figures out which additional .js files are needed like MicrosoftAjaxTemplates.js and adds them in the correct order.  This approach ensures the page doesn’t pull more JavaScript than needed.

The real magic happens in Sys.onReady, whose function is called once the DOM is loaded.  The first thing it does is instantiate an openDataServiceProxy object which is responsible for communicating with an oData endpoint, in our case ADO.Net Data Services.

The second thing it does is instantiate a DataView object and associate it with the userStoriesList element.  The fetchOperation parameter tells it which list to retrieve ListItems from (the UserStories list in our case) and the fetchOperation parameter tells it how to sort, filter, or paginate the data.

After the DataView is instantiated (because autoFetch is set to true) the DataView retrieves JSON data from its dataProvider, and then duplicates the innerHtml of its associated DOM element for each row returned while replacing the binding syntax with real data.  Seems simple enough, but it gets sophisticated very quickly as we’ll see in future posts.

One last thing to notice is the sys-template class.  This is a pre-specified CSS class that ASP.Net AJAX sets to display: block when it is finished rendering.  It’s necessary to create a CSS class for sys-template with display: none so that end users don’t see your template code while the page is loading.

So now if you click Build -> Deploy Solution you should see something like this:


Summary

Certainly this could have been done much more easily with server side code.  But hang in there; this has a lot of potential.  For instance to what extent can we combine this with jQuery to make it pretty?  How do Data Contexts write data back to the server?  How do master detail views work? I’ll explore these questions in the next and future posts in the series.

Guest Author: Lee Richardson
http://rapidapplicationdevelopment.blogspot.com/

Lee Richardson is a Senior Software Engineer at Near Infinity Corporation, an enterprise software development and consulting services company based in Reston, Virginia. He is a Microsoft Certified Solution Developer (MCSD), a Project Management Professional (PMP), a Certified SCRUM master and has over ten years of experience consulting for the public and private sector. You can follow Lee on Twitter at @lprichar

Bookmark and Share
 

Please Join the Discussion

4 Responses to “Client Side AJAX Applications in SharePoint 2010 – Part 3: ASP.Net AJAX Templating 101”
  1. Ramin Ahmadi says:

    veri nice article !
    thanks lee

  2. Ross says:

    Hello Lee,

    Several comments on your post:

    1. Scripts/MicrosoftAjax/jQueryStart.js does not exist in the latest release you pointed in the post. Instead there is Scripts/MicrosoftAjax/Start.js

    2. Sys.require is good, but if you reference classes like this, objects and their properties do not appear in intellisense dropdowns in visual studio, so coding is difficult

    3. There some things not working in the code

    var dataSource = $.openDataServiceProxy(
    ‘/PreDemo/_vti_bin/ListData.svc’
    );
    $.openDataServiceProxy – cannot find this function. What is meant by $.?

    $(“#userStoriesList”).dataView({
    dataProvider: dataSource,
    fetchOperation: “UserStories”,
    fetchParameters: { orderby: ‘Title’ },
    autoFetch: “true”
    });
    dataView is not a method of the userStoriesList.

    I managed to fix it using
    var dataSource = new Sys.Data.OpenDataServiceProxy(‘/PreDemo/_vti_bin/ListData.svc’);

    and

    $create(Sys.UI.DataView,
    {
    autoFetch: true,
    dataProvider: dataContext,
    fetchOperation: “UserStories”
    },
    {},
    {},
    $get(“AnnouncementsList”)
    );

    ..but am i missing some easy coding techniques?
    Will appreciate your help.
    Ross

  3. Jake says:

    Have the same questions as Ross. In addition does the Sys.require need to be

    Sys.require([
    Sys.components.dataView,
    Sys.components.openDataServiceProxy,
    Sys.scripts.jQuery
    ]);

    instead of (see placement of second comma….I might be wrong though)

    Sys.require([
    Sys.components.dataView,
    Sys.components.openDataServiceProxy
    Sys.scripts.jQuery,
    ]);

    ?? I am not sure and so asking.

  4. Napoleon says:

    Is Response.Redirect or Server.Transfer available when you use this design.I want to be able to transfer or redirect the user to another custom application page.

Subscribe without commenting

Speak and you will be heard.

We check comments hourly.
If you want a pic to show with your comment, go get a gravatar!