Friday 10 June 2016

Build a SharePoint Hosted App Using REST Services




One of the most widely used features of SharePoint Online is the ability to create and easily store data in a list.  In just a few clicks you are able to create a data store which is integrated with various actions: creating views, sharing, following, managing permissions, running workflows, exporting to Excel, opening with Access, alerts and the list goes on.
As you can imagine, organizations quickly adopt this methodology for storing data and managing tasks.  ‘Out of the Box’ SharePoint also provides various web parts for displaying data in your lists on pages: List View Web Part, Content Query Web Part, Content Search Web Part, etc.
Now what it if you wanted to aggregate your list data with data from an external data source such as a RSS feed or data API, and display them together on a SharePoint page?  How would you go about this?
My current client, who has recently migrated their intranet over to Office 365, had this exact request.  They wanted to display their most recent internal blog posts from SharePoint blogs along with their external blog posts form their publicly-facing website.  One thing to keep in mind is that pretty much everything in SharePoint is in its most basic form ‘a list’.  Therefore this would just be a matter of querying the list programmatically as well as querying the associated external feeds.  Now if you search online for this type of solution you’ll find that it will be very difficult to find a straight forward example.  Most of the examples will reference accessing data from a list that is in your ‘app web’ which is the web that houses your new SharePoint App.  This is not the same as data that is in your ‘host web’ which is your actual Team or Publishing site for example.
For this example I’ll simulate this scenario by creating a blog in SharePoint Online and retrieving the data.  You can then easily add the logic to access your external blog posts.
These are the technologies we’ll use to do it:
  • SharePoint Hosted App
  • SharePoint REST API
  • JavaScript
  • jQuery
 I’ll provide the full source code in GitHub however if you would like to reproduce this from scratch simply follow the following 10 easy steps:
I have done so and the following is my Office 365 tenant.  I have named my tenant ‘Modern Appz’ which is what I use for my various personal projects.
2. Create a Blog site below your Team Site:
 
3.  Next we’ll need to create a SharePoint Hosted App Project in Visual Studio.  I’m using Visual Studio 2013 Update 4:
 
4.  Add your new SharePoint site (https://modernappz.sharepoint.com) and leave the app setting to ‘SharePoint-hosted’:

5.  Sign in with your Office 365 account:
 
6.  Your project is now created and you are now ready to implement your custom code:
 
7.  Next we need to add a Client Web Part to our project which will serve as the ‘App Part’ that we will eventually add to our SharePoint page:

8.  Replace the code in the newly created ‘ClientWebPartBlogs.aspx’ page in you ‘Pages’ folder with the following:

<%@ Page language="C#" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ 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" %>

<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>


<WebPartPages:AllowFraming ID="AllowFraming" runat="server" />


<html>

<head>

<title></title>


<script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>

<script type="text/javascript" src="/_layouts/15/MicrosoftAjax.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>


<script type="text/javascript">

// Set the style of the client web part page to be consistent with the host web.

(function () {

'use strict';



var hostUrl = '';

if (document.URL.indexOf('?') != -1) {

var params = document.URL.split('?')[1].split('&');

for (var i = 0; i < params.length; i++) {

var p = decodeURIComponent(params[i]);

if (/^SPHostUrl=/i.test(p)) {

hostUrl = p.split('=')[1];

document.write('<link rel="stylesheet" href="' + hostUrl + '/_layouts/15/defaultcss.ashx" />');

break;

}

}

}

if (hostUrl == '') {

document.write('<link rel="stylesheet" href="/_layouts/15/1033/styles/themable/corev15.css" />');

}

})();

</script>


<%-- Internal blog --%>

<script type="text/javascript">



var hostweburl;

var appweburl;



// Load the required SharePoint libraries

$(document).ready(function () {

//Get the URI decoded URLs.

hostweburl =

decodeURIComponent(

getQueryStringParameter("SPHostUrl")

);

appweburl =

decodeURIComponent(

getQueryStringParameter("SPAppWebUrl")

);



// resources are in URLs in the form:

// web_url/_layouts/15/resource

var scriptbase = hostweburl + "/_layouts/15/";



// Load the js files and continue to the successHandler

$.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);



});



// Function to prepare and issue the request to get

// SharePoint data

function execCrossDomainRequest() {

// executor: The RequestExecutor object

// Initialize the RequestExecutor with the app web URL.

var executor = new SP.RequestExecutor(appweburl);



// Issue the call against the app web.

// To get the title using REST we can hit the endpoint:

// appweburl/_api/web/lists/getbytitle('listname')/items

// The response formats the data in the JSON format.

// The functions successHandler and errorHandler attend the

// sucess and error events respectively.

executor.executeAsync(

{

url: appweburl + "/_api/SP.AppContextSite(@target)/web/lists/getbytitle('Posts')/items?@target='" + hostweburl + "/blog'&$top=1",

method: "GET",

headers: { "Accept": "application/json; odata=verbose" },

success: successHandler,

error: errorHandler

}

);

}



// Function to handle the success event.

// Prints the data to the page.

function successHandler(data) {

var jsonObject = JSON.parse(data.body);

var blogsHTML = "";



var results = jsonObject.d.results;

for (var i = 0; i < results.length; i++) {

blogsHTML = blogsHTML + "<div><a href=\"" + hostweburl + "/blog/Lists/Posts/Post.aspx?ID=" + results[i].ID + "\" target=\"_blank\">" + results[i].Title + "</a></div><br>";

}



$('#internal').append(blogsHTML);

}



// Function to handle the error event.

// Prints the error message to the page.

function errorHandler(data, errorCode, errorMessage) {

document.getElementById("internal").innerText =

"Could not complete cross-domain call: " + errorMessage;

}



// Function to retrieve a query string value.

// For production purposes you may want to use

// a library to handle the query string.

function getQueryStringParameter(paramToRetrieve) {

var params =

document.URL.split("?")[1].split("&");

var strParams = "";

for (var i = 0; i < params.length; i = i + 1) {

var singleParam = params[i].split("=");

if (singleParam[0] == paramToRetrieve)

return singleParam[1];

}

}

</script>

</head>

<body>

<div>

<div><strong>Internal Blog Posts</strong></div>

<div id="internal"></div>

<div><strong>External Blog Posts</strong></div>

<div id="external">[Append your External Blog Posts Here]</div>

</div>

</body>

</html>
9.  Now here’s the secret sauce to all of this.  In order for your app to read data from the host web, you need to provide the app with read permissions to the site collection.  To do so double-click on your AppManifest, click the ‘Permissions’ tab and set it to the following:
 
10.  We are now ready to deploy our new app to our site collection.  Simply right click the root of your project in Visual Studio and click ‘Deploy’.  Once the installation is completed you will be presented with this screen.  By clicking ‘Trust It’ you confirm that you would like to provide the app with read permissions to the host web (site collection).
After you have trusted the app simply add the ‘App Part’ to your page and here you have it my friends.  This serves the basis for all list queries you will need to make from your host web :). 

No comments:

Post a Comment