Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / CSS

Using Knockout.js for SharePoint Web Part Templating: Part 2

4.62/5 (5 votes)
29 Dec 2013CPOL7 min read 20.4K   244  
Part 2 of the series Using knockout for web part templating

Introduction

This is part 2 of this mini series. In Part 1 I was explaining knockout and gave example of little proof of concept web page (js, html, css only). Now we're going to SharePoint part

Using the code

SharePoint Part

As I said I will assume that you have some experience with SharePoint development so I will not explain how to create the project and add project items. Project type is standard Visual Studio 2010 SharePoint Empty Project template.

SharePoint part consists of following items:

  • Web part item – KnockoutWp. Standard SharePoint Visual Web part project Item
  • Assets module. SharePoint module project item. We are going to use it for deploying of images and css files (0.png – empty container for images and controls.css – css file for our projects).
  • Layouts mapped folder. We’ll put here editor page for template.

And here is the solution explorer for project:

Image 1

Assets

We are going to deploy 2 files:

  • 0.png – 1x1 pixel transparent image aka placeholder
  • Controls.css – css file for our template

Both of these items are going to be deployed to Style Library of the SharePoint site collection, so content editors may change it later without need of solution redeployment.

Here is the elements.xml file:

So our assets will end to http://oursitecollectionurl/Style Library/wp folder.

KnockoutWp

This is Visual Studio 2010 Visual Web part.

It is consisted of 4 items:

  • KnockoutWp.cs – web part class
  • KnockoutWpUserControl – User control of our web part
  • KnockoutWp.webpart – web part xml file
  • Elements.xml – manifest file

KnockoutWP.cs

This is the class of the web part itself. It is auto generated by Visual Studio and inherits System.Web.UI.WebControls.WebParts.WebPart . Here we define properties and methods of our web part. One property is auto generated (others would be added later): _ascxpath, string that locates UserControl that would be used for presentation of this web part. CreateChildControls method is also here and it’s pretty basic. We're going to change it later.
Properties

Web part has following properties:

  • ListUrl (string, required) – url of the list we are displaying.
  • TitleField (string, optional) – display name of the field that would be displayed as Title. If it’s blank Title field would be used.
  • DateField (string, optional) – display name of the field that would be displayed as date. If it’s blank Created field would be used.
  • DescriptionField (string, optional) – display name of the field that would be displayed as Description. If it’s blank it would be omitted.
  • ImageField (string, optional) - display name of the field that would be displayed as Thumbnail picture. If it’s blank it would be omitted.
  • NoOfItems (int) – how many items from the list would be displayed
  • ItemTemplate (string) – html template of the web part. Defines the look of our web part.
  • WpPosition (enum) – Used for a three column layouts. Web part has styles for three zones: right, central and left. Difference is in width, padding and margin. Everything is set in css so you can accommodate it to your environment.
On picture below you can see mapping between Field properties of web part and list item fields.

 Image 2

EditorPart 

I've added one more thing to this web part it’s EditorPart class GenericListPartEditorPart. I’m not going into deep with editor parts, but here is quick info. When you create public property for a web part it is automatically displayed in web part edit panel. And it is great concept when you need simple properties as strings, numbers and short lists. If you want more complicated scenario (as we want here for our web part) it’s not enough. What I wanted here is template editor. It could be reasonably large so idea was to have a button in web part edit panel that would open large dialog window with editor. User would work with our template, click Apply and change ItemTemplate web part property.

Image 3

Image 4

These two pictures above explain concept. Next step would be implementing code highlighting framework as CodeMirror.

Adding EditorPart is easy. First you create class that inherits EditorPart. In CreateChildControls override you create controls for custom editor. In ApplyChanges and SyncChanges overrides you sync editorpart with web part. When the editor part is finished, our main web part class had to implement IWebEditable interface and to map EditorPart object with web part itself. Check picture below.

More on this subject http://msdn.microsoft.com/en-us/library/hh228018(v=office.14).aspx.

Template editor KnockoutWpUserControl

This is user control created by Visual Studio, when we added Visual web part project item to the project. It consists of markup ascx file and code behind .ascx.cs file. We will put our markup and our c# code here.

Markup

Here is the complete markup:

ASP.NET
<script type='text/javascript' src="http://knockoutjs.com/downloads/knockout-3.0.0.js">
</script>
<style type="text/css">  @import url("/Style
Library/wp/controls.css");  </style>  
<div class="glwp glwp-<%=PositionClass %>" id="k<%=WpId %>">
  <div class="glwpLine"></div>      
  <h5><img src="<%=Icon %>" width="28" 
    height="28" align="absmiddle"><%=Title %></h5>
    <div class="glwpLineGrey"></div>      
  <asp:Literal ID="LitLayout" runat="server"></asp:Literal>
</div>  

<script type="text/javascript">    
  function OpenDialog(Url) {
    var options = SP.UI.$create_DialogOptions();        
    options.resizable = 1;        
    options.scroll = 1;        
    options.url = Url;
    SP.UI.ModalDialog.showModalDialog(options);    
}         
// Item class         
  var Item = function (id, title, datecreated,url,description,thumbnail) {            
     this.id = id;            
     this.title = title;
     this.datecreated = datecreated;
     this.url=url;
     this.description=description;
     this.thumbnail=thumbnail;
  }         
 //ViewModel goes here (It's created on server)        
 <asp:Literal runat="server" ID="LitItems"></asp:Literal>
 
//Function that opens Template editor. Used only in edit mode of web part       
 function portal_openTemplateEditor(wpid) {       
  var val="";              
  var options = SP.UI.$create_DialogOptions();              
  options.width = 600;             
  options.height = 500;                
  options.url = "/_layouts/KnockoutTemplate/TemplateEditor.aspx?c="+wpid;//"";
  options.dialogReturnValueCallback =
           Function.createDelegate(null,portal_openTemplateEditorClosedCallback);
  SP.UI.ModalDialog.showModalDialog(options);
}
</script>

First Section, of the markup (picture below) has script (knockout, on the remote server) and style references (controls.css in local Document library). Below is html markup that defines the container of the web part (top and bottom borders, width, icon and title). Markup is not the cleanest because I was little lazy and left some public properties in it. Note <%=PositionClass%>, <%=WpId%> and so on.

There are all public properties of the user control and they are used for presentation:

  • PositionClass – depending on WpPosition web part property (right, central or left) adds appropriate css class to markup and that way defines width, padding and margin of web part WpId is guid of the web part. It is used to uniquely identify the web part, because we can put several web parts of the same type and everything would crush without this identificator.
  • Icon – is a url to icon that would be displayed on web part. Web part property Title Icon Image URL is used here (this is OOB property)
  • Title –title text of the web part. Text that was entered in the title area of the web part. Web part property Title is used here (this is OOB property)
Last interesting thing here is Literal control LitLayout. This control would hold our ItemTemplate property (html template of our web part).

Second section, is a java script function that opens list item in a dialog window. It is used when underlying list is not document library.

Third section consists of knockout view model (java script). Item class definition is self-explanatory (defines 6 properties only). The rest of the model is created on the server side so now there is only LitItems Literal control there.

Fourth section is just a java script function that is used when editing web part properties. This function opens template editor in dialog window.

Code

Properties:

  • Properties from web part
    • Icon – url to the icon
    • Title – title of the web part
    • ListUrl – url to the list
    • TitleField – Title field in the list
    • DateField – Date field in the list
    • ImageField – Image field in the list
    • DescriptionField – Description field in the list
    • NoOfItems – number of items to return
    • Position – position of the web part (right, left or central)
    • ItemTemplate - html template of the web part
    • WpId – guid id of the web part ·
  • UC’s properties
    • PositionClass – css class based on position
    • ColumnMap – dictionary that holds internal names of the list item fields. 
Methods: File has only one method Page_Load. Code is executing with elevated privileges.

In that method we:

  1. Resolve list by the supplied URL (ListUrl property) SPList annList = annWeb.GetList(ListUrl);
  2. Get internal names of the list columns by their Display names SpHelper.GetFieldsInternals(annWeb, annList.Title, TitleField, DateField, DescriptionField, ImageField, columnMap );  
  3. Create CAML Query
    SpHelper.GetGenericQuery(annList,
    q, NoOfItems);
  4. Execute it
  5. Iterate over SPListItemCollection (coll) and create required JavaScript 
Helper class

SPHelper is helper class and you can find it in Helpers directory.

It has 3 responsibilities:

  1. To retrieve List Columns Internal names based on supplied List Columns display names (WP properties - TitleField – Title field, DateField, ImageField , DescriptionField ) - GetFieldsInternals method
  2. To create Caml query for retrieving list items – GetGenericQuery method  
  3. To retrieve values from SharePoint columns based on their types – GetFieldValue method

Download files 

Summary 

So, that's it. I tried to help you to create more flexible views. In Sharepoint 2013 you can use same techniques but you don't need to use web parts you may customize views. Although Knockout  is a great framework, for displaying purposes you should check Handlebars as well. Maybe mustaches suits you better :-). 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)