PnP JavaScript Library With KnockoutJS In SharePoint

From my previous posts, we can learn how to integrate PnP JavaScript library in Angular JS 1.0 and React JS frameworks, from the following links.

In this article, I am taking the same example but a different JS framework to build the UI interfaces.

In the modern SharePoint experience, the SharePoint team uses Knockout JS as one of the frameworks to update the UI interfaces.

Knockout JS supports MVVM pattern (Model – View – ViewModel) to build the web UI interface and it follows a different model in updating DOM as compared to the other JS frameworks. You can learn more about Knockout JS from their site. They are providing nice examples and tutorials to learn it step by step (I also have learned from those tutorials).

PnP-JS-Core library contains the number of extensible methods and properties. By using that, we can achieve the various actions in a simple code. To know more about this library component, visit the below links,

After reading the above links, you will have the basic idea about PnP-JS-Core library and how to use it in accessing the SharePoint.

Now, we will get back on the integration part. Before starting it, we have to identify some required files for this example.

What essential files are required?

  • knockoutjs,js A latest Knockout java script library for building user interfaces
  • Pnp.js PnP JavaScript library
  • Fetch.js Used by PnP js file to handle the web requests and responses (Required for IE)
  • Promise.js Used by PnP js file to handle the web requests and responses (Required for IE)
    Note: Fetch JS & Promise JS files are required to run PnP methods in some browsers (IE).

In our example, we have to create a sample.html file under Style Library or Site Assets. Here, I am creating the file under Site Assets Library.

Include Script Files

I have uploaded the required script files under the Site Assets library and added the below lines to our sample html file.

  1. <script type="text/javascript" src="/siteassets/scripts/pnp.min.js"></script>   
  2. <script type="text/javascript" src="/siteassets/scripts/fetch.js"></script>   
  3. <script type="text/javascript" src="/siteassets/scripts/promise.min.js"></script>   
  4. <script type="text/javascript" src="/siteassets/scripts/knockout-3.4.0.js"></script>  
Note: I have downloaded the latest knockout js file and referenced it in the script.

Include HTML

Add the below css styles and html snippet to the sample html file.
  1. <!-- To style table in html -->  
  2. <style type="text/css">    
  3. .web-table th{  background-color:#ddd;  border:2px solid #fff;}    
  4. .web-table td{  background-color:#eee;  border:2px solid #fff;}    
  5. .web-heading{   padding:2px;}    
  6. </style>    
  7. <div>    
  8.     <h2 class="web-heading">Sub Sites</h2>   
  9. <div>  
  10.     <table width="100%" cellpadding="10" cellspacing="2" class="web-table">    
  11.         <thead>    
  12.             <tr>    
  13.                 <th>Title</th>    
  14.                 <th>Id</th>    
  15.                 <th>Created</th>    
  16.                 <th>Web Template</th>    
  17.             </tr>    
  18.         </thead>    
  19.         <tbody data-bind="foreach: webSites">    
  20.             <tr >    
  21.                 <td data-bind="text: Title"></td>    
  22.                 <td data-bind="text: Id"></td>    
  23.                 <td data-bind="text: Created"></td>    
  24.                 <td data-bind="text: WebTemplate"></td>    
  25.             </tr>    
  26.         </tbody>    
  27.     </table>  
  28.     <p data-bind="visible: webSites().length <= 0">No websites</p>  
  29. </div>  
  30. </div>  
  32. <script type="text/javascript">  
  33. <!- - Insert Knockout JS Code - - >  
  34. </script>   
  • Data-bound attributes are how Knockout lets you declaratively associate viewmodel properties with DOM elements. You just use the text binding to assign the text to your DOM elements.
  • Websites represent observable object – this is a property that, automatically, will issue notifications whenever their value changes.
  • If sub sites are not available, “No websites” content is visible to the user by using visible binding and by comparing the length property of a observable property.

Include Knockout JS Code

  1. // This is a simple viewmodel - JavaScript that defines the data and behavior of your UI  
  2. function websViewModel() {  
  3.     var self = this;  
  5.     self.webSites = ko.observableArray();  
  7.     //Include PnP JS Code to set the subsite collection to self.webSites variable  
  8. }  
  10. // Activates knockout.js  
  11. ko.applyBindings(new websViewModel());  
The ko.applyBindings method activates the knockout code on websViewModel. And, the properties and methods are executed to store the variables in a viewModel property.

Include PnP JS Code

Replace the included PnP JS Code comment from the html snippet, with the below PnP code.
  1. $pnp.sp.web.webs.get().then(function(result) {  
  2.         self.webSites(result);  //knockout JS Code used to set the result object to webSites  
  3.     });  
PnP executes the code and sets the returned value to the website's observable property. We can use this observable property in html to update the content in the UI.

Full Sample Code

Insert the below code in Script Editor or Content Editor web-part.
  1. <style type="text/css">    
  2. .web-table th{  background-color:#ddd;  border:2px solid #fff;}    
  3. .web-table td{  background-color:#eee;  border:2px solid #fff;}    
  4. .web-heading{   padding:2px;}    
  5. </style>    
  6. <script type="text/javascript" src="/siteassets/scripts/fetch.js"></script>   
  7. <script type="text/javascript" src="/siteassets/scripts/promise.min.js"></script>   
  8. <script type="text/javascript" src="/siteassets/scripts/pnp.min.js"></script>    
  9. <script type="text/javascript" src="/siteassets/scripts/knockout-3.4.0.js"></script>  
  11. <div>    
  12.     <h2 class="web-heading">Sub Sites</h2>   
  13. <div>  
  14.     <table width="100%" cellpadding="10" cellspacing="2" class="web-table">    
  15.         <thead>    
  16.             <tr>    
  17.                 <th>Title</th>    
  18.                 <th>Id</th>    
  19.                 <th>Created</th>    
  20.                 <th>Web Template</th>    
  21.             </tr>    
  22.         </thead>    
  23.         <tbody data-bind="foreach: webSites">    
  24.             <tr >    
  25.                 <td data-bind="text: Title"></td>    
  26.                 <td data-bind="text: Id"></td>    
  27.                 <td data-bind="text: Created"></td>    
  28.                 <td data-bind="text: WebTemplate"></td>    
  29.             </tr>    
  30.         </tbody>    
  31.     </table>  
  32.     <p data-bind="visible: webSites().length <= 0">No websites</p>  
  33. </div>  
  34. </div>  
  36. <script type="text/javascript">  
  37. // This is a simple viewmodel (websViewModel) - JavaScript that defines the data and behavior of your UI  
  38. function websViewModel() {  
  39.     var self = this;  
  41.     self.webSites = ko.observableArray();  
  42.     $pnp.sp.web.webs.get().then(function(result) {  
  43.         //knockout JS Code used to set the result object to webSites  
  44.         self.webSites(result);  
  45.     });  
  46. }  
  47. // Activates knockout.js  
  48. ko.applyBindings(new websViewModel());  
  49. </script>  



This article provides a simple example to list the sub sites in a table format using Knockout JS framework. Click here to read the same article from my blog.