In my search to a nice Picture Web Part I came across some things.
2 free Flash Web Parts that SlideShow pictures from a Picture Library. Here are the links:
http://www.flexnetconsult.co.uk/WebParts/WebParts.htm
The downside of these Web Parts is that's it SlideShow WebParts, not really useful as Picture Viewer. But hey it's free, so you might want to test it J
The opposite of Flash is ofcourse SilverLight.
There is a nice free SilverLight project on codeplex called Slide.Show
http://www.codeplex.com/SlideShow
Very handsome and customizable SilverLight project, but … no SharePoint integration. I could have used my Web Part to host it, but no.
Second SilverLight option SilverLight Photoviewer. A photoviewer with the functionality you need. Except, it's in beta fase and doesn't run now J. It does however have SharePoint integration.
http://www.codeplex.com/bjspv
There was some a mention of using the Data View Web Part instead of a hosting Web Part. See: http://www.wssdemo.com/Blog/archive/2008/01/05/sharepoint-picture-library-silverlight-demo-working-again.aspx
Not my taste and I don't know enough SilverLight to adjust it.
All this made me come to the following solution.
A Data View Web Part to show and browse your pictures. How do you start ?
- Open SharePoint Designer and add a test page
- Add a Data View Web Part to it
- Select your Picture Library in the Data Source Panel
- Show Data
- Drag and drop the fields you need. One is enough to get started
- Now SharePoint Designer makes all the XSLT you need for the library
From here on I'll show you some tricks about how to get some decent stuff
If you want a some function you don't know how to start, first look at the common tasks:
Right click and go to the arrow
Paging is one of those things that require a lot of functions
This option shows all your items in sets of 6 and adds a footer containing the navigation you need
At the Layout tab you can define most of the basic layouts. Use this before you fine tune your XSLT
General shows some more functions
Select one field of a row and right click: Format as.
This lets you change the variable to images, links, textboxes,. …
Conditional Formatting can be used to hide, highlight, … stuff.
Right Click on the row



