Create SharePoint Hosted App in SharePoint 2013

6 comments
Hello Everyone,

In this post we will see how to build a SharePoint hosted Client Webpart.In Our sample demo we are using REST API and Client Object Model (ECMA Script).Following App will fetch items from the SharePoint List and bind to the drop down list.

Applies To : SharePoint Foundation 2013,SharePoint Server 2013.

Open Visual Studio as an Administrator,Click on Create "New Project..."

Select "App for SharePoint" from the "Office/SharePoint"->"Apps" from Templates as shown in screen below provide "AppName" and provide the "Path of the App".

Select a site where you want to deploy your App for testing purpose ,among the two radio buttons (Provided,SharePoint) select SharePoint-hosted app and click on Finish.

Now, Our App solution is creating ,It will take some time to create .

After creating the solution ,It will contain four folders each folder contains app related files.

Content:
which contains the App.css file, In further if we want to add/create any css it is better to create in this folder.
Images:
default it contains the Appicon.png file, you can place your image files in this folder
Pages:
which contains Default.aspx , starting point of our App.After creating our Client webpart our page will be placed in this folder
Scripts:
this folder contains the Apps.js file and some other js files.

Now , we need to create Client Webpart ,to create Client Web Part Right click on solution and "Add"->"New Item".

Select "Client Web Part(Host Web)" from the Templates ,Specify a name to it and click on "Add"

After creating the Client Web Part along with this a new page will also created, Provide name here.

Now you can see that a page will be created under Pages folder and new folder is created with Web Part name..

Open our page , Add "css" and "js" to our page.
<WebPartPages:AllowFraming ID="AllowFraming" runat="server" /> which is important to allow the page to show in IFRAME.

    <script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="../Scripts/MicrosoftAjax.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.js"></script>

   
    <meta name="WebPartPageExpansion" content="full" />
    <!-- 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>
Note: js file order is Important.

In our page , I am adding drop down control to bind list values inside <form> tag
Code.
<body>
    <h1>My first SP Hosted App</h1>
    <form id="myForm" runat="server">
       <h2> Using REST API </h2>
        <br />
        <select id="ddl1">
        </select>

      <h2>  Using ECMA Script</h2>
        <br />
        <select id="ddl2">

        </select>
    </form>

</body>


Now,Open "App.js" file add below Code in it.
//'use strict';

// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
var spHostUrl;
var SPAppWebUrl;
$(document).ready(function () {
    //Get the Host Url from the URl
    spHostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
    //Get the App Url from the browser Url.
    SPAppWebUrl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));

    SP.SOD.executeFunc("sp.js", "SP.ClientContext", function () {
        SP.SOD.executeFunc("sp.runtime.js", "SP.ClientContext", function () {
            $.getScript(spHostUrl + "/_Layouts/15/SP.RequestExecutor.js", function (data) {
                //Our Main function.
                MainFunction();
            });
        });
    });
});

function MainFunction() {
    //Calling function , which will load values from SP List using REST API.
    getItems_Rest();

    //Calling a function , which will load values from sp list using ECMA Script
    getItems_List();
}
//This function is used to get the Host and App Web Url from the Url
function getQueryStringParameter(urlParameterKey) {
    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] == urlParameterKey)
            return decodeURIComponent(singleParam[1]);
    }
}

// Regular way to fetch the Items from List by using REST
/*
function getItems(WebUrl) {
    var queryUrl = WebUrl + "/_api/lists/getbytitle('TestList')/items";
    alert(queryUrl);
    $.ajax({
        url: queryUrl,
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: onQuerySuccess,
        error: onQueryError
    });
}
*/

function getItems_Rest() {
    //Generating the Url
    var url = SPAppWebUrl + "/_api/SP.AppContextSite(@target)" +
        "/web/lists/getbytitle('TestList')/items?" +
        "@target='" + spHostUrl + "'";
    var executor = new SP.RequestExecutor(SPAppWebUrl);
    executor.executeAsync({
        url: url,
        method: "GET",
        headers: { "Accept": "application/json;odata=verbose" }, // return data format
        success: onQuerySuccess,
        error: onQueryError
    });
}

function onQuerySuccess(data) {
    var jsonObject = JSON.parse(data.body);
    var results = jsonObject.d.results;
    if (results != null) {
        //Looping Jason data and binding to div
        $.each(results, function (index, Loaddata) {
            var optionhtml = '<option value="' +
        Loaddata.Title + '">' + Loaddata.Title + '</option>';
            $('#ddl1').append(optionhtml);
        });
    }
}

function onQueryError(error) {
    alert("Error: " + error.statusText);
}

