I didn't have much trouble finding a bit of scripting (via Google) to achieve this effect. I ran in to difficulties when I wanted to take this one step further and present several random items from a SharePoint list. However hard I Googled, I just couldn't turn up comprehensive, step-by-step instructions on how to display more than one random item.
The solution turned out to be a combination of two different methods, that I'd picked up in two different locations. As always, as I couldn't find the total solution by Googling alone, I'll explain how to display a number of random items from a list here.
First things first: set up a list. In my case, I wanted to display a set of four large buttons that users can click on to be taken to content in the sub-sites below the top level of the Intranet. So to have a reasonable selection of buttons to choose from, I specified at least eight for each landing page. These were stored in a document library.
As a document library is a just a flavour of list, I decided to keep things simple by using the library to double for the list and added my metadata in extra columns in the Document Library.
So I used the Title field to store the text equivalent (alt attribute) for the button image. Then I added a custom column to hold the destination URL. You could use a Hyperlink-type content type, but I just opted for a Single line of text, to keep things simple. I also added an extra column to hold the value for the tab page the buttons would be appearing on, set up as a Choice.
Then I uploaded all the button images and made sure the metadata was completed correctly.
|
The next step might not apply to you, but I was looking to manage a button set for each of my main tab pages on our Intranet. So once I had the Dataview Web Part on the page, I needed to filter out the irrelevant buttons.
In SharePoint Designer, there's a wizard that allows you to Filter, sort and set the number of items displayed. |
This allows me to filter out all the buttons except for those tagged as "Community". |
The raw DVWP tends to nest tables inside tables which can get messy and complex to work with. Some people prefer to replace the table elements with DIVs, and sometimes I might do that. But here, I thought I'd stick with a simplified table as I wanted to iterate across the row, rather than down the column. So first I removed the extra nested table.
Inside the "rowview" template, first take out the TR, TD and TABLE tags ... |
... SharePoint Designer then highlights the closing tags for you, making them easy to find and delete. |
Wrap the dvt_1_body template in TR tags. |
Deleting the table column is very simple. |
So I removed the unneeded TR tags ... |
Re-arranging the value-of calls and eliminating the unwanted TD tags. |
Here's the final code ... |
Next, I needed to go back to the Wizard and set the Paging to Display All Items.
Select Display all items ... |
I'd already previously implemented DVWPs where the script selected one item at random from the list to display. Suitable techniques for this are not difficult to find on the Internet via Google search. I've come across several ways to do this. The one I've most commonly used is:
<xsl:template name="dvt_1.body">
<xsl:param name="Rows"/>
<xsl:variable name="Random" select="ddwrt:Random(1,count($Rows))" />
<xsl:for-each select="$Rows[position()=$Random]">
<xsl:call-template name="dvt_1.rowview" />
</xsl:for-each>
</xsl:template>
... but this only displays one random item from the list. My challenge was to get the DVWP to display four random items. I figured this would be made more difficult because I didn't want to any of the items to be repeated, which would be a possibility with a routine that selected four items randomly, one after another.
But while digging around on Google, I came across several different ways of rendering a random item from a list and came to understand that I might have to combine two different methods to get the effect I wanted.
In the end I settled for a slightly different way of rendering a random item that turned up in several different SharePoint blogs, but this is the one I came back to.
<xsl:for-each select="$Rows">
<xsl:sort select="ddwrt:Random(1, $RowCount)" order="ascending"/>
<xsl:call-template name="dvt_1.rowview" />
</xsl:for-each>
What this is doing is sorting the items in the list into a random order and rendering the first one. It's a slightly different approach to the one I was using, but it does get me a step closer to where I want to be.
I did get error messages with this saying that the variable wasn't defined, so I added in the line:
<xsl:variable name="RowCount" select="count($Rows)" />
... before the <xsl:for-each= ...> line and it seemed to work okay.
All I had to do next was figure out how to select the first four items in this randomised list and I'd be there. I found something on another blog that selected the first x number of items from a list, so I figured I might be able to combine the two elements to get a randomised first four items ... I added the line:
<xsl:if test="position() < 5">
This is saying: display the row if the position is less than five (ie, four, then) ... so the "for-each" section should now look like this:
<xsl:variable name="RowCount" select="count($Rows)" />
<xsl:for-each select="$Rows">
<xsl:sort select="ddwrt:Random(1, $RowCount)" order="ascending" />
<xsl:if test="position()<5">
<xsl:call-template name="dvt_1.rowview" />
</xsl:if>
</xsl:for-each>
Now the buttons will change randomly each time the user lands on the page for the first time, or indeed refreshes the page. The final effect looks like this:
|
Hit refresh and another four images display. |
Hope this helps someone.