Wednesday, February 06, 2008

Sorting DataView in SharePoint

Recently I was trying to connect a DataView Web Part to another Web Part containing sort options, so I could present a view of names and phone numbers and let the end-user choose how they'd like the view sorted.

Seems simple enough, right?

Maybe there's an easier way, but twice I've been trapped by the same idiosyncrasy in XSL sorting.

When you add a DataView Web Part in SharePoint designer, the XSL code is generated for you. If you specify a sort for your DataView, for example a sort by 'Name', you'll see something similar as your xsl-sort tag:

<xsl:sort select="Name" order="ascending" />

To make it dynamic, I connected the Web Parts and passed a parameter from my sort options Web Part to my DataView Web Part. The parameter was called SortOrder, so I assumed I could just change the select attribute to $SortOrder and it would sort by Name or Phone depending on what the user had selected.

It turns out this does not work, and the workaround is to use this code instead in the select attribute:

<xsl:sort select="*[name()=$SortOrder]" order="ascending" />

That worked great for me the first time I ran into this problem. The XML that was feeding the DataView had the data stored in elements like so:

<People>
 <Person>
   <Name>Joe Smith</Name>
   <Phone>999-999-9999</Phone>
 </Person>
</People>

But what if the data is stored in attributes instead? This is the case when you feed your DataView Web Part with another SharePoint List. The data comes over in a form somewhat like this (thanks to David Wise's post for help in discovering this)

<People>
 <Person Name="Joe Smith" Phone="999-999-9999">
 </Person>
</People>

In this case, you'll need to use the following select attribute to make this work (note the @ attribute sign)

<xsl:sort select="@*[name()=$SortOrder]" order="ascending" />

I'm no expert in XSL, but essentially this says to me select all attributes with an attribute name of $SortOrder.