function getItems_List() {
    var context = SP.ClientContext.get_current();
    var parentContext = new SP.AppContextSite(context, spHostUrl);
    var web = parentContext.get_web();

    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml("");

    //var query = "<View><Query><Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + strValue + "</Value></Eq></Where></Query></View>";
    //camlQuery.set_viewXml(query);

    var list = web.get_lists().getByTitle("TestList");
    var listItems = list.getItems(camlQuery);

    context.load(listItems);
    context.executeQueryAsync(onQuerySucceeded, onQueryFailed);

    function onQuerySucceeded() {
        PopulateValues(listItems, "#ddl2", "Title");
    }
    function onQueryFailed(sender, args) {
        alert('Request failed. ' + args.get_message() +
            '\n' + args.get_stackTrace());
    }
}

//used to bind values to ddl(listcollection,Control ID,Name of the column)
function PopulateValues(listItems, ddl, columnName) {
    var listEnumerator = listItems.getEnumerator();

    var ddlList = $(ddl);
    if (listEnumerator.$2K_0 > 0) {
        ddlList.append("<option>Click To Select</option>");
    }
    while (listEnumerator.moveNext()) {
        var listItem = listEnumerator.get_current();
        var optionValue = "<option value='" + listItem.get_item(columnName) + "'>" +
            listItem.get_item(columnName) + "</option>";
        ddlList.append(optionValue);
    }

}


Explanation of Code:
In order for SharePoint-hosted apps to access data in their host webs. app permissions have to be set and the cross-domain library has to be used. The cross-domain library is needed because the app is in its own app domain and not in the SharePoint domain.
Also, the user has to have the proper permissions on the respective sites.Using the Cross-Domain JavaScript Library The SharePoint cross-domain library is contained in the file "SP.RequestExecutor.js",which is located in the virtual "/_layouts/15/" directory on SharePoint servers. To use it, load this file on a remote Web page.
In JavaScript, we need to create an SP.RequestExecutor object and then call its executeAsync method. As a parameter to this method we can pass the information it needs to construct an HTTP request to the REST service. The main differences between REST calls using OAuth and REST calls using the cross-­domain library are that for the latter, you don’t need to pass an access token in the request, but you do need to specify (in the RESTful URL) the SharePoint Web site that will serve as the client context site.
var url = SPAppWebUrl + "/_api/SP.AppContextSite(@target)" +
        "/web/lists/getbytitle('TestList')/items?" +
        "@target='" + spHostUrl + "'";
    var executor = new SP.RequestExecutor(SPAppWebUrl);
    executor.executeAsync({
        url: url,
        method: "GET",
        headers: { "Accept": "application/json;odata=verbose" }, // return data format
        success: onQuerySuccess,
        error: onQueryError
    });

The SharePoint App JavaScript code can locate the List in the site collection using the following url:var url = SPAppWebUrl + "/_api/SP.AppContextSite(@target)" +
        "/web/lists/getbytitle('TestList')/items?" +
        "@target='" + spHostUrl + "'";
In the above code, the SPAppWebUrl represents the SharePoint App URL where the App is hosted and SPHostUrl represents the URL for the Site collection from where the List is accessed. The listName is the list on which operations are to be performed.

Permissions:
In Order to access the host web data app should have permissions.
Open "AppManifest.xml" file

Click on "Permissions" Tab.

here, I am adding permission on "Web - Read" and "List - Full Control".

Click on "General" Tab and select the start page for our app .In my case i am selecting "SampleClientWp.aspx" and Save file.

Now, deploy your solution by right click on your solution

Once deployed you will be prompted with a trust dialog verifying the web part will be accessing the permissions as set in the AppManifest.xml.
Click on “Trust It”.
Alternatively you can hit F5 and you can debug and step through the code but you will still be prompted with the trust dialog.

Now the page will be rendered and you will look out put as follows.



In above Post, MicrosoftAjax.js is important .If it is not loaded properly we will get an error like,
Error message: 'Type' is undefined.
The JSOM uses the Type.registerNamespace method in the Microsoft Ajax library to register the SP namespace.So we need to add the reference in Page.
I have included that js file in my "Scripts" folder.

You can download the solution from the below link,

https://sites.google.com/site/sharepointkitchenblog/SPHostedApp.zip

Thanks for Reading.

Related Post

6 comments:

  1. SharePoint free development solutions can be used to create various web-sites with shared documents, dedicated applications, as well as blogs, forums, wikis etc. SharePoint functionalities are presented to the user through editable control elements to display and work on data. All of the SharePoint functionality is made available to the user via browser. See more information at : - www.cloudappsportal.com

    ReplyDelete
  2. this is working for me but it is showing all options twicly in dropdown list

    ReplyDelete