CRUD In SharePoint Using REST And Knockout

SharePoint expanded a lot in REST API from the 2013 version onwards. Nowadays modern frameworks like Angular and Knockout are very useful and powerful in web development.

With this, I have come up with a blog which will showcase basic Create, Read, Update and Delete operations in SharePoint lists. I have used Knockout js as a binding agent. Also Knockout validation is used to validate data before submitting. You can customize the files as per the needs of a business.

I personally like to start with UI part so below is the HTML required for our application.

HTML

SharePoint

The above code shows standard input fields in HTML for first name and last name.

Below that will be a tabular format to display data from SharePoint lists.

JavaScript

I am using SharePoint REST API to get list data and perform other operations.

  1. //load view model after documnet gets loaded  
  2. $(document).ready(function() {  
  3.     mainFunction();  
  4. });  
  5. var modelInstance = null;  
  6. //Function to activate Knockout  
  7. function mainFunction() {  
  8.     modelInstance = new crudViewModel();  
  9.     modelInstance.errors = ko.validation.group(modelInstance); //for validation of fields  
  10.     ko.applyBindings(modelInstance);  
  11.     modelInstance.getEmpDetails();  
  12. }  
  13. //define view Model  
  14. var crudViewModel = function() {  
  15.     var self = this;  
  16.     var listName = "EmpDetails";  
  17.     self.Id = ko.observable();  
  18.     self.firstName = ko.observable().extend({  
  19.         required: "Please enter First name"  
  20.     });  
  21.     self.lastName = ko.observable().extend({  
  22.         required: "Please enter Last name"  
  23.     });  
  24.     self.Employees = ko.observableArray();  
  25.     self.displayStatus = ko.observable();  
  26.     //Function to Read all Employees details  
  27.     self.getEmpDetails = function() {  
  28.         $.ajax({  
  29.             url: _spPageContextInfo.siteAbsoluteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items",  
  30.             type: "GET",  
  31.             headers: {  
  32.                 "Accept""application/json;odata=verbose"  
  33.             },  
  34.             success: function(data) {  
  35.                 self.Employees(data.d.results); //add employee details to observable  
  36.             },  
  37.             error: function(data) {  
  38.                 self.displayStatus("Error in processing request " + data.status);  
  39.             }  
  40.         });  
  41.     };  
  42.     //function to validate data such as blank values are not alllowed in input fields  
  43.     self.validateAndSave = function() {  
  44.         if (modelInstance.errors().length === 0) {  
  45.             self.addEmployee();  
  46.         } else {  
  47.             alert("please check your details");  
  48.             modelInstance.errors.showAllMessages();  
  49.             self.displayStatus("Please fill all required details");  
  50.         }  
  51.     };  
  52.     //Function to add new employee details in list  
  53.     self.addEmployee = function() {  
  54.         var itemType = "SP.Data.EmpDetailsListItem";  
  55.         var emp = {  
  56.             "__metadata": {  
  57.                 "type": itemType  
  58.             },  
  59.             "firstName": self.firstName,  
  60.             "lastName": self.lastName  
  61.         };  
  62.         $.ajax({  
  63.             url: _spPageContextInfo.siteAbsoluteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items",  
  64.             type: "POST",  
  65.             contentType: "application/json;odata=verbose",  
  66.             data: ko.toJSON(emp),  
  67.             headers: {  
  68.                 "Accept""application/json;odata=verbose",  
  69.                 "X-RequestDigest": $("#__REQUESTDIGEST").val()  
  70.             },  
  71.             success: function(data) {  
  72.                 alert("New Employee Created Successfully");  
  73.                 self.getEmpDetails(); //call to display again  
  74.             },  
  75.             error: function(data) {  
  76.                 self.displayStatus("Error in processing request " + data.status);  
  77.             }  
  78.         });  
  79.         self.clear();  
  80.     };  
  81.     //Function to get Specific Employee details using its ID  
  82.     function getEmpById(callback) {  
  83.         var url = _spPageContextInfo.siteAbsoluteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items(" + self.Id() + ")";  
  84.         $.ajax({  
  85.             url: url,  
  86.             type: "GET",  
  87.             headers: {  
  88.                 "Accept""application/json;odata=verbose"  
  89.             },  
  90.             success: function(data) {  
  91.                 callback(data);  
  92.             },  
  93.             error: function(data) {  
  94.                 self.displayStatus("Error in processing request");  
  95.             }  
  96.         });  
  97.     };  
  98.     //Function to Update Category  
  99.     self.updateEmpDetails = function() {  
  100.         getEmpById(function(data) {  
  101.             var itemType = "SP.Data.EmpDetailsListItem";  
  102.             var emp = {  
  103.                 "__metadata": {  
  104.                     "type": itemType  
  105.                 },  
  106.                 "firstName": self.firstName,  
  107.                 "lastName": self.lastName  
  108.             };  
  109.             $.ajax({  
  110.                 url: data.d.__metadata.uri,  
  111.                 type: "POST",  
  112.                 contentType: "application/json;odata=verbose",  
  113.                 data: ko.toJSON(emp),  
  114.                 headers: {  
  115.                     "Accept""application/json;odata=verbose",  
  116.                     "X-RequestDigest": $("#__REQUESTDIGEST").val(),  
  117.                     "X-HTTP-Method""MERGE",  
  118.                     "If-Match": data.d.__metadata.etag  
  119.                 },  
  120.                 success: function(data) {  
  121.                     alert("Employee details updated successfully");  
  122.                     self.getEmpDetails(); //call to display again  
  123.                     self.clear();  
  124.                 },  
  125.                 error: function(data) {  
  126.                     self.displayStatus("Error in processing request " + data.status + " " + data.statusCode);  
  127.                 }  
  128.             });  
  129.         });  
  130.     };  
  131.     //Function to Delete Employee details  
  132.     self.deleteEmpDetails = function(emp) {  
  133.         getEmpById(function(data) {  
  134.             var itemType = "SP.Data.EmpDetailsListItem";  
  135.             var emp = {  
  136.                 "__metadata": {  
  137.                     "type": itemType  
  138.                 },  
  139.                 "firstName": self.firstName,  
  140.                 "lastName": self.lastName  
  141.             };  
  142.             $.ajax({  
  143.                 url: data.d.__metadata.uri,  
  144.                 type: "POST",  
  145.                 contentType: "application/json;odata=verbose",  
  146.                 data: ko.toJSON(emp),  
  147.                 headers: {  
  148.                     "Accept""application/json;odata=verbose",  
  149.                     "X-RequestDigest": $("#__REQUESTDIGEST").val(),  
  150.                     "X-HTTP-Method""DELETE",  
  151.                     "If-Match": data.d.__metadata.etag  
  152.                 },  
  153.                 success: function(data) {  
  154.                     alert("Employee details deleted successfully");  
  155.                     self.getEmpDetails(); //call to display again  
  156.                     self.clear();  
  157.                 },  
  158.                 error: function(data) {  
  159.                     self.displayStatus("Error in processing request " + data.status + " " + data.statusCode);  
  160.                 }  
  161.             });  
  162.         });  
  163.     };  
  164.     //Function to Select Employee used for Update and Delete  
  165.     self.selectEmployee = function(emp) {  
  166.         self.Id(emp.Id);  
  167.         self.firstName(emp.firstName);  
  168.         self.lastName(emp.lastName);  
  169.     };  
  170.     //Function to clear all fields  
  171.     self.clear = function() {  
  172.         self.displayStatus("");  
  173.         self.Id(0);  
  174.         self.firstName("");  
  175.         self.lastName("");  
  176.     };  
  177. }; //End of view model  

Finally add content editor web part on any page and refer to the html file from SharePoint.

End result will be as follows,

SharePoint  

Add First Name and last name. Click on Create. Alert will be displayed that “New employee created.”

To update and delete, first click on the table row. It will select an employee and then click on update/delete which will perform an action in the list and will be displayed in UI as well.

Code files are attached for reference.