Alpha Selection of List Items in a Data View Web Part (DVWP)
Say you have a list of people (or rooms or products or whatever) where you would like to let the user specify the first letter of the person and then show them all of the people’s names which start with that letter. Doable, of course, and a nice little recursive XSL template can get you there. The little screenshot below doesn’t look like much, but it shows an example of this type of alpha listing with the letter C selected.
The Alpha template below takes two parameters:
- Rows: The nodeset which contains the rows you want to work with (needed to make the right letters links vs. static text)
- RemainingLetters: The list of ‘remaining’ letters you have to work with. On first call, this should be ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’, since you still have the whole alphabet to go.
The template is recursive; as long as there’s still work to do, it calls itself again with the remaining letters to work with. There are a couple of slick bits to this:
- The xsl:attribute setting of the style bolds the letter if it is the letter the user has chosen
- If there aren’t any items in the list which start with the letter, then we don’t make the letter a link. (It’s always annoying to have a link that returns you nothing.)
- The links simply call the same page with the chosen letter on the Query String (?Letter=X)
<xsl:template name="Alpha"> <xsl:param name="Rows"/> <xsl:param name="RemainingLetters"/> <xsl:variable name="ThisLetter" select="substring($RemainingLetters, 1, 1)"/> <td> <xsl:attribute name="style"> <xsl:if test="$ThisLetter = $Letter"> font-weight:bold; </xsl:if> </xsl:attribute> <xsl:choose> <xsl:when test="count(/dsQueryResponse/Rows/Row[starts-with(@Title, $ThisLetter)])"> <a href="{$URL}?Letter={$ThisLetter}"><xsl:value-of select="$ThisLetter"/></a> </xsl:when> <xsl:otherwise> <xsl:value-of select="$ThisLetter"/> </xsl:otherwise> </xsl:choose> </td> <xsl:if test="string-length($RemainingLetters) &> 1"> <xsl:call-template name="Alpha"> <xsl:with-param name="Rows" select="$Rows"/> <xsl:with-param name="RemainingLetters" select="substring-after($RemainingLetters, $ThisLetter)"/> </xsl:call-template> </xsl:if> </xsl:template>
You can call the Alpha template like this:
<xsl:call-template name="Alpha"> <xsl:with-param name="Rows" select="$Rows"/> <xsl:with-param name="RemainingLetters" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> </xsl:call-template>
and the row selection looks like this:
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[ starts-with(@Title, $Letter) or string-length($Letter) = 0 ]"/>
Is there anything I need to do differently to get this to work with a joined list?
Glenn:
That’s got to be a big “it depends”.
M.
Hi Marc,
This solution is great and I wondered if the same result can be achieved in a list that uses folders?
Many thanks
Ben
Ben:
Sure. You just need to change the DataSource to include items inside folders. Just add Scope=”Recursive”.
M.
Good Morning
I am a beginner developer c #, I want to learn xslt.
From your example, I tried to create the XSLT file, but it does not work
Can you provide me a complete example to Set my web part?
thank you very much
DRO:
I can’t just give you an XSL file because it depends on what you are trying to do. You can use this template as part of your XSL.
M.
Do you have full instructions for SharePoint 2010 A to Z index.
Debra:
This will work just fine in 2010.
M.
any help how to do this sort of thing for a website?