Thursday, November 26, 2015

Building Charts using ecmascript, REST with Cross Domain Call in SharePoint Hosted App

Building Charts using ecmascript, REST with Cross Domain Call in SharePoint Hosted App
High Chart Site : http://www.highcharts.com/
First Create a SharePoint List called "Temperature" as shown below.
Open Visual Studio -> File -> New -> Project -> Installed -> Templates ->  Visual C# -> Office/SharePoint -> Apps -> Apps for Office
Go to SharePointApp6 -> pages -> Open 'Default.aspx' page.
Change 'Default.aspx' page code as shown below.
--------------------------------------------------------------------------------------------------------
<%@ Page Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" MasterPageFile="~masterurl/default.master" Language="C#" %>
<%@ 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" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
    <script type="text/javascript" src="../Scripts/jquery-1.9.1.min.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" />
    <link rel="Stylesheet" type="text/css" href="../Content/App.css" />
    <script type="text/javascript" src="https://code.highcharts.com/highcharts.js"></script>
    <script type="text/javascript" src="https://code.highcharts.com/modules/exporting.js">
</script>
    <script type="text/javascript" src="../Scripts/App.js"></script>
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
    Page Title
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
    <table>
        <tr>
            <td>
                <div id="div1"></div>
            </td>
            <td>
                <div id="container"></div>
            </td>
        </tr>
    </table>
