CRUD operation with Dialog box using REST in SharePoint Hosted App
The REST API in
SharePoint 2013 provides developers with a simple standardized method of
accessing information contained within SharePoint.
REST is a software architecture that
uses uniform resource identifiers (URI) to specify operations against a remote
service. Open Data Protocol (OData) is the protocol that is used along with
REST to access many cloud-based services.
REST-based (known more commonly as
“RESTful”) solutions use standard HTTP GET, POST, PUT, and
DELETE verbs to perform CRUD operations against a remote source. Support
for the standard HTTP verbs provides easy cross-platform data access and is
ideally suited for cloud-based apps. The OData protocol returns results in either
the Atom Publishing Protocol (AtomPub) or JSON.
Obtaining the site URI
One key prerequisite to
interacting with SharePoint lists items is to obtain the correct URI for the
SharePoint site the list is hosted in. There are multiple ways to do this:- On SharePoint pages _spPageContextInfo.siteAbsoluteUrl
contains the URI to the site that the app is installed within (the parent
site).
- You can include a set of standard tokens in the URL
attribute of both pages and web parts. Adding {StandardTokens} will
include the following 7 parameters to the url; SPHostUrl, SPHostTitle,
SPAppWebUrl, SPLanguage, SPClientTag, SPProductNumber, and SenderId. These
will need to be split out of the URL to be used. There are multiple ways
to do this. The simplest is to loop through all the parameters until you
find the parameter you are looking for. The following snippet of code
searches for the SPAppWebUrl.
Fig1.1
List Item Types
To update or create list items
you will need to include the list item type. This is a string automatically
created by SharePoint when the list is first created. Two possible ways to
obtain this are:- Perform a read operation on the list and locate the
type within the returned set of elements. In JSON format the type can be
found within the __metadata attribute of all of the returned list items.
In Atom/xml format (the default format returned if you query from a web
browser) you can find it in the category scheme attribute (labelled
‘term’) within the item.
- You can attempt to generate the value from the list
name. In general list item types follow the convention SP.Data.ListNameListItem
(e.g. list name is “Test”, list item type is SP.Data.TestListItem).
However this is not always the case. For example SharePoint automatically
capitalises the first letter of the list name (e.g. list name “test” list
item type is SP.Data.TestListItem). The following code snippet shows how
to generate the List Item Type based on the list name.
Request Digests
A replay attack occurs when a
valid request is sent to the server and a copy of that request is stored. The
request is then sent multiple times (replayed). This can result in a variety of
different issues the most common of which is duplication of data. To prevent
this, SharePoint requires the user to include a request digest value with each
create, update and delete operation. This value is then used by SharePoint to
identify non-genuine requests. Inside SharePoint Hosted apps, the request
digest can be found by reading the value of the “__REQUESTDIGEST” object within
the html page.
1. var digestValue = $("#__REQUESTDIGEST").val()
Note: this will only work on pages that contain
the SharePoint Chrome element. The example above requires JQuery to work.
eTags
When updating or deleting items
within SharePoint lists via REST you must specify the Entity Tag (eTag) value
that was returned with the item during the initial query. This enables
SharePoint to determine if the item has changed since it was requested.
Alternatively you can tell SharePoint to perform the operation regardless by
specifying * as the eTag value. For example:- “If-Match”: item.__metadata.etag can be used to
specify the actual eTag value (‘item’ is the object returned from
SharePoint containing the list item in JSON format).
- “If-Match”: “*” can be used to match any eTag value
resulting in the operation being performed regardless of the actual value.
Create SharePoint Hosted App with below mention structure
Fig 1.2
Add
Default data to Custom Customers List
|
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListInstance Title="Customers" OnQuickLaunch="TRUE" TemplateType="10000"
Url="Lists/Customers" Description="My List Instance">
<Data>
<Rows>
<Row>
<Field Name="FirstName">Scot</Field>
<Field Name="Title">Hillier</Field>
</Row>
<Row>
<Field Name="FirstName">Ted</Field>
<Field Name="Title">Pattison</Field>
</Row>
<Row>
<Field Name="FirstName">Mike</Field>
<Field Name="Title">Morton</Field>
</Row>
</Rows>
</Data>
</ListInstance>
</Elements>
|
Add HTML
Content to Default.aspx
|
<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<script type="text/javascript" src="../Scripts/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.runtime.debug.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.debug.js"></script>
<script type="text/javascript" src="../Scripts/jsrender.js"></script>
<!-- Add your CSS styles to the following file -->
<link rel="Stylesheet"
type="text/css" href="../Content/App.css" />
<!-- Add your JavaScript to the following file -->
<script type="text/javascript" src="../Scripts/App.js"></script>
<script type="text/javascript" src="../Scripts/jquery-ui-1.9.2.min.js"></script>
</asp:Content>
|
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
<h1>SharePoint Hosted
App -CRUD Operations using REST </h1>
<div id="toolbar">
<input type="button" id="cmdAddNewCustomer" value="Add New Customer" class="ms-ButtonHeightWidth" />
</div>
<div id="results"></div>
<div id="viewCustomerDialog" style="display: none;"></div>
<div id="editCustomerDialog" style="display: none;">
<table id="customerEditTable">
<tr>
<td>First Name:</td>
<td><input id="customerFirstName" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input id="customerLastName" /></td>
</tr>
</table>
<div style="display: none;">
<input id="customerId"
/>
<input id="customerETag"
/>
</div>
</div>
</asp:Content
|
Read Item from Customer List (Code in
App.js file)
A simple ajax call is executed against the SharePoint
server. If the call succeeds then the success function (passed in as a
parameter) is called, if it fails then the failure function (also passed in
as a parameter) is called. In both cases the data returned from the server is
passed through to the function.
|
function Read() {
var url =
_spPageContextInfo.webServerRelativeUrl
getListItems(url,
function
(data) {
var odataResults =
data.d.results;
// set rendering template
var tableHeader = "<thead>"
+
"<td>Last
Name</td>" +
"<td>First
Name</td>" +
"<td> </td>" +
"<td> </td>" +
"</thead>";
var table = $("<table>",
{ id: "customersTable" }).append($(tableHeader));
var renderingTemplate = "<tr>"
+
"<td>{{>Title}}</td>" +
"<td>{{>FirstName}}</td>" +
"<td><a href='javascript:
onUpdateCustomer({{>Id}});'><img src='../Content/EDITITEM.gif'
alt='Edit' /></a></td>"
+
"<td><a href='javascript:
onDeleteCustomer({{>Id}});'><img src='../Content/DELITEM.gif'
alt='Delete' /></a></td>"
+
"</tr>";
$.templates({ "tmplTable": renderingTemplate });
table.append($.render.tmplTable(odataResults));
$("#results").append(table);
}, function (data) {
alert("Ooops, an error occured. Please try again");
});
}
function
getListItems(siteurl, success, failure) {
$.ajax({
url:
siteurl + "/_api/web/lists/getbytitle('Customers')/items?$select=Id,FirstName,Title" + "&$orderby=Title,FirstName",
method: "GET",
headers: {
"Accept": "application/json;
odata=verbose" },
success: function (data) {
success(data);
},
error: function (data) {
failure(data);
}
});
}
|
Update
In contrast to reading list
items updating them is probably the hardest operation. To update an item you
will need to obtain the URL of the item and, depending on your handling of
eTags, the eTag value. The simplest way to do this is to perform a get operation
and then use the properties of the item. The update method uses the same
method mentioned for update operations to generate the list item type. Read
Function assign Id to all Edit Button, On Click of Edit button , Dialog Open
with existing value of corresponding Id , User can update the existing value
and Click on Save. Once User click on the save button, It will update the
base page data without refreshing the page. |
function
onUpdateCustomer(customerId) {
var url =
_spPageContextInfo.webServerRelativeUrl;
updateListItem(customerId, url, function () {
alert("Item updated, refreshing avilable items");
}, function () {
alert("Ooops, an error occured. Please try again");
});
}
// Update Operation
function updateListItem(itemId,
siteUrl, success, failure) {
$.ajax({
url:
siteUrl + "/_api/web/lists/getByTitle('Customers')/items(" + itemId + ")",
method: "Get",
headers: {
"ACCEPT": "application/json;odata=verbose" },
success: onCustomerReturned,
error:function (data) {
failure(data);
}
});
}
function
onCustomerReturned(data) {
$("#customerId").val(data.d.Id);
$("#customerLastName").val(data.d.Title);
$("#customerFirstName").val(data.d.FirstName);
$("#customerETag").val(data.d.__metadata.etag);
var customer_dialog = $("#editCustomerDialog");
customer_dialog.dialog({
autoOpen: true,
title: "Edit Customer",
width:
420,
buttons: {
"Save":
updateCustomer,
"Cancel": function () { $(this).dialog("close"); },
}
});
}
function
updateCustomer(event) {
$(this).dialog("close");
var Id = $("#customerId").val();
var FirstName = $("#customerLastName").val();
var LastName = $("#customerFirstName").val();
var etag = $("#customerETag").val();
$.ajax({
url:
_spPageContextInfo.webServerRelativeUrl + "/_api/web/lists/getByTitle('Customers')/getItemByStringId('" + Id + "')",
type: "POST",
contentType: "application/json;odata=verbose",
data:
JSON.stringify(
{
'__metadata': {
'type': 'SP.Data.CustomersListItem'
},
'Title': LastName,
'FirstName': FirstName
}),
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"IF-MATCH": "*",
"X-Http-Method":
"PATCH"
},
success: function (data) {
Read();
},
error: function (err) {
alert(JSON.stringify(err));
}
});
}
|
Delete
The code below performs a
delete operation. In a similar way to updating items delete operations are
performed using the URI of the item |
// occurs when a user clicks the delete button
function
onDeleteCustomer(customerId) {
var url = _spPageContextInfo.webServerRelativeUrl;
deleteListItem(customerId, url, function () {
alert("Item deleted, refreshing avilable items");
Read();
}, function () {
alert("Ooops, an error occured. Please try again");
});
}
// Delete Operation
function
deleteListItem(itemId, siteUrl, success, failure) {
$.ajax({
url:
siteUrl + "/_api/web/lists/getByTitle('Customers')/getItemByStringId('" + itemId + "')",
type: "DELETE",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"IF-MATCH": "*"
},
success: function (data) {
success(data);
},
error:
function
(data) {
failure(data);
}
});
}
|
Create
First
bind the OnAddCustomer event to input button
On
click Button , Div based dialog box will appear as pop up
User
can enter first name and last name and click on Save, Parent table data will
be refresh by new record.
|
$(function () {
$("#cmdAddNewCustomer").click(onAddCustomer);
$("#cmdAddNewCustomer").button();
$("#results").append($("<img>",
{ src: "../Content/gears_anv4.gif" }));
Read();
});
function
onAddCustomer(event) {
var customer_dialog = $("#editCustomerDialog");
customer_dialog.dialog({
autoOpen: true,
title: "Add New Customer",
width:
420,
buttons: {
"Save":
saveNewCustomer,
"Cancel": function () { $(this).dialog("close"); },
}
});
}
function
saveNewCustomer(event) {
$(this).dialog("close");
// clear results and add spinning gears icon
$("#results").empty();
$("<img>",
{ "src": "../Content/GEARS_AN.GIF" }).appendTo("#results");
// get data from dialog for new customer
var LastName = $("#customerLastName").val();
var FirstName = $("#customerFirstName").val();
$.ajax({
url:
_spPageContextInfo.webServerRelativeUrl +"/_api/web/lists/getByTitle('Customers')/items",
type: "POST",
contentType: "application/json;odata=verbose",
data:
JSON.stringify(
{
'__metadata': {
'type': 'SP.Data.CustomersListItem'
},
'Title': LastName,
'FirstName':
FirstName,
}),
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function () {
Read();
},
error: function (err) {
alert(JSON.stringify(err));
}
});
}
|
Out Put:-
No comments:
Post a Comment