SharePoint 2013 List CRUD operation using Angular and REST API
This article explains how to perform the CRUD operation on a SharePoint List using Angular JavaScript and the REST API.
Create an empty SharePoint 2013 solution, In that add the module of Pages, JS & CSS.
In pages module add new item, Test.aspx.
In JS module, add new Javascript file with name Controller.js , CommonServices.js & SharePointListModule.js
Other Javascripts needs to add:
1. angular.min.js
2. anugular.min.js.map
Project structure will look something like below:
For doing a CRUD operation with SharePoint List, will create an Angular Service to make a SharePoint REST API calls,
This testService having dependency of $http & $q
Information related to $http & $q https://docs.angularjs.org/api/ng/service/$http , https://docs.angularjs.org/api/ng/service/$q
Following code showing how to get, add, delete & update tasks from specified SharePoint list,
Now, its time to consume all these services by creating an angular controller.
Full code to consume the above service methods is below, paste it in Controller.js
Now, its time to bind the view. add the below piece of code in test.aspx
If you noticed in parent div i have added : <div class="page" ng-app="SharePointAngApp">
and in child div added ng-controller
Once we add the controller, we can access all the scope variables in child elements.
Output will looks like below:
Create an empty SharePoint 2013 solution, In that add the module of Pages, JS & CSS.
In pages module add new item, Test.aspx.
In JS module, add new Javascript file with name Controller.js , CommonServices.js & SharePointListModule.js
Other Javascripts needs to add:
1. angular.min.js
2. anugular.min.js.map
Project structure will look something like below:
In SharePointListModule.js will create a App of angular, Paste the below code.
//App creation
var app = angular.module("SharePointAngApp", [])
For doing a CRUD operation with SharePoint List, will create an Angular Service to make a SharePoint REST API calls,
app.service('testService', ['$http', '$q', function ($http, $q) {//common services}]);
This testService having dependency of $http & $q
Information related to $http & $q https://docs.angularjs.org/api/ng/service/$http , https://docs.angularjs.org/api/ng/service/$q
Following code showing how to get, add, delete & update tasks from specified SharePoint list,
//Common service for SharePoint CRUD operations
app.service('testService', ['$http', '$q', function ($http, $q) {
var formDigest = $('#__REQUESTDIGEST').val();
//Define the http headers
$http.defaults.headers.common.Accept = "application/json;odata=verbose";
$http.defaults.headers.post['Content-Type'] = 'application/json;odata=verbose';
$http.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest';
$http.defaults.headers.post['If-Match'] = "*";
$http.defaults.headers.post['X-RequestDigest'] = formDigest;
//Get the tasks
this.getTasks = function (listTitle) {
var dfd = $q.defer();
$http.defaults.headers.post['X-HTTP-Method'] = ""
var query = "?$select=Title,Status,Priority,ID,Body";
var restUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items" + query;
$http.get(restUrl).success(function (data) {
dfd.resolve(data.d.results);
}).error(function (data) {
dfd.reject("error getting tasks");
});
return dfd.promise;
}
//Create a task , for now static text, we can pass input fields to add apropriate value
this.addTask = function (listTitle) {
var dfd = $q.defer();
$http.defaults.headers.post['X-HTTP-Method'] = "";
var restUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items";
$http.post(restUrl, {
__metadata: {
type: "SP.List"
},
Title: "New Tasks"
}).success(function (data) {
//resolve the new data
dfd.resolve(data.d);
}).error(function (data) {
dfd.reject("failed to add task");
});
return dfd.promise;
}
//Update a task
this.updateTask = function (listTitle, task) {
var dfd = $q.defer();
$http.defaults.headers.post['X-HTTP-Method'] = "MERGE";
var restUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items(" + task.ID + ")";
$http.post(restUrl, {
__metadata: {
type: "SP.List"
},
Title: task.Title
}).success(function (data) {
//resolve something
dfd.resolve(true);
}).error(function (data) {
dfd.reject("error updating task");
});
return dfd.promise;
}
//Delete a task
this.deleteTask = function (listTitle, task) {
var dfd = $q.defer();
$http.defaults.headers.post['X-HTTP-Method'] = "DELETE";
var restUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items(" + task.ID + ")";
$http.post(restUrl)
.success(function (data) {
//resolve something
dfd.resolve(true);
}).error(function (data) {
dfd.reject("error deleting task");
});
return dfd.promise;
}
}]);
Now, its time to consume all these services by creating an angular controller.
app.controller('spTasksController', function ($scope, $http, testService) {
//functions to consume the service methods});
Full code to consume the above service methods is below, paste it in Controller.js
//Controller to featch data from Tasks list
app.controller('spTasksController', function ($scope, $http, testService) {
$scope.editing = false;
//example populating tasks
testService.getTasks("Workflow Tasks").then(function (result) {
$scope.tasks = result;
});
//example to add task
$scope.addTask = function (listName) {
testService.addTask(listName).then(function (result) {
//update the scope with new task created
$scope.tasks.push(result);
$scope.task = {};
$scope.$apply();
});
};
// example to update task
$scope.updateTask = function (listName, item) {
testService.updateTask(listName, item).then(function (result) {
$scope.editing = $scope.tasks.indexOf(item);
$scope.$apply();
});
};
$scope.editItem = function (index) {
$scope.editing = $scope.tasks.indexOf(index);
}
$scope.saveField = function (index) {
if ($scope.editing !== false) {
$scope.editing = false;
}
};
// example to delete task
$scope.deleteTask = function (listName, item,index) {
testService.deleteTask(listName, item).then(function (result) {
$scope.tasks.splice(index, 1);
$scope.$apply();
});
};
});
Now, its time to bind the view. add the below piece of code in test.aspx
<%@ Page Language="C#" MasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=15.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" meta:progid="SharePoint.WebPartPage.Document" meta:webpartpageexpansion="full" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
<SharePoint:EncodedLiteral runat="server" Text="<%$Resources:wss,multipages_homelink_text%>" EncodeMethod="HtmlEncode" />
-
<SharePoint:ProjectProperty Property="Title" runat="server" />
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderPageImage" runat="server">
<img src="/_layouts/15/images/blank.gif?rev=23" width='1' height='1' alt="" />
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
<label class="ms-hidden">
<SharePoint:ProjectProperty Property="Title" runat="server" />
</label>
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderTitleAreaClass" runat="server">
<SharePoint:UIVersionedContent runat="server" UIVersion="<=3">
<contenttemplate>
<style type="text/css">
td.ms-titleareaframe, .ms-pagetitleareaframe {
height: 10px;
}
div.ms-titleareaframe {
height: 100%;
}
.ms-pagetitleareaframe table {
background: none;
height: 10px;
}
.ms-viewheadertr ms-vhltr {
background: rgb(246,248,249); /* Old browsers */
/* IE9 SVG, needs conditional override of 'filter' to 'none' */
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y2ZjhmOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2U1ZWJlZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUxJSIgc3RvcC1jb2xvcj0iI2Q3ZGVlMyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNWY3ZjkiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
background: -moz-linear-gradient(top, rgba(246,248,249,1) 0%, rgba(229,235,238,1) 50%, rgba(215,222,227,1) 51%, rgba(245,247,249,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(246,248,249,1)), color-stop(50%,rgba(229,235,238,1)), color-stop(51%,rgba(215,222,227,1)), color-stop(100%,rgba(245,247,249,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 50%,rgba(215,222,227,1) 51%,rgba(245,247,249,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 50%,rgba(215,222,227,1) 51%,rgba(245,247,249,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 50%,rgba(215,222,227,1) 51%,rgba(245,247,249,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(246,248,249,1) 0%,rgba(229,235,238,1) 50%,rgba(215,222,227,1) 51%,rgba(245,247,249,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f6f8f9', endColorstr='#f5f7f9',GradientType=0 ); /* IE6-8 */
}
.ms-vh2 {
font-size: 13px;
font-weight: 500;
}
</style> <!--[if gte IE 9]>
<style type="text/css">
.gradient {
filter: none;
}
</style> <![endif]-->
</contenttemplate>
</SharePoint:UIVersionedContent>
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<meta name="CollaborationServer" content="SharePoint Team Web Site" />
<SharePoint:StyleBlock runat="server">
.s4-nothome {
display:none;
}
</SharePoint:StyleBlock>
<script type="text/javascript" src="../JS/jquery.min.js">//<![CDATA[//]]></script>
<script type="text/javascript" src="../JS/angular.min.js"></script>
<script type="text/javascript" src="../JS/SharePointListModule.js"></script>
<script type="text/javascript" src="../JS/Controllers.js"></script>
<script type="text/javascript" src="../JS/Common.Services.js"></script>
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderSearchArea" runat="server">
<SharePoint:DelegateControl runat="server"
ControlId="SmallSearchInputBox" />
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderLeftActions" runat="server" />
<asp:Content ContentPlaceHolderID="PlaceHolderLeftNavBar" runat="server">
<div class="page">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="navHolder" id="fisCustomNav">
<ul class="nav-site" id="fisNavroot">
</ul>
<ul class="nav-device-main">
<li></li>
</ul>
</div>
</div>
</div>
</div>
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderPageDescription" runat="server">
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderBodyAreaClass" runat="server">
<SharePoint:StyleBlock runat="server">
.ms-bodyareaframe {
padding: 0px;
}
</SharePoint:StyleBlock>
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
<form class="form-horizontal" name="taskForm" novalidate>
<div class="page" ng-app="SharePointAngApp">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 replacement-btn-list">
<h3 class="text-bold text-color-dark ">List of Tasks:</h3>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="table-responsive replacement-list" ng-controller="spTasksController">
<table class="table">
<tr>
<th>Tasks</th>
<th>Status</th>
<th>Prority</th>
<th>Update</th>
</tr>
<tbody>
<tr ng-repeat="task in tasks">
<td><span ng-hide="editMode">{{task.Title}}</span><input type="text" ng-show="editMode" ng-model="task.Title" /></td>
<td>
<div>{{task.Status}}</div>
</td>
<td>
<div>{{task.Priority}}</div>
</td>
<td><span>
<input type="button" ng-hide="editMode" ng-click="editMode = true; editItem(task) " value="Edit" /></span>
<span>
<input type="button" ng-show="editMode" ng-click="editMode = false; updateTask('Workflow Tasks',task)" value="Save"></span></td>
<td>
<div>
<input type="button" ng-click="deleteTask('Workflow Tasks',task,$index)" value="Delete" /></div>
</td>
</tr>
<tr>
<td>
<input type="button" ng-click="addTask('Workflow Tasks')" value="Add" /></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</form>
</asp:Content>
If you noticed in parent div i have added : <div class="page" ng-app="SharePointAngApp">
and in child div added ng-controller
<div class="table-responsive replacement-list" ng-controller="spTasksController">
Once we add the controller, we can access all the scope variables in child elements.
Output will looks like below:
Hope this will help you to build SharePoint applications using Angualr.
Happy learning!
Thank you for such a wonderful Information !!
ReplyDeleteHere is a list of Top LINUX INTERVIEW QUESTIONS
Veritas Cluster Interview Questions
SAMBA Server Interview Questions
Linux FTP vsftpd Interview Questions
SSH Interview Questions
Apache Interview Questions
Nagios Interview questions
IPTABLES Interview Questions
Ldap Server Interview Questions
LVM Interview questions
Sendmail Server Interview Questions
YUM Interview Questions
NFS Interview Questions
Read More at :- Linux Troubleshooting
Poorly written code with heaps of errors
ReplyDeleteThank's, should I need to use request executor ? how can I make CORS request ?
ReplyDeleteHi Anuja,
ReplyDeleteSo bloody thorough! Ah! So happy and blissed out! I feel redeemed by reading out #topic. Keep up the good work!
I’m a Spanish student of electronics and I join in computer science programming arduino. Later I study something of java by myself and now I want to use Linux and learn bash.
It consists of delaying block allocation until the data is going to be written to the disk, unlike some other file systems, which may allocate the necessary blocks before that step.
Now I am using ubuntu GNOME for 2 weeks ago, but I don’t really like it(WHY DONT HAVE DESKTOP??), so I want to try other distros. I use the computer for use Firefox, programming arduino and java, freeoffice, play League of Legends and for some programs of electronics (I still have problems with wine, but I hope I can fix it).
But great job man, do keep posted with the new updates.
Kind Regards,
Kevin
ReplyDeleteThis post is so interactive and informative.keep update more information...
Manual Testing Course in Bangalore
Manual Testing Training in Bangalore