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
   ]"/>

Similar Posts

63 Comments

  1. 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

  2. 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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.