SharePoint Apps for Public Site: XsltListView Web Part approach

Jun 30
SharePoint Apps for Public Site: XsltListView Web Part approach

‚ÄčIn this post I'd like to share another approach how to get data in SharePoint hosted app for anonymous users. It uses a XsltListViewWebPart, as it gets data on server side, store it in a JS variable that is used in CSR. 

spsitepro_28_WP_data.png

Thus you can override CSR of a view or make it hidden and just use it as a datasource.

CSR approach

In general we have the following algorithm to make it working:
  • Create a list or a library
  • Create a custom View (or use All Items)
  • Customize rendering template as you need
  • Place XsltListViewWebPart on an App page, configure it to use appropriate View and rendering template

View CAML

I've created a simple list based on a Contact list template and added a new view called "Customized by CSR", it has a BaseViewID set to "3". Actually BaseViewID is a non unique integer that can be set to any number you like. Using this number, it's really easy to provision views to site pages (you will see an example below). But please take into account that some values may not work and throw error - just use another number to make it work. You can read more here.

Also I set JSLink to a script file with my CSR function to customize the page as required.

<View DisplayName="Customized by CSR"
BaseViewID="3"
Type="HTML"
MobileView="TRUE"
ImageUrl="/_layouts/15/images/generic.png?rev=23"
WebPartZoneID="Main"
WebPartOrder="1"
Url="customized_CSR.aspx"
SetupPath="pages\viewpage.aspx">
<XslLink Default="TRUE">main.xsl</XslLink>
<JSLink>~site/Scripts/CSR.js</JSLink>
<Query>
<OrderBy>
<FieldRef Name="ID"></FieldRef>
</OrderBy>
</Query>
<ViewFields>
<FieldRef Name="ID"/>
<FieldRef Name="LinkTitle"/>
<FieldRef Name="FirstName"/>
<FieldRef Name="Email"/>
<FieldRef Name="Company"/>
<FieldRef Name="JobTitle"/>
<FieldRef Name="WorkCity"/>
<FieldRef Name="WebPage"/>
</ViewFields>
<RowLimit Paged="TRUE">30</RowLimit>
</View>

Provision page with XsltListViewWebPart

First of all I need to insert a Web Part Zone into my default.aspx page, zone is called "Main".

<WebPartPages:WebPartZone runat="server" FrameType="None" ID="Main" Title="loc:Main" PartChromeType="None" ShowTitleIcons="True" AllowLayoutChange="False" />

I use module to provision view to a page as the easiest approach for SharePoint hosted apps, List property defines url of the list I want to work with, BaseViewID defines the view of the list, WebPartZoneID defines the place where to add view on the page (there can be multiple zones), WebPartOrder defines the order with the zone (starts from 0 - the toppest in the zone). Inside View we can specify any properties of XsltListViewWebPart. In my case I like to disable switching views and searching.

<Module Name="Pages">
<File Path="Pages\Default.aspx" Url="Pages/Default.aspx" ReplaceContent="TRUE">
<View List="Lists/Contacts" BaseViewID="3" WebPartZoneID="Main" WebPartOrder="1">
<![CDATA[
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart,Microsoft.SharePoint,Version=15.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" />
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<property name="DisableViewSelectorMenu" type="bool">True</property>
<property name="InplaceSearchEnabled" type="bool">False</property>
<property name="ShowToolbarWithRibbon" type="bool">False</property>
</properties>
</data>
</webPart>
</webParts>
]]>
</View>
</File>
</Module>

CSR code

The final thing is customization of CSR to display items the way we like. Please note this code is just an example :)

(function () {
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
        Templates: {
            Header: function (ctx) {
                return String.format("<ul class='contacts'>");
            },
            Footer: function (ctx) { return String.format("</ul>"); },
            Item: function (ctx) {
                var builder = new Sys.StringBuilder();
                builder.append("<li>");
                builder.append("<table>");
                builder.append(String.format("<tr><td>Name:</td><td>{0}{1}</td></tr>", ctx.RenderFieldByName(ctx, "FirstName"), ctx.RenderFieldByName(ctx, "Title")));
                builder.append(String.format("<tr><td>Company:</td><td>{0}</td></tr>", ctx.RenderFieldByName(ctx, "Company")));
                builder.append(String.format("<tr><td>Email:</td><td>{0}</td></tr>", ctx.RenderFieldByName(ctx, "Email")));
                builder.append(String.format("<tr><td>City:</td><td>{0}</td></tr>", ctx.RenderFieldByName(ctx, "WorkCity")));
                builder.append(String.format("<tr><td>Job Title:</td><td>{0}</td></tr>", ctx.RenderFieldByName(ctx, "JobTitle")));
                builder.append(String.format("<tr><td>Site:</td><td>{0}</td></tr>", ctx.RenderFieldByName(ctx, "WebPage")));
                builder.append("</table>");
                builder.append("</li>");
                return builder.toString();
            }
        }
    });
})();

The result

You can find live demo here.

spsitepro_28_result.png

You can download the App and its code on https://spsitepro.codeplex.com.
Web Part Error: Activation of solutions with sandboxed code has been disabled. Correlation ID: e0fe369e-d0ee-5000-b540-97da9cd0a79c.