Skip to main content

Cloud

Randomize SharePoint List Items

Challenge
 
You have to show items from a SharePoint list in a random order. Maybe it’s a subset of data (or just one item). Maybe it’s everything, just returned in a random order.
 
Approach
 
You may think .NET code is necessary to make that work, but there’s a much easier approach. SharePoint’s decoupling of list items from their presentation allows us to present arbitrary data in any format we want.
 
The approach outlined here relies on eXtensible Stylesheet Language Transformations (XSLT) to format aggregated data.
 
 
Several SharePoint web parts allow results to be styled with XSLT, including:
  1. Content Query Web Part
  2. Data View Web Part
  3. Search Core Results Web Part
From Scratch
 
If you’re starting from a blank slate, the first step is to decide which web part to use for aggregating list items.
 
When To Use a Content Query Web Part
 
If you need to “roll up” content spread across multiple lists or webs, the CQWP is the easiest path to do so. It provides a straightforward UI for selecting your list(s), content type(s), web(s), and filtering criteria. On the downside, CQWPs are more difficult to style and rely on modifying other files including ItemStyle.xsl and Header.xsl.
 
When To Use a Data View Web Part
 
If you only need to show data from one list and SharePoint Designer is installed, the DVWP is easiest to style. Joining data from multiple locations is complicated, but SharePoint Designer makes editing and previewing XSLT easiest.
 
Decide carefully between the two options.
  1. For guidance in setting up a Content Query Web Part, see this guide from Heather Solomon.
  2. For guidance setting up a Data View Web Part, see this guide by Laura Rogers.
The important consideration for this guide is to return all list items that will selectable for our randomizer (the corpus of data).
 
Randomizing Results
 
Once all possible list items are being returned by your web part, it’s time to customize the underlying XSL formatting to randomize our results.
 
If working with a CQWP, that logic will live within files in /Style Library/XSL Style Sheets/ such as ItemStyle.xsl and Header.xsl. If working with a DWVP, the XSL can be manipulated by viewing source in SharePoint Designer. For other XSLT web parts such as Search Code Results, you should be able to edit XSL directly in the web part properties.
 
Enabling the ddwrt:Random() function
 
The trick to randomizing results in XSLT is making a special function in the DDWRT namespace available. That’s a SharePoint-specific set of functions that Microsoft built. Data View Web Parts reference DDWRT by default, but other web parts need a reference to be explicitly added.
 
I described how to do so in a previous post. It involves adding the bold sections to your opening <xsl:stylesheet /> block:

<xsl:stylesheet version=”1.0″ exclude-result-prefixes=”x d ddwrt cmswrt xsl msxsl” xmlns:x=”http://www.w3.org/2001/XMLSchema” xmlns:d=”http://schemas.microsoft.com/sharepoint/dsp” xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” xmlns:cmswrt=”http://schemas.microsoft.com/WebParts/v3/Publishing/runtime” xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:msxsl=”urn:schemas-microsoft-com:xslt”>

The “Randomize” Template
Once the DDWRT namespace has been added, the ddwrt:Random function will be usable. It accepts two parameters: a minimum number and a maximum number. We’ll be using that in a custom template to choose results.
Here’s the core template to add to your XSL:
 
<xsl:templatename=Randomize>
<
xsl:paramname=Rows />
<
xsl:paramname=Limit />
<xsl:variablename=SelectedRowselect=ddwrt:Random(1, count($Rows)) />
<
xsl:value-ofselect=$Rows[position() = number($SelectedRow)]/@FileLeafRef /><br/>
<xsl:iftest=count($Rows) &gt; 1 and ($Limit &gt; 1 or $Limit = 0)>
<
xsl:call-templatename=Randomize>
<
xsl:with-paramname=Rowsselect=$Rows[position() != number($SelectedRow)] />
<
xsl:with-paramname=Limitselect=$Limit – 1 />
</
xsl:call-template>
</
xsl:if>
</
xsl:template>
 
That template accepts two parameters.

  • Rows: The node set of items to choose from.
  • Limit: The number of items to return. To return everything, pass 0.

It works by selecting one node at a time, then iterating through the remaining nodes one at a time until either there are no nodes left or the limit has been met. Because of the recursive approach, overall running time is bound by O(N^2) where N is the number of nodes.
Randomizing Results
Once that template has been added, you can replace existing xsl:for-each loops with the following:
<xsl:call-templatename=Randomize>
<
xsl:with-paramname=Rowsselect=/dsQueryResponse/Rows/Row/>
<
xsl:with-paramname=Limitselect=1/>
</
xsl:call-template>

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.

Bert Johnson

More from this Author

Follow Us