</asp:Content>
--------------------------------------------------------------------------------------------------------
Go to SharePointApp6 -> Scripts -> open 'App.js' JavaScript file.
Change  'App.js' JavaScript file code as shown below.
--------------------------------------------------------------------------------------------------------
Below Code using ecmascript
--------------------------------------------------------------------------------------------------------
var web;
var hostweburl;
var appweburl;
var arrayTemperatureListItems = [];
var arrayCity = [];
var arrarMonth = [];
var seriesData = [];
var tempArray = [];
var temCity;
$(document).ready(function () {
    hostweburl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
    appweburl = decodeURIComponent(getQueryStringParameter('SPAppWebUrl'));
    var scriptbase = hostweburl + '/_layouts/15/';
    $.getScript(scriptbase + 'SP.RequestExecutor.js', printAllListItemsFromHostWeb);
});
function printAllListItemsFromHostWeb() {
    var context;
    var factory;
    var appContextSite;
    var collList;
    context = new SP.ClientContext(appweburl);
    factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
    context.set_webRequestExecutorFactory(factory);
    appContextSite = new SP.AppContextSite(context, hostweburl);
    this.web = appContextSite.get_web();
    this.list = this.web.get_lists().getByTitle('Temperature');
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><RowLimit>10</RowLimit></View>');
    this.listItems = this.list.getItems(camlQuery);
    context.load(this.listItems, 'Include(ID,City,Month,Temperature)');
    context.executeQueryAsync(Function.createDelegate(this, successHandler), Function.createDelegate(this, errorHandler));
    function successHandler() {
        var listInfo = '';
        var listEnumerator = this.listItems.getEnumerator();
        listInfo += "<table border='1'><tr><td>ID</td><td>City</td><td>Month</td><td>Temperature</td></tr>";
        while (listEnumerator.moveNext()) {
            var oList = listEnumerator.get_current();
            listInfo += '<tr><td>' + oList.get_item('ID') + "</td><td>" + oList.get_item('City') + "</td><td>" + oList.get_item('Month') + "</td><td>" + oList.get_item('Temperature') + '</td></tr>';
            arrayCity.push(oList.get_item('City'));
            arrarMonth.push(oList.get_item('Month'));
            arrayTemperatureListItems.push([oList.get_item('City'), oList.get_item('Month'), oList.get_item('Temperature')]);
        }
        listInfo += "</tr></table>";
        document.getElementById("div1").innerHTML = 'List Items found:<br/>' + listInfo;
        arrayCity = jQuery.unique(arrayCity);
        arrayCity.reverse();
        arrarMonth = jQuery.unique(arrarMonth);
        arrarMonth.reverse();
        for (var i = 0; i <arrayCity.length; i++) {
            for (var j = 0; j < arrarMonth.length; j++) {
                for (var k = 0; k < arrayTemperatureListItems.length; k++) {
                    if (arrayCity[i] == arrayTemperatureListItems[k][0] && arrarMonth[j] == arrayTemperatureListItems[k][1]) {
                        temCity = arrayCity[i];
                        tempArray.push(arrayTemperatureListItems[k][2]);
                    }
                }
            }
            seriesData.push({ name: temCity, data: tempArray });
            temCity = "";
            tempArray = [];
        }
        showChart();
    }
    function errorHandler(sender, args) {
        document.getElementById("div1").innerText = "Could not complete cross-domain call: " + args.get_message();
    }
}
function getQueryStringParameter(param) {
    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] == param) {
            return singleParam[1];
        }
    }
}
function showChart() {
    $('#container').highcharts({
        title: {
            text: 'Monthly Average Temperature',
            x: -20 //center
        },
        subtitle: {
            text: 'Source: Temperature List',
            x: -20
        },
        xAxis: {
            categories: arrarMonth
        },
        yAxis: {
            title: {
                text: 'Temperature (°C)'
            },
            plotLines: [{
                value: 0,
                width: 1,
                color: '#808080'
            }]
        },
        tooltip: {
            valueSuffix: '°C'
        },
        legend: {
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'middle',
            borderWidth: 0
        },
        series: seriesData     
    });
}
--------------------------------------------------------------------------------------------------------
Below Code using REST
--------------------------------------------------------------------------------------------------------
var web;
var hostweburl;
var appweburl;
var arrayTemperatureListItems = [];
var arrayCity = [];
var arrarMonth = [];
var seriesData = [];
var tempArray = [];
var temCity;
$(document).ready(function () {
    hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
    appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
    var scriptbase = hostweburl + '/_layouts/15/';
    $.getScript(scriptbase + 'SP.RequestExecutor.js', execCrossDomainRequest);
});
function execCrossDomainRequest() {
    var executor;
    executor = new SP.RequestExecutor(appweburl);
    executor.executeAsync(
        {
            url: appweburl + "/_api/SP.AppContextSite(@target)/web/lists/getbytitle('Temperature')/Items?$select=ID,Month,Temperature,City&@target='" + hostweburl + "/" + "'",
            method: "GET",
            headers: { "Accept": "application/json; odata=verbose" },
            success: successHandler,
            error: errorHandler
        }
    );
}
function successHandler(data) {
    var jsonObject = JSON.parse(data.body);
    var listInfo = '';
    listInfo += "<table border='1'><tr><td>ID</td><td>City</td><td>Month</td><td>Temperature</td></tr>";
    for (var i = 0; i < jsonObject.d.results.length; i++) {
        listInfo += '<tr><td>' + jsonObject.d.results[i]['ID'] + "</td><td>" + jsonObject.d.results[i]['City'] + "</td><td>" + jsonObject.d.results[i]['Month'] + "</td><td>" + jsonObject.d.results[i]['Temperature'] + '</td></tr>';
        arrayCity.push(jsonObject.d.results[i]['City']);
        arrarMonth.push(jsonObject.d.results[i]['Month']);
        arrayTemperatureListItems.push([jsonObject.d.results[i]['City'], jsonObject.d.results[i]['Month'], jsonObject.d.results[i]['Temperature']]);
    }
    listInfo += "</tr></table>";
    document.getElementById("div1").innerHTML = 'List Items found:<br/>' + listInfo;
    arrayCity = jQuery.unique(arrayCity);
    arrayCity.reverse();
    arrarMonth = jQuery.unique(arrarMonth);
    arrarMonth.reverse();
    for (var i = 0; i < arrayCity.length; i++) {
        for (var j = 0; j < arrarMonth.length; j++) {
            for (var k = 0; k < arrayTemperatureListItems.length; k++) {
                if (arrayCity[i] == arrayTemperatureListItems[k][0] && arrarMonth[j] == arrayTemperatureListItems[k][1]) {
                    temCity = arrayCity[i];
                    tempArray.push(arrayTemperatureListItems[k][2]);
                }
            }
        }
        seriesData.push({ name: temCity, data: tempArray });
        temCity = "";
        tempArray = [];
    }
    showChart();
}
function errorHandler(data, errorCode, errorMessage) {
    var oli = document.createElement("li");
    oli.innerText = "Could not complete cross-domain call: " + errorMessage;
    document.getElementById("WebTitles").appendChild(oli);
}
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];
    }
}
function showChart() {
    $('#container').highcharts({
        title: {
            text: 'Monthly Average Temperature',
            x: -20 //center
        },
        subtitle: {
            text: 'Source: Temperature List',
            x: -20
        },
        xAxis: {
            categories: arrarMonth
        },
        yAxis: {
            title: {
                text: 'Temperature (°C)'
            },
            plotLines: [{
                value: 0,
                width: 1,
                color: '#808080'
            }]
        },
        tooltip: {
            valueSuffix: '°C'
        },
        legend: {
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'middle',
            borderWidth: 0
        },
        series: seriesData
    });
}
--------------------------------------------------------------------------------------------------------
Go to SharePointApp6 -> AppManifest.xml -> Permission Tab and give "Full Control" for "Web" Scope as shown below.
For deploy Click "F5" and Click on "Trust it" to proceed.
Thank You.