Code view lets us then "generate" what we want see the if block
Editing Formula gives us the possibility to change the results. Very handy as you'll see later.
Formula Screen
Openign the Formula screen from within code view. Inside a XSLT tag enter a space
If you use fields elsewhere like in my example, be sure not to forget {} or else the value won't be substituted.
Now you know the basics and can start editing in code view. I made 2 XSLT views with a little of JavaScript and some CSS and got this.
The most importing part is this line:
<a href="{@FileRef}" onmouseover="changePicture('{@FileRef}');"><img height="110" border="0" src="{concat('/', substring-before(substring-after(@FileRef, '/'),'/'), '/_t/', substring-after(substring-after(concat(translate(@FileRef,'.','_'),'.jpg'), '/'), '/'))}"></img></a>
I had to change the link a bit so I could use thumbnails which are located in another folder. /Pictures/_t/filename_extention.jpg
Result:
XSLT used for it:
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:output method="html" indent="no"/>
<xsl:decimal-format NaN=""/>
<xsl:param name="dvt_apos">'</xsl:param>
<xsl:param name="dvt_firstrow">1</xsl:param>
<xsl:param name="dvt_nextpagedata" />
<xsl:variable name="dvt_1_automode">0</xsl:variable>
<!-- Here Starts the XSLT Render Process -->
<xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
<!-- Add the javascript to change the picture -->
<SCRIPT LANGUAGE="javascript">
function changePicture(picture)
{
document.getElementById("imgPhoto").src = picture;
document.getElementById("divPhoto").style.display = 'inline';
}
</SCRIPT>
<!-- Add the CSS for the Thumbnail row and the Picture Holder -->
<style type="text/css">
/* Class for the Photo Div */
.photoClass
{
border: 1px solid #000000;
background-color: #FFFFFF;
width: 590px;
padding: 10px;
display: none;
}
/* Position the Thumbnail row*/
#motioncontainer {
/*margin:0 auto; Uncomment this line if you wish to center the gallery on page */
width: 100%; /* Set to gallery width, in px or percentage */;
height: 160px;
vertical-align: middle;
margin-bottom: 20px;
}
/* Add a small invisible box around the thumbnail */
#motioncontainer a img {
border: 1px solid white;
vertical-align: middle;
}
/* Add a small gray rectangle around the thumbnail on hover */
#motioncontainer a:hover img {
border: 1px dashed #000000; /* Set image border hover color */
}
</style> <table width="100%">
<tr>
<td align="center">
<div id="motioncontainer" style="position:relative; overflow:hidden; margin-bottom:5px">
<div id="motiongallery" style="position:absolute;left:0;top:0;white-space: nowrap; vertical-align: middle; margin-bottom:20px;">
<nobr id="trueContainer">
<!-- Call the looping process -->
<xsl:call-template name="dvt_1"/>
</nobr>
</div>
</div>
</td>
</tr>
<tr>
<td align="center" valign="top">
<div id="divPhoto" class="photoClass">
<img id="imgPhoto" width="600"/>
</div>
</td>
</tr>
</table>
</xsl:template>
<!-- Here ends the XSLT Render Process -->
<!-- The XSLT Body -->
<xsl:template name="dvt_1">
<!-- Here Starts the XSLT Render Process -->
<xsl:variable name="dvt_StyleName">2ColFrm</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row" />
<xsl:variable name="dvt_RowCount" select="count($Rows)" />
<xsl:variable name="RowLimit" select="5" />
<xsl:variable name="FirstRow" select="$dvt_firstrow" />
<xsl:variable name="LastRow" select="$FirstRow + $dvt_RowCount - 1" />
<xsl:variable name="IsEmpty" select="$dvt_RowCount = 0 or $RowLimit = 0" />
<!-- Call the Header Template -->
<xsl:call-template name="dvt_1.commandheader">
<xsl:with-param name="FirstRow" select="$FirstRow" />
<xsl:with-param name="LastRow" select="$LastRow" />
<xsl:with-param name="RowLimit" select="$RowLimit" />
<xsl:with-param name="dvt_RowCount" select="$dvt_RowCount" />
<xsl:with-param name="RealLastRow" select="number(ddwrt:NameChanged('',-100))" />
</xsl:call-template>
<!-- Call the Body (the rows which are pictures here) Template -->
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows" />
<xsl:with-param name="FirstRow" select="1" />
<xsl:with-param name="LastRow" select="$LastRow - $FirstRow + 1" />
</xsl:call-template>
</xsl:template>
<!-- End of render process Template -->
<!-- Here starts the Body Template -->
<xsl:template name="dvt_1.body">
<xsl:param name="Rows" />
<xsl:param name="FirstRow" />
<xsl:param name="LastRow" />
<!-- Call the RowView Template for each Row (Picture) -->
<xsl:for-each select="$Rows">
<xsl:variable name="dvt_KeepItemsTogether" select="false()" />
<xsl:variable name="dvt_HideGroupDetail" select="false()" />
<xsl:if test="(position() >= $FirstRow and position() <= $LastRow) or $dvt_KeepItemsTogether">
<xsl:if test="not($dvt_HideGroupDetail)" ddwrt:cf_ignore="1">
<xsl:call-template name="dvt_1.rowview" />
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Here ends the Body Template -->
<!-- Here starts the RowView Template -->
<xsl:template name="dvt_1.rowview">
<!-- A Link is build per picture containing the thumbnail as link -->
<a href="{@FileRef}" onmouseover="changePicture('{@FileRef}');"><img border="0" height="90" src="{concat('/', substring-before(substring-after(@FileRef, '/'),'/'), '/_t/', substring-after(substring-after(concat(translate(@FileRef,'.','_'),'.jpg'), '/'), '/'))}"></img></a>
<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
<span ddwrt:amkeyfield="" ddwrt:amkeyvalue="''" ddwrt:ammode="view" />
</xsl:if>
</xsl:template>
<!-- Here ends the RowView Template -->
<!-- Here starts the Command Header Template -->
<xsl:template name="dvt_1.commandheader">
<xsl:param name="FirstRow" />
<xsl:param name="LastRow" />
<xsl:param name="RowLimit" />
<xsl:param name="dvt_RowCount" />
<xsl:param name="RealLastRow" />
<table cellspacing="0" cellpadding="4" border="0" width="100%">
<tr>
<!-- If there is paging needed add it -->
<xsl:if test="$FirstRow > 1 or $dvt_nextpagedata">
<xsl:call-template name="dvt_1.navigation">
<xsl:with-param name="FirstRow" select="$FirstRow" />
<xsl:with-param name="LastRow" select="$LastRow" />
<xsl:with-param name="RowLimit" select="$RowLimit" />
<xsl:with-param name="dvt_RowCount" select="$dvt_RowCount" />
<xsl:with-param name="RealLastRow" select="$RealLastRow" />
</xsl:call-template>
</xsl:if>
</tr>
</table>
</xsl:template>
<!-- Here ends the Command Header Template -->
<!-- Here starts the Paging Template -->
<xsl:template name="dvt_1.navigation">
<xsl:param name="FirstRow" />
<xsl:param name="LastRow" />
<xsl:param name="RowLimit" />
<xsl:param name="dvt_RowCount" />
<xsl:param name="RealLastRow" />
<xsl:variable name="PrevRow">
<xsl:choose>
<xsl:when test="$FirstRow - $RowLimit < 1">1</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$FirstRow - $RowLimit" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="LastRowValue">
<xsl:choose>
<xsl:when test="$LastRow > $RealLastRow">
<xsl:value-of select="$LastRow"></xsl:value-of>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$RealLastRow"></xsl:value-of>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="NextRow">
<xsl:value-of select="$LastRowValue + 1"></xsl:value-of>
</xsl:variable>
<td nowrap="" class="ms-paging" align="center">
<span style= "margin-right:5px">Count : <xsl:value-of select="count(/dsQueryResponse/Rows/Row)" /></span>
<xsl:if test="$dvt_firstrow > 1" ddwrt:cf_ignore="1">
<a>
<xsl:attribute name="href">javascript: <xsl:value-of select="ddwrt:GenFireServerEvent('dvt_firstrow={1};dvt_startposition={}')" />;</xsl:attribute>
Start</a>
<xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&nbsp;</xsl:text>
<a>
<xsl:attribute name="href">javascript: history.back();</xsl:attribute>
<img src="/_layouts/images/prev.gif" border="0" alt="Previous" />
</a>
<xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&nbsp;</xsl:text>
</xsl:if>
<xsl:value-of select="$FirstRow" />
- <xsl:value-of select="$LastRowValue" />
<xsl:text xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" ddwrt:nbsp-preserve="yes" disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:if test="$LastRowValue < $dvt_RowCount or string-length($dvt_nextpagedata)!=0" ddwrt:cf_ignore="1">
<a>
<xsl:attribute name="href">javascript: <xsl:value-of select="ddwrt:GenFireServerEvent(concat('dvt_firstrow={',$NextRow,'};dvt_startposition={',$dvt_nextpagedata,'}'))" />;</xsl:attribute>
<img src="/_layouts/images/next.gif" border="0" alt="Next" />
</a>
</xsl:if>
</td>
</xsl:template>
<!-- Here ends the Paging Template -->
</xsl:stylesheet>
Changing the look and feel:
- Edit Page
- Modify Shared Web Part
- XSL Editor
- Paste your new
Second layout:
The XSLT:
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:output method="html" indent="no"/>
<xsl:decimal-format NaN=""/>
<xsl:param name="dvt_apos">'</xsl:param>
<xsl:param name="dvt_firstrow">1</xsl:param>
<xsl:param name="dvt_nextpagedata" />
<xsl:variable name="dvt_1_automode">0</xsl:variable>
<!-- Here Starts the XSLT Render Process -->
<xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
<!-- Add the javascript to change the picture -->
<SCRIPT LANGUAGE="javascript">
function changePicture(picture)
{
document.getElementById("imgPhoto").src = picture;
document.getElementById("divPhoto").style.display = 'inline';
}
</SCRIPT>
<!-- Add the CSS for the Thumbnail row and the Picture Holder -->
<style type="text/css">
/* Class for the Photo Div */
.photoClass
{
border: 1px solid #000000;
background-color: #FFFFFF;
height: 480px;
padding: 10px;
display: none;
}
/* Position the Thumbnail row*/
#motioncontainer {
/*margin:0 auto; Uncomment this line if you wish to center the gallery on page */
height: auto; /* Set to gallery width, in px or percentage */;
width: 145px;
vertical-align: middle;
margin-bottom: 20px;
}
/* Add a small invisible box around the thumbnail */
#motioncontainer a img {
border: 1px solid white;
vertical-align: middle;
}
/* Add a small gray rectangle around the thumbnail on hover */
#motioncontainer a:hover img {
border: 1px dashed #000000; /* Set image border hover color */
}
</style> <table width="100%">
<tr>
<td align="center" width="150" valign="top">
<div id="motioncontainer" style="position:relative; margin-bottom:5px">
<div id="motiongallery" style="position:absolute;left:0;top:0;white-space: nowrap; vertical-align: middle; margin-bottom:20px;">
<nobr id="trueContainer">
<!-- Call the looping process -->
<xsl:call-template name="dvt_1"/>
</nobr>
</div>
</div>
</td>
<td align="center" valign="top" height="500">
<div id="divPhoto" class="photoClass">
<img id="imgPhoto" height="480"/>
</div>
</td>
</tr>
</table>
</xsl:template>
<!-- Here ends the XSLT Render Process -->
<!-- The XSLT Body -->
<xsl:template name="dvt_1">
<!-- Here Starts the XSLT Render Process -->
<xsl:variable name="dvt_StyleName">2ColFrm</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row" />
<xsl:variable name="dvt_RowCount" select="count($Rows)" />
<xsl:variable name="RowLimit" select="4" />
<xsl:variable name="FirstRow" select="$dvt_firstrow" />
<xsl:variable name="LastRow" select="$FirstRow + $dvt_RowCount - 1" />
<xsl:variable name="IsEmpty" select="$dvt_RowCount = 0 or $RowLimit = 0" />
<!-- Call the Header Template -->
<xsl:call-template name="dvt_1.commandheader">
<xsl:with-param name="FirstRow" select="$FirstRow" />
<xsl:with-param name="LastRow" select="$LastRow" />
<xsl:with-param name="RowLimit" select="$RowLimit" />
<xsl:with-param name="dvt_RowCount" select="$dvt_RowCount" />
<xsl:with-param name="RealLastRow" select="number(ddwrt:NameChanged('',-100))" />
</xsl:call-template>
<!-- Call the Body (the rows which are pictures here) Template -->
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows" />
<xsl:with-param name="FirstRow" select="1" />
<xsl:with-param name="LastRow" select="$LastRow - $FirstRow + 1" />
</xsl:call-template>
</xsl:template>
<!-- End of render process Template -->
<!-- Here starts the Body Template -->
<xsl:template name="dvt_1.body">
<xsl:param name="Rows" />
<xsl:param name="FirstRow" />
<xsl:param name="LastRow" />
<!-- Call the RowView Template for each Row (Picture) -->
<xsl:for-each select="$Rows">
<xsl:variable name="dvt_KeepItemsTogether" select="false()" />
<xsl:variable name="dvt_HideGroupDetail" select="false()" />
<xsl:if test="(position() >= $FirstRow and position() <= $LastRow) or $dvt_KeepItemsTogether">
<xsl:if test="not($dvt_HideGroupDetail)" ddwrt:cf_ignore="1">
<xsl:call-template name="dvt_1.rowview" />
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Here ends the Body Template -->
<!-- Here starts the RowView Template -->
<xsl:template name="dvt_1.rowview">
<!-- A Link is build per picture containing the thumbnail as link -->
<a href="{@FileRef}" onmouseover="changePicture('{@FileRef}');"><img height="110" border="0" src="{concat('/', substring-before(substring-after(@FileRef, '/'),'/'), '/_t/', substring-after(substring-after(concat(translate(@FileRef,'.','_'),'.jpg'), '/'), '/'))}"></img></a>
<br />
<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
<span ddwrt:amkeyfield="" ddwrt:amkeyvalue="''" ddwrt:ammode="view" />
</xsl:if>
</xsl:template>
<!-- Here ends the RowView Template -->
<!-- Here starts the Command Header Template -->
<xsl:template name="dvt_1.commandheader">
<xsl:param name="FirstRow" />
<xsl:param name="LastRow" />
<xsl:param name="RowLimit" />
<xsl:param name="dvt_RowCount" />
<xsl:param name="RealLastRow" />
<table cellspacing="0" cellpadding="4" border="0" width="100%">
<tr>
<!-- If there is paging needed add it -->
<xsl:if test="$FirstRow > 1 or $dvt_nextpagedata">
<xsl:call-template name="dvt_1.navigation">
<xsl:with-param name="FirstRow" select="$FirstRow" />
<xsl:with-param name="LastRow" select="$LastRow" />
<xsl:with-param name="RowLimit" select="$RowLimit" />
<xsl:with-param name="dvt_RowCount" select="$dvt_RowCount" />
<xsl:with-param name="RealLastRow" select="$RealLastRow" />
</xsl:call-template>
</xsl:if>
</tr>
</table>
</xsl:template>
<!-- Here ends the Command Header Template -->
<!-- Here starts the Paging Template -->
<xsl:template name="dvt_1.navigation">
<xsl:param name="FirstRow" />
<xsl:param name="LastRow" />
<xsl:param name="RowLimit" />
<xsl:param name="dvt_RowCount" />
<xsl:param name="RealLastRow" />
<xsl:variable name="PrevRow">
<xsl:choose>
<xsl:when test="$FirstRow - $RowLimit < 1">1</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$FirstRow - $RowLimit" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="LastRowValue">
<xsl:choose>
<xsl:when test="$LastRow > $RealLastRow">
<xsl:value-of select="$LastRow"></xsl:value-of>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$RealLastRow"></xsl:value-of>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="NextRow">
<xsl:value-of select="$LastRowValue + 1"></xsl:value-of>
</xsl:variable>
<td nowrap="" class="ms-paging" align="center">
<span style= "margin-right:5px">Count : <xsl:value-of select="count(/dsQueryResponse/Rows/Row)" /></span>
<xsl:if test="$dvt_firstrow > 1" ddwrt:cf_ignore="1">
<a>
<xsl:attribute name="href">javascript: <xsl:value-of select="ddwrt:GenFireServerEvent('dvt_firstrow={1};dvt_startposition={}')" />;</xsl:attribute>
Start</a>
<xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&nbsp;</xsl:text>
<a>
<xsl:attribute name="href">javascript: history.back();</xsl:attribute>
<img src="/_layouts/images/prev.gif" border="0" alt="Previous" />
</a>
<xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&nbsp;</xsl:text>
</xsl:if>
<xsl:value-of select="$FirstRow" />
- <xsl:value-of select="$LastRowValue" />
<xsl:text xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" ddwrt:nbsp-preserve="yes" disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:if test="$LastRowValue < $dvt_RowCount or string-length($dvt_nextpagedata)!=0" ddwrt:cf_ignore="1">
<a>
<xsl:attribute name="href">javascript: <xsl:value-of select="ddwrt:GenFireServerEvent(concat('dvt_firstrow={',$NextRow,'};dvt_startposition={',$dvt_nextpagedata,'}'))" />;</xsl:attribute>
<img src="/_layouts/images/next.gif" border="0" alt="Next" />
</a>
</xsl:if>
</td>
</xsl:template>
<!-- Here ends the Paging Template --></xsl:stylesheet>
I hope you see how fast (if you are good at CSS / Javascript) you can write nice pages.
Btw: this is security trimmed J