Dear Microsoft: Please Listen to Us About the New Document Library “Experience”

One of the latest hubbubs in the Office 365 world is around the new Document Library “experience”. (I refuse to use the word “experience” in this sort of context without a little sarcasm and some air quotes.)

There’s a new “experience” coming to Office 365 that makes Document Libraries look a lot like the OneDrive browser UI that some of you must use. (I prefer to use a synced folder on my devices to interact with OneDrive – when syncing actually works.)

In case you haven’t see the new “experience” yet, here’s how it goes. Here’s a very simple Document Library in our Sympraxis tenant.

2016-06-16_10-12-36

When you go to a Document Library for the first time after the functionality hits your tenant, you can choose to walk through a Motherhood and apple pie set of intro screens that show why the new experience is swell.

New Document Library "Experience" Prompt

2016-06-16_10-08-59

2016-06-16_10-09-15

2016-06-16_10-09-30

2016-06-16_10-09-43

And after clicking on “Let’s get started”, you see the new “experience”…

2016-06-16_10-11-58

 

Note the small link at the bottom left that lets you switch back to the “classic” view – for now.

The issue isn’t so much the new “experience”. I do think since people hate change, it’ll cause a lot of discomfort in many organizations, especially since it’s roaring into all tenants. In fact, the new capabilities are indeed swell. The issues are around existing customizations to the branding of functionality of Document Library views.

If you’d like to see what’s got people upset about it, you can check out the UserVoice item Allow Javascript customization and CSS branding/theming in the new Document Library Experience. There’s also a very long thread at the Office 365 Network in Yammer about it.

I do think the “Working on it” message in the UserVoice entry should give some hope. Microsoft knows there are issues. If they can’t address them and others like them, the flow to Office 365 will reverse back to on premises. What I think sows a lot of Fear, Uncertainty, and Doubt about this is it feels – yet again – like it could be a slippery slope.

Document Library default views are often built into what amounts to applications, or at least launch pads into application. It can be anything from simply adding some explanatory text in a CEWP at the top of the page (which is, after all, a Web Part Page) to full fledged functionality provided by additions of JavaScript using jsLink, DVWPs, JavaScript, CSS, etc. In many cases, the view page ends up looking little like what it started out as.

There simply has to be a way to keep these view pages in the mix, as considerable investment of time and money have gone into them. One would hope “telemetry” will show many people *choosing* to stick with “classic” (in this case meaning “functional” and “useful”) mode pages, even if all the “Working on it” stuff happens.

What I’m asking for in this post (Are these Dear Microsoft posts of mine merely rhetorical? I hope not.) is for a sincere attempt to hear what the concerns are. There are many times where people are feeling like a change to something new risks removing some of the exact reasons why the SharePoint platform has been successful in the past. Running Office 365 as a service can indeed be at odds to the successful methods used in Document Libraries, but understanding how to continue the exact patterns of enhancement that were encouraged in the past – by Microsoft- is critical.  Change can be good, but not if it undoes past investment and successful implementation.

I like the image that Brent Ellis (@Brentless) posted in the Yammer thread:

Do No Harm

Software development isn’t medicine, but still…

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) &gt; 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() &lt;= $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}&amp;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="&lt;View&gt;&lt;Lists ServerTemplate='101'&gt;&lt;/Lists&gt;<Query><Where><Eq><FieldRef Name='FSObjType' /><Value Type='int'>0</Value></Eq></Where><OrderBy><ListProperty Name='Title'/></OrderBy></Query>&lt;ViewFields&gt;&lt;ListProperty Name=&quot;Title&quot; /&gt;<FieldRef Name='FSObjType' />&lt;FieldRef Name=&quot;ID&quot;/&gt;&lt;FieldRef Name=&quot;Title&quot;/&gt;&lt;FieldRef Name=&quot;FileRef&quot;/&gt;&lt;FieldRef Name=&quot;FileDirRef&quot;/&gt;&lt;FieldRef Name=&quot;FileLeafRef&quot;/&gt;&lt;FieldRef Name=&quot;Editor&quot;/&gt;&lt;FieldRef Name=&quot;Modified&quot;/&gt;&lt;/ViewFields&gt;&lt;/ViewFields&gt;&lt;/View&gt;" UpdateCommand="" InsertCommand="" DeleteCommand="" UseInternalName="True" UseServerDataFormat="True" ID="dataformwebpart1">
  </SharePoint:SPDataSource>
</DataSources>
</WebPartPages:DataFormWebPart>