From the SPServices Discussions: Why Should I Bother to Learn XSLT?

Client Server DiagramHere’s a question from gdavis321 from the good old SPServices discussions. In most cases, I just answer the questions in situ, but occasionally – as you frequent readers know – I realize what I’m writing feels more like a blog post, so I move it over here.

It seems that Spservices (thank you for this god send) can do anything that you might want to do with a content query webpart or other webpart… am I missing something? Why should I bother to learn XSLT?

It’s a fair question. As someone who loves using the Data View Web Part (DVWP) – which is XSL-based – the answer is, as always, it depends.

Doing everything client side isn’t always a great idea. For each specific requirement, you should look at whether it makes more sense to do the heavy processing on the server or client. There are many variables which go into this, like client machine capabilities, data volume, number of data sources, need to join data from different sources, skills on the development team, desired time to market, etc.

In SharePoint 2013, much of the processing has moved to the client side (often called Client Side Rendering, or CSR), so many people think that we should just process everything client side now. I worry about this sort of myopia.

Client machines – meaning the machine sitting on your desk or in your lap or hand rather than the server, which sits in a data center somewhere – have better and better capabilities. Yet in many organizations, you may still see Windows XP machines with 1Gb of RAM – or worse!

Additionally, client side processing may mean moving a huge volume of data from the server to the client in order to roll it up, for example. If you’re moving thousands of rows (items) to make one calculation, it *can* feel sluggish on client machine without a lot of oomph.

So client side libraries like SPServices or KnockoutJS or AngularJS (among many others) are fantastic for some things, not so fantastic for others.

When it comes to the JavaScript versus XSL question, both approaches should be part of your toolset. Sometimes good old XSL will be an excellent call if you can do some of the heavy lifting on the server, then pass the results to the client for further processing. The output need not be just nicely formatted list views, but could be sent in such a format as to make the client side processing easy to start up upon page load. My approach is often to ship the data to the browser via a DVWP and then process it further with jQuery on the client.

The mix of what happens where is on a spectrum, too, depending on what you need to do. You might roll up tens of thousands of items in a DVWP and then request items from two or three other lists from the client as the page loads to optimize your architecture.

Yup, there’s that architecture word. A good SharePoint architect will know when to use each of the tools in the toolkit, and JavaScript and XSL are just two of many.

Keep in mind that because “it depends”, your mileage may vary in any and all of this: cavete architectus.

Single-Page Applications (SPAs) in SharePoint Using SPServices – Part 3 – GetListItemChanges

In building a Single Page Application (SPA), we’ll usually want to keep the data we’re displaying up to date. You can probably think of many examples where you see this on the Web, but newsfeeds are a prime example. While we’re sitting on the page, we see newly posted content pop up, usually on the top of the feed. To do this, we can simply set up a call to run at fixed intervals using JavaScript’s timing functions setTimeout() or setInterval() to pull back the data.

If the content we want is in a list, it’s “expensive” to request all of the items at each interval. Instead, it’s much better to either cache the items if they rarely change – as is available in SPServices 0.7.2+, though the approach in 2013.01 is much improved – or to request only those items which have changed since the last request.

There are two operations which can help with this: GetListItemChanges and GetListItemChangesWithToken.

[important]GetListItemChanges and GetListItemChangesWithToken do not work in versions of SPServices before 2013.02.[/important]

In this post, let’s take a look at the GetListItemChanges operation.


GetListItemChanges retrieves changes to the list since a specified date/time. The parameters are similar to those for GetListItems, with a few additions:


See the GetListItems post in this series.


See the GetListItems post in this series.


See the GetListItems post in this series.


A date/time specified in Coordinated Universal Time (UTC) ISO8601 format. What that means is that the date/time has to look like “2013-06-30T15:29:43Z”. That’s “YYYY-MM-DDThh:mm:ssZ”. The “Z” means “Zulu” time, or GMT. You can also provide time offsets, like “2013-06-30T15:29:43-05:00” for Eastern (US) Time.

Because I’m a nice guy, I have a function in SPServices called SPConvertDateToISO to convert JavaScript date/time objects to the ISO8601 format.


The contains parameter is much like the CAMLQuery parameter in GetListItems, but a little simpler. For instance, you may only be interested in list changes where the current user is the Author, in which case you’d pass:

contains: "<Eq><FieldRef Name='Author'/><Value Type='Integer'><UserID/></Value></Eq>",

If you don’t pass anything for contains, you’ll get back all of the changes since since.

Because the GetListItemChanges operation retrieves only changes in the list, the requests will return very slim results in all but the most active lists. However, the operation will prove valuable in our SPA development because it will allow us to keep our display current for the user with a minimum of fuss unless there have been changes to the underlying data.

