Using KnockoutJs in SharePoint 2013

In this article we will see how to use Knockout.js in SharePoint 2013. You do not need server-side coding nor Visual Studio nor the SharePoint designer to build this user interface (UI). Only knowledge of knockout.js is required. Before going into details, I am pasting the screenshot of how the UI will look once this sample is built.

Tiles with KnockoutJs

We will need to refer to 3 js libraries. I have uploaded them in the document library but as a best practice create a different JavaScript library for them, "jquery-2.0.3.min.js", "knockout-3.0.0rc.js" and "ko.sp-1.0.min.Ex.js".

"ko.sp-1.0.min.Ex.js" can be downloaded from kosp.codeplex.com and has binders for knockout with SharePoint. Some SharePoint data types such as images and hyperlinks need special processing to provide correct results that is handled by this library.

We will use a simple example of a product list. Build a SharePoint List, ProductList, with the following columns and add a few records in this list.

ProductList

Create a Site Page and insert a Script Editor Web Part from the Media and Content category onto the page.

ScriptEditor

Click on "Edit Snippet" and paste in the following code:

   <script src="http://win-4f44sec6iug:34480/sites/ts/Style Library/jquery-2.0.3.min.js"></script>

    <script src="http://win-4f44sec6iug:34480/sites/ts/Style Library/knockout-3.0.0rc.js"></script>

    <script src="http://win-4f44sec6iug:34480/sites/ts/Style Library/ko.sp-1.0.min.Ex.js"></script>

    <div style="background-color: lightblue; margin: 10px">

        &nbsp;&nbsp;<a href="#" data-bind="click: previous">&lt;</a> <span data-bind="text: $root.pageNumber()+1">

        </span><a href="#" data-bind="click: next">&gt;</a></div>

    <table align="center" width="100%">

        <div data-bind="template: { name: 'allProducts-template', foreach: currentPage }">

        </div>

        <script type="text/html" id="allProducts-template">

        <tr><td align = "center">

          <div  data-bind="text:ProductName" ></div></td></tr>

        <tr><td align = "center"><div><img data-bind="spSrc:ProductImage" /></div>

            </td></tr>

           <tr><td align = "center"><div  data-bind="text:ProductRate"></div></td></tr>

           <tr><td><hr /></td></tr>

        </script>

    </table>

    <script type="text/javascript">

             function ProductModal() {

            var self = this;

            self.pageNumber = ko.observable(0);

            self.nbPerPage = 2;

            self.Products = ko.observableArray([]);

            $.getJSON(_spPageContextInfo.webAbsoluteUrl + "/_vti_bin/listdata.svc/ProductList", function (data) {

                if (data.d.results) {

                    self.Products(ko.toJS(data.d.results));

                }

            });

            self.totalPages = ko.computed(function () {

                var div = Math.floor(self.Products().length / self.nbPerPage);

                div += self.Products().length % self.nbPerPage > 0 ? 1 : 0;

                return div - 1;

            });

            self.next = function () {

                if (self.pageNumber() < self.totalPages()) {

                    self.pageNumber(self.pageNumber() + 1);

                }

            }

            self.previous = function () {

                if (self.pageNumber() != 0) {

                    self.pageNumber(self.pageNumber() - 1);

                }

            }

            self.currentPage = ko.computed(function () {

                var startPageIndex = self.pageNumber();

                var endPageIndex = self.pageNumber() + self.nbPerPage;

                return self.Products().slice(startPageIndex, endPageIndex);

            });

        }

        ko.applyBindings(new ProductModal());

    </script>
 
Click on "Insert and Stop Editing". If all goes well then you will see the results as shown in the first screenshot.

The following are a few things to note:

  1. $.getJSON(_spPageContextInfo.webAbsoluteUrl + "/_vti_bin/listdata.svc/ProductList"
    is the main data returning element. Change to your list name and you can add filters at the JSON request to get specific records.
     
  2. Pagination is controlled in the following:
     

    self.currentPage = ko.computed(function () {

    var startPageIndex = self.pageNumber();

    var endPageIndex = self.pageNumber() + self.nbPerPage;

    return self.Products().slice(startPageIndex ,endPageIndex );
     

  3. For image data binding use spSrc (the kosp library handles this)

This program can be extended for many other visual effects and for checking boundary conditions. This is one of the powerful ways to write a UI without requiring server-side coding and without Visual Studio and SharePoint Designer.


Similar Articles