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    ]"/>
This is a very cool idea you came up with! Thanx // Christian
full ack – very cool. thx for sharing!
nice info.thanks for sharing
http://antwablog.blogspot.com
Yowser. I have been looking for something like this for a couple months!
I haven’t been able to get it to work yet though. Where does the “Rows: row selection variable code go?
I was able to define $URL as in the Alpha xsl template after “ThisLetter”.
I put all the code into one data view of a phone list.
I added the xsl:template after the other templates.
I called the Alpha template from a new row I added at the top of the data view.
I added the “Letter” querystring parameter through the dataview’s chevron menu.
Default value A, and then filtered the dataview on that.
That may be causing the result: Only the A is bold or linked. Only the A items show.
It sounds like you may be filtering in your CAML so the templates above will never “see” the full set of rows in the list. You’ll want to do your filtering in your XSL templates rather than in the CAML, as I show above in the third code snippet. (It generally ends up in the CAML if you filter using the dialogs.)
M.
Hello Mark
first ,thank u for that post
, Im trying to use the code above,
can u please specify where to put each code block,
for exemple using a simple contact list,
i created a page with the dataview, than added a text box
than…?
thank u very much
Koby
Koby:
I’m not sure what your text box is for, but basically you can drop the templates above into your DVWP, tweak them for your purposes, and you should be good to go.
M.
Hello Mark,
Thx for that post, it is exactly what i am looking for.
Koby, if that will help you, you can see a short movie that I made on that subject:
http://www.youtube.com/watch?v=OyhgFF5pyEw
Nice video, ValerianCh! I like the music, too! Soothing SharePoint.
M.
Thanks a lot for the vedio, makes the post complete.
Is there anyway you can make a movie about this subject for SharePoint 2010
Thank you for sharing this. The video was extremely helpful in implementing the code. My question pertains to when you “Enable sorting and filtering on column headers”. Is there a way to limit the available dropdown filters to only display the data that is currently visible? For example, if I alpha filter on names beginning with the letter A, when I click on the column header “Name” I see all names. I just want to see the names beginning with A. The List View Web Part does this by default.
Thanks in advance.
In this scenario, what would you be using the sorting and filtering on column headers for? I would think that this method would make that unnecessary.
M.
Marc,
Thanks for the quick reply. The reason I need the column header filtering is due to the type of data I’m displaying. I would provide a screenshot, but I’m working on sensitive information.
-Lee
You’ll need to do some work this make this happen. I usually throw away the column sorting stuff that SharePoint Designer outputs and just write my own so that I have more control over it.
M.
Marc,
One other question…How can the script be modified to handle lower case letters?
Thanks again.
Lee
Sure. You can use the translate function like this:
translate(@Title, ‘abcdefghijklmnopqrstuvwxyz’, ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’)
M.