GetListItemChanges Returns

When Paul Tavares (@paul_tavares) pointed out the GetListItemChangesWithToken operation a while back, I recalled that I never could get it running properly in my test environment back when I first wrapped it in SPServices. I wrote it off to either my own ineptitude or simply a bug on the Microsoft side (that wouldn’t be a first). At the time, it didn’t seem as though the operation offered enough benefit to chase it down any further.

I was wrong on several counts, of course. The bit about my ineptitude was the one part I was right about. When I wrapped the operation, I accepted two things about it that the documentation told me:


A string that contains the change token for the request. For a description of the format that is used in this string, see Overview: Change Tokens, Object Types, and Change Types. If null is passed, all items in the list are returned.


A Contains element that defines custom filtering for the query and that can be assigned to a System.Xml.XmlNode object, as in the following example.

   <FieldRef Name="Status"/>
   <Value Type="Text">Complete</Value>

This parameter can contain null.

The italicized, maroon parts were the issue. While it’s probably possible to pass null on the server side, there’s no such analogous value on the client that we can pass. Since everything we pass is text, generally an empty string will work in those operations where null is allowable. But not in this case.

This means that in all versions of SPServices until the alpha I’ve currently got posted, the operations GetListItemsChanges and GetListItemsChangesWithToken won’t work, no matter how hard you try. That’s because I passed empty strings for the elements above, which just throws an error.

All that said, GetListItemsChanges returns XML that looks the same as what GetListItems gives us.

<listitems xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
   xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"
   <rs:data ItemCount="4">
      <z:row ows_Number_Field="6555.00000000000"
         ows_ID="3" ows_owshiddenversion="3" />
      <z:row ows_Number_Field="78905456.0000000"
         ows_ID="4" ows_owshiddenversion="2" />

There’s one subtle difference. Can you spot it? GetListItemChanges gives us one additional piece of data with the results, and that’s the TimeStamp value. This date/time value tells us when we requested the data, so we can use that value to inform the user when the data was last updated, should we want to.

Processing GetListItems Results

Processing the results from GetListItemChanges is just about the same as with GetListItems.

