Monday, June 23, 2014

SharePoint:Add addEventListener Radar in Host Web to load App Part Custom postMessage to Ribbons

Hi all, 
This article talks about a frequent topic SharePoint Apps Parts and SharePoint Sites. How to communicate between App as Iframe to SharePoint Site. A lot of developers know how to manage this type of problems adding webPart with addEventListener code and postMessage to communicate with App Iframe.

This solution create a "Radar" of EventListeners in the SharePoint site and add a Custom Ribbon with content sent by the Iframe from a App Part added in the SharePoint Page. 
For this example solution was created 2 App Parts to send different content to  SharePoint Pages.

Here is the architecture of the Example Solution:

Final output of the example solution:

Here is a article talking about this type of communication between the App Part and SharePoint Site with Iframe approach:

How to Create our Radar Listener Solution

Create Event Listener Site Radata Script File

This Script will add a Listener in the SharePoint site to load the content sent by the Client App Part.

PS: this is a simple example for more complex apps recomend to add some type of id to be more easy to indentify and complex format of Data

function processFrameEvent(message) {
    if (! {
    var res =";");
    if (res.length == 2){
  if (res[0].indexOf("Option")> -1)
  $(document).ready(function () {
   SP.SOD.executeFunc('sp.js', 'SP.ClientContext', LoadRibbon(res[0], res[1]));

//Add addEventListener for the App Part
if (typeof window.addEventListener != 'undefined') {
    window.addEventListener('message', processFrameEvent, false);

function LoadRibbon(Tab, message) {
    SP.SOD.executeOrDelayUntilScriptLoaded(function () {
        try {
            var pm = SP.Ribbon.PageManager.get_instance();
            pm.add_ribbonInited(function () {
                ribbonTab(Tab, message);
            var ribbon = null;
            try {
                ribbon = pm.get_ribbon();
            catch (e) { }
            if (!ribbon) {
                if (typeof (_ribbonStartInit) == "function")
                    _ribbonStartInit(_ribbon.initialTabId, false, null);
            else {
                ribbonTab(Tab, message);
        } catch (e)
        { }
    }, "sp.ribbon.js");
function ribbonTab(Tab, message) {
    var Ribbonhtml = "";
    Ribbonhtml += "<div><div><a href='#' onclick=\"alert('" + message + "')\" ><img src='/_layouts/images/NoteBoard_32x32.png' /></a><br/>Ribbon Example</div></div>";
    var ribbon = SP.Ribbon.PageManager.get_instance().get_ribbon();
    if (ribbon) {
        var tab = new CUI.Tab(ribbon, 'GlobalRibbon.Tab', Tab, 'Option', 'GlobalRibbon.Tab.Command', false, '', null);
        ribbon.addChildAtIndex(tab, 1);
        var group = new CUI.Group(ribbon, 'GlobalRibbon.Tab.Group', 'Custom Ribbon', 'Global Ribbon Example', 'GlobalRibbon.Group.Command', null);
    SelectRibbonTab('GlobalRibbon.Tab', false);
    $("span:contains('Custom Ribbon')").prev("span").html(Ribbonhtml);
    SelectRibbonTab('Ribbon.Read', true);

Add Javascript to Site Assets Library 

After the Javascript file is created recommend add in the Site Assets document Library.
This file will be used when the Custom Actions Scriptlink is created to be available in SharePoint Site.

Add Scriptlink reference to SiteRadar.js

After the file is created, you need to reference the Javascript File to the SharePoint site, you can make that using a Scriptlink Custom Action, the tool "Ribbon Manager App" can support you in this task. 

After you save the Custom action you will be able to see the custom actions in the View of the Ribbon Manager App. 

If you like to use Visual Studio and Declarative code you can use the option "Generate Declarative XML" to create the XML for your SharePoint Feature as shown.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="">
  <CustomAction Id="Site Radar" Title="Site Radar" Description="" Location="ScriptLink"ScriptSrc="~Site/SiteAssets/SiteRadata.js" Sequence="2" > </CustomAction>

You can use Internet Explorer Developer tools to validate if the file was included in the SharePoint Site.

Create AddRibbonListnerRadar app solution using Visual Studio

After the SiteRadar.js file is reference in the SharePoint Site, you can create a SharePoint App Solution and include 2 ClientWebPart to send content from the SharePoint Web to SharePoint Hosted from Iframes to customize the Ribbons.

Client App Part

Create 2 new Client Web Part using Visual Studio "Add Item> Client WebPart"

Add the following Javascript code in ClientWebpart1.aspx:
window.parent.postMessage('Option1;Option Select App Part1', document.referrer);

Add the following Javascript code in ClientWebpart2.aspx:
window.parent.postMessage('Option2;Option Select App Part2', document.referrer);

Client App Part web Part Schema Sctructure

Reduce the size of the Apps to minmal, change the default height and width to "0" by default the App has 200x300 and we dont want to show the app.

Deploy the App Solution to your SharePoint Site 

After the Schema is change, you are ready to deploy your sharePoint App solution to your SharePoint Site using the Right Click Solution "AddRibbonListnerRadar > Deploy" and deploy to SharePoint Site.

When you access to "Site Contents" in the SharePoint Site, you are are able to see the new App instaled in the SharePoint Hosted Site.

Deploy App Part in SharePoint Page
Access to SharePoint Page where you want to add the App Part with Custom Ribbon Customization and edit the Page to add the App Part
The App Part will be included in the page as hidden +/- because we define the site as 0 width and Heigth.
Do the same action and include "ClientWebPart1 Title" (eg: Page 1) and "ClientWebPart2 Title" (eg: Page 2) and the image bellow show the final result with 2 different Contents in the Ribbon.


Done, very easy to comunicate between SharePoint Host Site and SharePoint App Parts and this shouldn't be a reason to don't create App for SharePoint Sites.

Hope you like the article, 
Kind regards, 
André Lage

No comments: