Saturday 31 October 2015

Set the Master Page of the Host Web in SharePoint Hosted App 2013 using JavaScript.

SharePoint CSOM (Client Side Object Model) or apps are capable of performing almost all functions that server-side code provides. There are some limitations, but the CSOM is maturing with time.

In this article, I will tell you how to set the master page of the host web from the app web (app) using JavaScript. Host web and App web reside in different contexts at different levels of scope, so SharePoint doesn't allow app web contexts to set host web master page directly.

Steps to set the master page of the host web from App Web:
1. Create a SharePoint hosted app and add a module named "CustomMasterPage".



2. Download a copy of seattle.master from the Master Page gallery.
3. Copy and paste this file content into our modules .txt file and make custom changes to it as required (I have just changed the background colour and image for the demo).

Tip: Don't change the extension file (.txt) in the module; otherwise, it is not easy to read the file content.

4. Now create a namespace to avoid method and property conflicts.
5. Get appweb and hostweb URLs.
6. Set clientContext and hostWebContext.
7. Read the text of the above created .txt file using a jQuery ajax call.
8. Create a file (by code) in host web and set that as the master page.
9. It will be at the site and system master page level.





SharePoint Hosted App JavaScript Code

"use strict";
 
// create namespace.
window.VB = window.VB || {};
 
window.VB.HostWebApp = function () {
    var hostWebUrl,
        appWebUrl,
        context,
        hostWebContext,
        destinationServerRelativeUrl,
        masterPageFileName,
        // read the master page contents from text file.
        readFileFromAppWeb = function (appPageUrl, hostWebServerRelativeUrl, fileName) {
            destinationServerRelativeUrl = hostWebServerRelativeUrl;
            masterPageFileName = fileName;
 
            $.ajax({
                url: appPageUrl,
                type: "GET",
                async: false,
                cache: false,
                success: function (data) {
                    if (data !== null && data !== undefined && data.length > 0) {
                        uploadFileToHostWeb(destinationServerRelativeUrl, masterPageFileName, data);
                    } else {
                        alert("Failed to read file from app web.");
                    }
                },
                error: function (jqXhr, textStatus) {
                    alert("Request for page in app web failed: " + textStatus);
                }
            });
        },
        // upload file to host web.
        uploadFileToHostWeb = function (serverRelativeUrl, filename, contents) {
            var createInfo = new SP.FileCreationInformation();
            createInfo.set_content(new SP.Base64EncodedByteArray());
            var index;
            for (index = 0; i < contents.length; index = index + 1) {
                createInfo.get_content().append(contents.charCodeAt(index));
            }
            createInfo.set_overwrite(true);
            createInfo.set_url(filename);
            var files = hostWebContext.get_web().getFolderByServerRelativeUrl(serverRelativeUrl).get_files();
 
            context.load(files);
            files.add(createInfo);
            context.executeQueryAsync(setMasterPageSuccess, setMasterPageError);
        },
        setMasterPageSuccess = function () {
            $("#message").append(["<br /><div>Master Page in host web successfully: ", destinationServerRelativeUrl, "/", masterPageFileName, "</div>"].join(""));
            var masterPageUrl = ["/", hostWebUrl.split("/")[3], "/", hostWebUrl.split("/")[4], "/", destinationServerRelativeUrl, "/", masterPageFileName].join("");
            setMaster(masterPageUrl);
        },
        setMasterPageError = function (sender, args) {
            alert('Request failed,Error: ' + args.get_message() + '\n' + args.get_stackTrace());
        },
        // set master page on host web.
        setMaster = function (masterUrl) {
            var hostWeb = hostWebContext.get_web();
            hostWeb.set_masterUrl(masterUrl);
            hostWeb.update();
 
            context.load(hostWeb);
            context.executeQueryAsync(onSetMasterPageSuccess, onSetMasterPageFail);
        },
        onSetMasterPageSuccess = function () {
            $("#message").append("<br /><div>Master page updated successfully..</div>");
        },
        onSetMasterPageFail = function (sender, args) {
            alert("Failed to update master page on host web. Error:" + args.get_message());
        },
        getQueryStringParameterValue = function (paramToRetrieve) {
            var params = document.URL.split("?")[1].split("&"),
                paramsLength = params.length,
                index;
            for (index = 0; index < paramsLength; index = index + 1) {
                var singleParam = params[index].split("=");
                if (singleParam[0] == paramToRetrieve) {
                    return singleParam[1];
                }
            }
        },
        init = function () {
            appWebUrl = decodeURIComponent(getQueryStringParameterValue("SPAppWebUrl"));
            hostWebUrl = decodeURIComponent(getQueryStringParameterValue("SPHostUrl"));
 
            //load the required scripts.
            var scriptbase = hostWebUrl + "/_layouts/15/";
            $.getScript(scriptbase + "SP.Runtime.js",
            function () {
                $.getScript(scriptbase + "SP.js",
                    function () {
                        //to execute cross domain request.
                        $.getScript(scriptbase + "SP.RequestExecutor.js");
                    }
                );
            });
        };
 
    return {
        execute: function () {
            init();
 
            context = new SP.ClientContext.get_current();
            hostWebContext = new SP.AppContextSite(context, hostWebUrl);
 
            readFileFromAppWeb(appWebUrl + "/_catalogs/masterpage/CustomAppMaster.txt""_catalogs/masterpage""CustomAppMasterPage.master");
        }
    };
}();
 
(function () {
    window.VB.HostWebApp.execute();
}());

This code will work both for setting the Master Page of HostWeb and AppWeb by using appropriate context.

🚀 "Happy Coding" 🚀

Saturday 10 October 2015

SharePoint activates the feature using the REST API.

The REST API provides a simple and easy way to activate features at the site and web level..

I have created simple JavaScript code to activate the feature.

function activateFeature() {
    $.ajax({
        url: _spPageContextInfo.siteAbsoluteUrl + "/_api/web/features/add('7e2e2482-9007-4db3-8a7f-9bccd986ec4e')",
        type: "POST",
        headers: {
            "Accept": "application/json;odata=verbose", //return data format.
           "X-RequestDigest": $("#__REQUESTDIGEST").val()
        },
        success: function (data) {
// perform operation on the response object.
        },
        error: function (err) {
            alert("Error: " + JSON.stringify(err));
        }
    });
}


Change the URI, and the feature will be activated based on the endpoint.

  1. /web - then feature will be activated at the web level.
  2. /site - then feature will be activated at the site collection level.

Now pass the feature GUID into the add method. You can get the GUID value by using the PowerShell command or by "SharePoint Manager 2013".


🚀 "Happy Coding" 🚀

Saturday 8 August 2015

SharePoint 2013 REST API Get requests from the designer workflow.

SharePoint 2013 provides a completely new workflow engine, which has a new "Call HTTP web service" action that enables us to communicate with the web service from our workflow.

In this blog post, I will show you how you can use this new action method for a REST API GET request to a SharePoint list.

I have created a list "WebServiceList" and inserted dummy data into it as shown below.


Open SharePoint Designer 2013 and create a workflow attached to the list created above. Use the platform type as SharePoint 2013 workflow; otherwise Call HTTP web service method will not be available.
In our normal CSOM(Client Side Object Model), we call the REST API to get data back in JSON format. You need these headers as:

Accept: application/json;odata=verbose
Content-Type: application/json;odata=verbose

In the workflow add the "Build the Dictionary" action of above headers as:

Click on the three dots to add items to the dictionary.






Now, add the HTTP call web service method with type GET as given below:


Test your REST call in the browser as given below:

Add the header dictionary variable created just above to the web service and set the request type to "GET" as:


Then click OK.
Add the GET action, and now we will get the result from the response content variable as

Now get the CountItems of the Output variable (allTitles) from the get action.
Then take one variable and set it to "0" and insert Loop (Loop n times). Inside the loop again, add the GET action to get all titles from the variable JsonResult and log it. Add the Calculate action to add "1" to the loop index variable and then again set its value. Now end the workflow.
Complete workflow is given below


See the Tasks and Workflow History list details below; you will get the data fetched from the source list is logged in the history list.

Hope this will help you!


🚀"Happy Coding"🚀