var out = "<ul>";
  operation: "GetListItemChanges",
  since: "2013-11-14T11:00:00-5:00",
  async: false,
  listName: "Announcements",
  CAMLRowLimit: 0,
  CAMLViewFields: "<ViewFields><FieldRef Name='Title' /></ViewFields>",
  completefunc: function (xData, Status) {
    var timeStamp = $(xData.responseXML).SPFilterNode("listitems").attr("TimeStamp");
    var itemCount = $(xData.responseXML).SPFilterNode("rs:data").attr("ItemCount");
    $(xData.responseXML).SPFilterNode("z:row").each(function() {
      out += "<li>" + $(this).attr("ows_Title") + "</li>";
    out += "</ul>";

Here I’m making the call to GetListItemChanges to get all of the items in the Announcements list which have changed since 11am this morning in Boston.


GetListItemChanges is a great addition to our toolkit because it allows us to make requests for items in a list that have changed since a time we specify. While we could accomplish something similar with GetListItems by passing in a filter for Modified in the CAMLQuery, GetListItemChanges is built for exactly what we need, and I would hope that it is therefore more efficient on the server side.
is a workhorse, all right, but we need more for our SPA work. In the next three parts of the series, I’ll introduce its siblings: GetListItemChanges, GetListItemChangesWithToken, and UpdateListItems. These four operations together will help us to build a highly interactive SPA and provide valuable functionality for our users.

SharePoint Saturday Chicago 2013 Follow Up

I can honestly say that I’m sure that everyone enjoyed SharePoint Saturday Chicago yesterday. From the location at the Hard Rock Chicago to the fantastic speaker line up (I snuck in) to the overall convivial atmosphere, it was an event to remember. Kudos go out to Kris Wagner (@SharePointKris), Doug Hemminger (@DougHemminger), Chris Geier (@chrisgeier), and Bryan Gulley (@UXJester) for all the hard work they put in to make it a special event. I know many others worked long and hard, too, but those names are not in my old brain. Thanks to all of you!

IMG_6503[1]Dux Sy (@meetdux) kicked things off with his keynote “Lead the Enterprise Social Revolution”, where we learned that #shifthappens. Yuo can see Dux’s entire presentation in a live recording on UStream or review or download his slides on SlideShare.

There were some other sessions.

My session was about “Designing with SharePoint 2013”, wherein I attempted to describe some of the high level goals one should have in designing for the platform as well as to demonstrate the great capabilities in the new Design Manager.

We had a standing room only crowd in the truly small Firebird room, so we all got a bit more chummy by rubbing elbows and knees. I was able to assist my pal Marcy Kellar (@marcykellar) in welcoming SharePoint newcomer Cara Gail (@caragail) from Indianapolis.

This session will introduce you to the possibilities of design and customization in SharePoint 2013. Tour the newest interface features, learn best practices, and discover exciting new ways to interact with your SharePoint 2013 environment.

While we can still implement designs in SharePoint 2013 the “old way” we’re used to, there are new capabilities that can make the process easier for both designers who are very familiar with SharePoint and those designers who have never worked with SharePoint.

We’ll look at the new Design Manager capabilities and learn how to create and integrate Master pages, Display Templates, and Page Layouts.  Not only does the Design Manager make it easier to create new designs for SharePoint from scratch, it can also help you manage your existing designs after an upgrade. The Design Manager even allows designers to use the tools they know and love like Dreamweaver, Photoshop, or any other HTML editor.

I didn’t have any fancy-schmancy live video recording going on like Dux did, but you can see my slides on SlideShare.

IMG_6508[1]After the formalities and a brief SharePint, a bunch of speakers and a few attendees decided to have dinner at The Signature Room at the 95th® (“The Restaurant Chicago Looks Up To”, don’t you know?) You can see the crew in this photo: Lori Gowen (@LoriGowin), Doug Hemminger (one of our most excellent hosts for the event), Kim Frehe (@KimFrehe), Brittany Kwait (@BrittanyKwait), Michelle Caldwell (@shellecaldwell), Chris Johnson (@LoungeFlyZ), Ruven Gotz (@ruveng), and another SharePoint community newcomer Dan Moore. (Dan: Isn’t the SharePoint community awesome? How was the duck hash this morning?)

IMG_6541[1]Finally, I had a little time to walk around this morning and made it to see a few things. Most impressive was “The Bean”, aka “Cloud City”. I’ve wanted to see this sculpture ever since it was first installed, and it did impress. (I really only went to see it to make Dave Coleman (@davecoleman146) jealous, and it worked.)

Setting a Conditional Breakpoint in Firefox with Firebug

Every once in a while I click randomly on something and realize that I’ve been an idiot. OK, sometimes it doesn’t require clicking on anything.

First off, if you’re working on client side code and you aren’t using Firefox with the Firebug add on, you should be. It gives you all the debugging capability that you need to win. (Some others swear by Chrome, but I’ve been developing with Firefox for a long time.)


Everyone else has probably known this for millennia, but I just figured out today that I can set a conditional breakpoint in Firebug. If you right click on a line where you’ve set a breakpoint (this was my random click), you get a syntax menu that looks something like this:

Firebug Breakpoint Context Menu

By selecting Edit Breakpoint Condition… you can add any valid JavaScript condition. Here’s one I used to break when I was processing row 55 in a loop:

Firebug Conditional BreakpointSetting a condition like this is really useful, especially when you know that item 55 out of 4645 is causing an error and you just want to step through your script for that item.

There’s more to conditional breakpoints in Firebug [I know now], as you can read in the Firebug Tip: Conditional Breakpoints post on the Firebug blog.

Perhaps because I’m old school, while I’ve truly wanted to be able to set conditional breakpoints like this I’ve simply changed my indices or put in conditional debugging statements. I’ve gotten by just fine, but I’m going to be a lot more efficient now. If you didn’t know about this little trick, then hopefully you’ll be more efficient now, too.

Or maybe I’m just an idiot.

SPServices Passes 100,000 Total Downloads

Here are some numbers for the meaningless-but-fun-statistics bin. Codeplex collects a bunch of numbers for me, so I can preserve them here.

Yesterday, Sunday, October 27th, 2013, SPServices crossed the 100,000 total downloads threshold. I posted the first version of SPServices (SPServices 0.2.3) on Codeplex on Aug 19th, 2009 as an alpha. That means it’s taken 4 years, 2 months, and 9 days – that’s 1531 days – to reach 100,000 downloads. That’s over 65 downloads per day!

SPServices 100,000 DownloadsDuring that same period, SPServices has also had almost 3,000,000 page views – 2,945,339 to be exact. I like to think that this number is a testament to the quality of the documentation.

SPServices 3,000,000 Page ViewsThere have been over 3/4 million visits to the Codeplex site.

SPServices 3/4 Million VisitsIt’s been a fun 4 years, 2 months, and 9 days working on and supporting SPServices. I doubt it’s got another 4 years in it, but I look forward to many more months and downloads to come.

Yes, I do make it up in volume.