Occasionally you want to display a single SharePoint list/document library item at random on screen refresh. Possible uses include rotators for quotes, images, or featured documents. I did some searching on the web for a solution, but outside of writing custom web parts, I did not find anything.
I developed the following solution using SharePoint Designer and a Data View web part.
This will work well as long as you can live with the following constraints:
- You don"t have any gaps in your ID numbers. A gap will result in a blank result on that particular refresh.
- You have no more than 60 items
This is how:
-
Create a new Data View web part in SharePoint Designer that displays all records in the format you want. We will end up only showing one record, so keep that in mind when you are laying this out.
- Open the Filter dialog
- Do not add any clauses, instead check the Add XSLT Filtering box and click Edit
- Create your XSLT filter. You can just paste in the following code:
[@ID = (substring(ddwrt:FormatDateTime(ddwrt:TodayIso(),1033,":mm:ss"),6,2) mod count(/dsQueryResponse/Rows/Row))+1]
- Click Ok and save the page in SharePoint Designer
- Check your work in your browser. Refresh the page to see the item rotate.
Technical Details
First you need to know that the filter logic is executed for each record. You may notice that there is a Random function available in the XSLT filter. The problem is it generates a different random number for each record in the result set. I initially tried using the logic of SelectedID = RandomNumber, but I found that you cannot guarantee how many records will actually get displayed. You may end up with 0, 1, or multiple depending on the random numbers generated.
I needed logic that would get evaluated for each record that would guarantee that I would end up with exactly one result. I ended up picking the item to display based on the seconds value of the current time when the page is loaded. So if the time is currently 8:02:05, then we display the 5th item. I use the MOD function to so that we always get a hit i.e. ID = Seconds MOD NumberOfItems + 1. The main downside of this logic is that you may end up with no result if you have gaps in your IDs (i.e. you have deleted records from this particular list). Some may object that using seconds is not truly random, but in practice it is good enough for most uses.
I found that working with the FormatDateTime() function was a little frustrating. It will only let you grab certain chunks of the date and time. For instance, I could not grab just the seconds, I had to grab both the minutes and the seconds and then use the substring() function to isolate the seconds.
Enjoy!
<Clayton Leonard />
P.S. It should be possible to develop a better solution by editing the For Loop in the XSLT generated by the Data View and using the Random function to pick the record to display. This would work even if items had been deleted. The main drawback to this approach is it prevents further edits to the web part using native Data View functionality - all future changes would require editing the XSLT.
Posted
04-26-2007 7:10 PM
by
wkkf