Sunday, March 21, 2010

Client Side AJAX Applications in SharePoint 2010 - Part 2

Note: This is one of a multi-part series exploring building client side AJAX applications with ASP.Net AJAX 4 Templating and the WCF Data Services (aka ADO.Net Data Services, aka oData, aka Astoria) in SharePoint 2010.

Part 1 – Exploring WCF Data Services in SharePoint 2010
Part 2 – Creating a read-only page with ASP.Net AJAX 4.0 Templates
Part 3 – Writing data back to SharePoint with ASP.Net AJAX 4.0 Templates
Part 4 - jQuery and Manual JSON Object Manipulation

In Part 1 I described how SharePoint 2010 exposes list data through ListData.svc and WCF Data Services. So far this is interesting, but the next logical question is how would you actually build a Web 2.0 application with the data? One answer is with a new technology called ASP.Net AJAX 4.0 Client Side Templating. I’ll give you some background and then provide a walkthrough of how to build a SharePoint application page that reads and writes data to SharePoint through ListData.svc.

What is ASP.Net AJAX 4.0 Client Side Templating?

In Part 1 I talked about some of the problems with the two existing ways of writing Web 2.0 interfaces. ASP.Net AJAX 4.0 Client Side Templating addresses most of these issues. Specifically it:

  • Minimizes plumbing code
  • Cleanly separates presentation from data access code
  • Simplifies saving data back to the server via Live Data Bindings
  • Has no ViewState!
  • Uses lightweight JSON rather than HTML

Sounds good? Ready to see some code?

Show Me The Code

Note: This walkthrough assumes you haven’t played with Visual Studio 2010 and SharePoint 2010, so please skip ahead to “No Really, Show Me the AJAX Templating Code” if you’ve already seen the sweet SharePoint and Visual Studio integration.

To get started open Visual Studio 2010. Select New Project and for the template navigate to SharePoint then 2010 select “Empty SharePoint Project” (p.s. see Visual Web Part in the list? Make sure you look that up if you haven’t heard of it yet).

If you haven’t been keeping up with what’s new in SharePoint 2010 you should immediately notice that SharePoint integration is built into Visual Studio 2010 out of the box just based on the listed templates. But just wait, it gets much better.

The next screen asks what site you want to use for debugging. It’s asking this because when you hit F5 (“Start Debugging”) Visual Studio 2010 packages up your wsp file, deployes it to the URL you enter here, attaches to the w3wp process, and opens a browser into SharePoint, and you’re immediately in debug mode!

If you aren’t deeply impressed then you haven’t developed in WSS 3.0. Now we aren’t writing any server side code in this tutorial, but it’s still extremely impressive how much work Microsoft has put into making SharePoint a first class citizen.

Once you have your site select Project -> Add New Item and select Application Page.

Visual Studio then plops out 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>

(ok, the “Hello World!” is mine). Now if you hit F5 or click Build -> “Deploy Solution” then as I mentioned SharePoint packages up the application page into a wsp file and deployes it out to SharePoint. Now if you navigate to your application page (in my case http://localhost/mysite/_layouts/MyAppPage/ApplicationPage1.aspx) then you should see something like this:

Amazed? You should be. We didn't write a line of evil looking CAML, didn't have to write any DOS batch files, 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! Ok, enough exuberance, back to business.

No Really, Show Me the AJAX Templating Code

Before writing code you should probably create some lists to read and write to. As I mentioned in a previous post I like tracking user stories in SharePoint. So for my examples I have an Iterations list and a User Stories list, which is based off of the Tasks content type (automatically giving you a number of columns like Priority).

After creating some lists you need to ensure you have the latest ASP.Net Ajax Library. I suspect an updated copy will be included with the RTM copy of SharePoint 2010, but in my case I downloaded the latest copy and moved the entire Scripts directory into C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ajax. Note that out of the box SharePoint 2010 already included some of these files in LAYOUTS, but it was missing others, so this step was necessary.

So here is the absolute simplest templating example that still works:

<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
    <script type="text/javascript" src="../ajax/MicrosoftAjax.js"></script>
    <script type="text/javascript" src="../ajax/MicrosoftAjaxDataContext.js"></script>
    <script type="text/javascript" src="../ajax/MicrosoftAjaxTemplates.js"></script>
    <script type="text/javascript" src="../ajax/MicrosoftAjaxAdoNet.js"></script>
</
asp:Content>

<
asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    <script type="text/javascript">
        function pageInit() {
            var dataContext = $create(Sys.Data.AdoNetDataContext, {
                       serviceUri: "/demoprep/_vti_bin/ListData.svc"
                     });

            $create(Sys.UI.DataView,
                {
                    autoFetch: true,
                    dataProvider: dataContext,
                    fetchOperation: "UserStories",
                    fetchParameters: { $top: 20 }
                },
                null,
                null,
                $get("userStoriesList")
            );
        }
        Sys.Application.add_init(pageInit);
    </script>

    <ul id="userStoriesList" class="sys-template">
        <li>{{ Title }}</li>
    </ul>
</
asp:Content>

The four script references in the PageHead Content control are necessary to define the required ASP.Net AJAX JavaScript classes you’ll need for templating. But the Main content control is where things get interesting.

Skip over the JavaScript for now and notice the unordered list named userStoriesList. Inside of the li elements is a strange notation: {{ Title }}. This specifies a binding to the name of a SharePoint field. You could also have put in PriorityValue or any of the other columns specified in the JSON that I showed in Part 1.

As far as the JavaScript, the dataContext variable is a class of type AdoNetDataContext, which knows how to talk to WCF Data Services like ListData.svc. It inherits from a JavaScript class called DataContext which is extensible and knows how to talk with other protocols, but us SharePoint developers probably won’t care about this most of the time.

The userStoriesTemplate variable is a class of type DataView. This is where the magic happens. DataViews pull data from a DataContext, duplicates the innerHtml of an associated DOM element for each row returned (e.g. userStoriesList), and replace the binding syntax with real data. Seems simple enough, but it is actually quite sophisticated when you get to some more advanced scenarios that I’ll describe later.

One last thing to notice is the sys-template class. This is a prespecified CSS class that ASP.Net AJAX sets to display: block when it is finished rendering. It’s a good idea 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. Obviously you should do this in a separate CSS class in LAYOUTS or if you’re lazy you can put it in the PageHead content control like so:

<STYLE type="text/css">
       .sys-template { display: block; }
</STYLE>

<
asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
       <script type="text/javascript" src="../ajax/MicrosoftAjax.js"></script>
       <script type="text/javascript" src="../ajax/MicrosoftAjaxDataContext.js"></script>
       <script type="text/javascript" src="../ajax/MicrosoftAjaxTemplates.js"></script>
       <script type="text/javascript" src="../ajax/MicrosoftAjaxAdoNet.js"></script>
       <STYLE type="text/css">
              .sys-template { display: block; }
       </STYLE>
</
asp:Content>

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

Summary

Ok, this isn’t super exciting yet. We certainly could have done this much easier with server side code. But bear with me, this has a lot of potential. For instance, how do you write data back to the server? How do you really make it AJAXy? I’ll explore these questions in Part 3 – Writing data back to SharePoint with ASP.Net AJAX 4.0 Templates and subsequent posts in the series.

2 comments:

dan rogy said...

My current project requires ability to display choice column value via color or image associated with a choice

But Sharepoint standard packaged misses that control

I am looking for available solutions on market

I came across

http://sharepointfields.com


Does anybody has experiece using it?

deep said...

wonderful blog information