Tags

, , ,

Dataformwebpart is probably one the most powerful web parts in SharePoint environment. But one of the biggest problems is it is not very well known by the developers, therefore is considered to be hard to work with. I don’t feel the same and I am still digging into it.

One of the recent challenges working with it was to create from scratch grouping functionality, which is very close related to select distinct values technique in XSLT. Let’s take steps one by one.

First thing, I need to set a parameter to define dynamically grouping criteria. This consists into two changes. One is to bind the parameter in “ParameterBindings” section.

<ParameterBinding  Name="GroupBy" Location="QueryString(GroupBy)" DefaultValue="Title" />

The second step is to let know SPDataSource about parameter and execute select command according to it’s value.

<SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" UseServerDataFormat="false" selectcommand='<![CDATA[<View><Query><GroupBy><FieldRef="{GroupBy}" /></GroupBy></Query></View>]]>'>
<SelectParameters>
<WebPartPages:DataFormParameter Name="ListName" ParameterKey="ListName" PropertyName="ParameterValues" />
<WebPartPages:DataFormParameter Name="GroupBy" ParameterKey="GroupBy" PropertyName="ParameterValues" />
</SelectParameters>
</SharePoint:SPDataSource>

Now, it remained to work with XSLT. This should start with the following code.

<XSL>
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:param name="GroupBy" />


</xsl:stylesheet>
</XSL>

Now as our XSLT knows about GroupBy parameter, I need to create grouping headers template and select only distinct values for grouping field.

<xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">

<table>
<thead>
<tr>
<td>Title</td>
</tr>
</thead>
<tbody>
				<xsl:call-template name="GroupHeaders">
				</xsl:call-template>
</tbody>
</table>

</xsl:template>

<xsl:template name="GroupHeaders">
<xsl:for-each select="/dsQueryResponse/Rows/Row[not(@*[name() = $GroupBy] = preceding-sibling::Row/@*[name() = $GroupBy])]">
<xsl:variable name="Attr" select="current()/@*[name() =  $GroupBy]" />
<tr>
<td><xsl:value-of select="$Attr" /></td>
</tr>
</xsl:for-each>
</xsl:template>

Please note how select distinct XSLT technique can adapted to be applied dynamically based on a parameter value. And now is time to call template for showing data for each displayed header.

<xsl:template name="GroupHeaders">
<xsl:for-each select="/dsQueryResponse/Rows/Row[not(@*[name() = $GroupBy] = preceding-sibling::Row/@*[name() = $GroupBy])]">
<xsl:variable name="Attr" select="current()/@*[name() =  $GroupBy]" />
<tr>
<td><xsl:value-of select="$Attr" /></td>
</tr>
<xsl:with-param name="nodeName" select="$GroupBy" />
<xsl:with-param name="nodeValue" select="$Attr" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>


<xsl:template name="RowView">
<xsl:param name="nodeName" />
<xsl:param name="nodeValue" />
<xsl:for-each select="/dsQueryResponse/Rows/Row[@*[name() = $nodeName] =  $nodeValue]">
<tr>
<td><xsl:value-of select="@Title" /></td>
</tr>
</xsl:for-each>
</xsl:template>

I hope this will help you customizing the web part. If you have any question, don’t hesitate to contact me on anvlpopescu@yahoo.com. As always, my code is not perfect, but can give you a start. Happy Codding!

Advertisements