Displaying the Most Recent Documents from All Document Libraries in a SharePoint Site
Data View Web Parts (DVWPs) are still my favorite tool in my SharePoint toolbox. Whenever I can use them to get the server to do the heavy lifting before the page is rendered, I do. jQuery and all of the fancy template libraries out there are grand, but in most cases it introduces a lag for the user between the time the page shows up in the browser and the time they can see all of the content.
In this case, I wanted to show the most recently modified documents in each of the Document Libraries in one site on that site’s home page. A DVWP using DataSourceMode=”CrossList” is a great way to do this. By using this method, any new Document Libraries will simply show up in the DVWP as soon as they are added. There’s no need to change any code at all.
I don’t usually like to just give the full code to something because I think it’s more beneficial to show the pieces so that you, gentle reader, must adapt things to your own environment and particular business needs. Given the neutered state of SharePoint Designer 2013, though, I think I’ll probably post full DVWPs where I can going forward. It’s simply too darn hard to edit DVWPs in SPD2013. Here I was working in SharePoint 2010, but the DVWP will work the same, whether you are in SharePoint 2007, 2010, or 2013.
This DVWP will display the Document Library name in a header row and then the three most recently modified documents, whether or not they are in folders. I’m display the name of the document as a link, the Modified By user as a link to their info or User Profile (depending on license version), and the Modified date/time columns. If you’d like to show other columns you can add them into the ViewFields in the DataSource section and then into the XSL. (In a CrossList DVWP, you must explicitly request each column you’d like to use.) To adjust the number of documents displayed per Document Library, just change the value of the TopN param near the top of the XSL section.
<WebPartPages:DataFormWebPart runat="server" Description="" ListDisplayName="" PartOrder="1" HelpLink="" AllowRemove="True" IsVisible="True" AllowHide="True" UseSQLDataSourcePaging="True" ExportControlledProperties="True" IsIncludedFilter="" DataSourceID="" Title="Most Recent Documents" ViewFlag="8" NoDefaultStyle="TRUE" AllowConnect="True" FrameState="Normal" PageSize="-1" PartImageLarge="" AsyncRefresh="False" ExportMode="All" Dir="Default" DetailLink="" ShowWithSampleData="False" FrameType="Default" PartImageSmall="" IsIncluded="True" SuppressWebPartChrome="False" AllowEdit="True" EnableOriginalValue="False" AutoRefresh="False" AutoRefreshInterval="60" AllowMinimize="True" ViewContentTypeId="" InitialAsyncDataFetch="False" MissingAssembly="Cannot import this Web Part." HelpMode="Modeless" ListUrl="" ID="g_2b53a84e_bf26_4583_af64_ac20e428b458" ConnectionID="00000000-0000-0000-0000-000000000000" AllowZoneChange="True" ManualRefresh="False" __MarkupType="vsattributemarkup" __WebPartId="{D2B80E07-81CE-48C5-83A1-D124096DC364}" __AllowXSLTEditing="true" WebPart="true" Height="" Width=""> <ParameterBindings> <ParameterBinding Name="URL" Location="ServerVariable(URL)" DefaultValue=""/> </ParameterBindings> <Xsl> <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:param name="URL"/> <xsl:param name="TopN">3</xsl:param> <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"> <xsl:call-template name="dvt_1"/> </xsl:template> <xsl:template name="dvt_1"> <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/> <table border="0" width="100%" cellpadding="2" cellspacing="0"> <tr valign="top"> <th class="ms-vh" nowrap="nowrap">Name</th> <th class="ms-vh" nowrap="nowrap">Modified By</th> <th class="ms-vh" nowrap="nowrap">Modified</th> </tr> <xsl:call-template name="dvt_1.body"> <xsl:with-param name="Rows" select="$Rows"/> </xsl:call-template> </table> </xsl:template> <xsl:template name="dvt_1.body"> <xsl:param name="Rows"/> <xsl:for-each select="$Rows"> <xsl:variable name="NewList" select="ddwrt:NameChanged(string(@ListProperty.Title), 0)"/> <xsl:if test="string-length($NewList) > 0"> <tr> <td class="ms-vb" style="background-color:#cfcfcf;" colspan="99"> <a style="color:#990202;" href="/{substring-after(@FileDirRef, ';#')}"><xsl:value-of select="@ListProperty.Title" /></a> </td> </tr> <xsl:call-template name="dvt_1.body2"> <xsl:with-param name="Rows" select="$Rows[@ListProperty.Title = current()/@ListProperty.Title]"/> </xsl:call-template> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template name="dvt_1.body2"> <xsl:param name="Rows"/> <xsl:for-each select="$Rows"> <xsl:sort select="ddwrt:FormatDateTime(string(@Modified), 1033, 'yyyyMMdd HHmmss')" order="descending"/> <xsl:if test="position() <= $TopN"> <xsl:call-template name="dvt_1.rowview" /> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template name="dvt_1.rowview"> <tr> <xsl:if test="position() mod 2 = 1"> <xsl:attribute name="class">ms-alternating</xsl:attribute> </xsl:if> <td class="ms-vb"> <a href="/{substring-after(@FileDirRef, ';#')}/Forms/DispForm.aspx?ID={@ID}&Source={$URL}"><xsl:value-of select="substring-after(@FileLeafRef, ';#')" /></a> </td> <td class="ms-vb"> <a href="/_layouts/userdisp.aspx?ID={substring-before(@Editor, ';#')}"><xsl:value-of select="substring-after(@Editor, ';#')"/></a> </td> <td class="ms-vb"> <xsl:value-of select="ddwrt:FormatDate(string(@Modified), 1033, 5)"/> </td> </tr> </xsl:template> </xsl:stylesheet></Xsl> <DataSources> <SharePoint:SPDataSource runat="server" DataSourceMode="CrossList" SelectCommand="<View><Lists ServerTemplate='101'></Lists><Query><Where><Eq><FieldRef Name='FSObjType' /><Value Type='int'>0</Value></Eq></Where><OrderBy><ListProperty Name='Title'/></OrderBy></Query><ViewFields><ListProperty Name="Title" /><FieldRef Name='FSObjType' /><FieldRef Name="ID"/><FieldRef Name="Title"/><FieldRef Name="FileRef"/><FieldRef Name="FileDirRef"/><FieldRef Name="FileLeafRef"/><FieldRef Name="Editor"/><FieldRef Name="Modified"/></ViewFields></ViewFields></View>" UpdateCommand="" InsertCommand="" DeleteCommand="" UseInternalName="True" UseServerDataFormat="True" ID="dataformwebpart1"> </SharePoint:SPDataSource> </DataSources> </WebPartPages:DataFormWebPart>
This will be even easier with SharePoint 2013 thanks to the new Search. Search Results Web Part with a built in query or a Content Search Web Part. All this using Display Templates (HTML + JS + CSS)
Theoretically, that’s true. However, I think it would be difficult to display the most recent three items from each Document Library with a Content Search Web Part. I’m having a dickens of a time getting them to do what I want in many cases.
My desired result looks something like:
Doc Lib 1
Doc 1
Doc 2
Doc 3
Doc Lib 2
Doc 1
Doc 2
Doc 3
etc.
M.
Hi Marc. Great stuff as always. I copy-pasted the code into a Form Web Part source editor section and only received this:
3
——————————————
Name Modified By Modified
——————————————
There are no documents listed, although there are 3 documents in the only document library on this site.
Obviously I missed something. (:-S
Carl:
This is a DVWP, which must be added to the page using SharePoint Designer.
Don’t be embarrassed by having WSS 3.0: I still use it myself.
M.
BTW, WSS 3.0 (no laughing please)
I have the dataview working properly but not when I turn on paging. No matter what, it returns all the results but has the arrow to move to the next page.. which shows the same set of results. Any idea how to fix this?
I’ve also tried to enable filtering. As long as its not “crosslist”, filtering works. However, once I change it, it stops working on most fields except the date fields.
Any idea?
Negin:
Once you’ve manually customized the XSL, you pretty much have to stick to manual updates.
M.
Hi Marc,
I had implement your DVWP in my site, and it’s works great. thanks!
1. Is there anything I can change in order to enable the save or edit option when I click on an item on the “most recent” list?
2. I want to create a similar list in my site, but this time for the most poplar docs. If it’s possible, how can I do it?
zvika:
If you’d like to add edit capabilities to the DVWP, you’d need to write your own XSL or script to do it.
There’s no real measure of “popular” docs available to you in the lists that I’m aware of.
M.
I inserted a Data view using SPD and replaced the code for the webpart with your but it shows datasourceID missing or set to an empty string error meeage. Please help
Hard to say what’s going on without more details.
M.
Thanks for this webpart, i try to make it work with on all include subsites (recursively), do you have already do that ?
Hey Mark, was just curious as to how you can exclude a library from this process? I have some jQuery stuff stashed in a library on the site and want to exclude this library from the dvwp.
As usual though, nice solution! Works a treat
dsanchez78:
You could simply ad a xsl:if test to exclude that specific library. Or probably better, figure out how to alter the CAML to exclude that library based on it’s template type or something.
M.
Thanks for the reply M. Any suggestions on how to do the above CAML alteration? I’m pretty average to say the least at making these CAML modifications
dsanchez78:
It’s going to depend on the specifics of your setup, so I can’t give you the exact answer. I would suggest using CAMLDesigner to help yourself out.
M.
Hi Marc
Thank you for the code. I am getting an error when i use this code. can you please advice me how to fix this issue?
I am getting “The property Query contains Invalid value”
Raj:
The error is probably telling you what you need to know. Check your query.
M.