SharePoint Pals
 | Sign In
How to create connected SharePoint Hosted App Part using Visual Studio
by Manoj Kumar Mittal 15 Mar 2015
Author
Visits   
Today  :   1     Total  :    5970

As SharePoint developers very well know, data can be shared between web part using SharePoint 2010 using standardized set of interfaces called connection interfaces that allowed Web Parts to exchange information with each other at run time.

More info on creating a Connectable Web Part can be found here

In the new SharePoint App model, web parts are replaced with app parts. The problem is they don't have an equivalent to Web Part Connections. So how can you pass parameters from one part to another? 

To answer this you have to consider several things:

1. App parts are basically small applications that are presented in your SharePoint site through Iframes

2. Each app is running in a separate domain and so are their app parts. Because of this any direct manipulation through some JavaScript code is out of the question because it would mean cross-domain scripting and all you would get is an "access denied" message

Thankfully there is a solution for this that is provided through HTML5, post Message and Event Listener method.

http://msdn.microsoft.com/en-us/library/windows/apps/hh441295.aspx

http://msdn.microsoft.com/en-us/library/ie/ff975245(v=vs.85).aspx

These method provides a way for communicating between browsing contents in HTML documents.
To demonstrate this I will take one scenario i.e.

I will create two SharePoint Hosted AppPart using Visual Studio, First one is Sender App and second one is Receiver App

Both Apps having Client Web Part (Host Web) and List Definition with default data

SenderSHAppPart having List Employee Data

ReceiverSHAppPart having List Department Data

image

                                Fig 1.1

Create Sender SharePoint Hosted App using Visual Studio

Project Structure as per below Fig 1.2

Right Click on the Project and Add two new items: - Custom List name Employee Data and Client Web Part name SenderAppPart.

image

Fig1.2

Adding Default Data to List

image

image

 

Fig 1.3

Add HTML and Script to SenderAppPart.aspx

 <script type="text/javascript">
   
   'use strict';
   
   function OnChange() {
     
     var myindex = D1.selectedIndex
         
         var SelValue = D1.options[myindex].text
             
             var appMsg = {
               
               SelValue: SelValue
               
             }
     ;
   
   window.parent.postMessage(appMsg, "*");
   
   return true;
   
 }
   
 </script>

HTML

 <div id="Success">
   
   <select class="select" id="select-reviewer" name="D1" onchange='OnChange();'>
   </select>
   
 </div>
 
 <div id="error">
   
 </div>

Add Script file SendData.js to Script folder and refer it in SenderAppPart.aspx

   'use strict';
   
   var hostweburl;
   
   var appweburl;
   
   var employeeData;
   
   // This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
   
   $(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.Runtime.js",
               
               function () {
                 
                 $.getScript(scriptbase + "SP.js",
                             
                             function () {
                               $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);
                             }
                             
                            );
                 
               }
               
              );
   
 }
                  );
   
   // This function prepares, loads, and then executes a SharePoint query to get the current users information
   
   // Function to prepare and issue the request to get
   
   //  SharePoint data
   
   function execCrossDomainRequest() {
     
     // context: The ClientContext object provides access to
     
     //      the web and lists objects.
     
     // factory: Initialize the factory object with the
     
     //      app web URL.
     
     var context = new SP.ClientContext(appweburl);
     
     var factory =
         
         new SP.ProxyWebRequestExecutorFactory(
           
           appweburl
           
         );
   
   context.set_webRequestExecutorFactory(factory);
   
   //Get the web and list objects
   
   //  and prepare the query
   
   var web = context.get_web();
   
   var list = web.get_lists().getByTitle("EmployeeData");
   
   var camlString =
       
       "<View><ViewFields>" +
       
       "<FieldRef Name='Title' />" +
       
       "<FieldRef Name='DepartmentId' />" +
       
       "</ViewFields></View>";
   
   var camlQuery = new SP.CamlQuery();
   
   camlQuery.set_viewXml(camlString);
   
   employeeData = list.getItems(camlQuery);
   
   context.load(employeeData, "Include(Title , DepartmentId)");
   
   //Execute the query with all the previous
   
   //  options and parameters
   
   context.executeQueryAsync(
     
     successHandler, errorHandler
     
   );
   
 }
   
   // Function to handle the success event.
   
   // Prints the data to the page.
   
   function successHandler(data, req) {
     
     var enumerator = employeeData.getEnumerator();
     
     while (enumerator.moveNext()) {
       
       var employeedetail = enumerator.get_current();
       
       var departmentId = employeedetail.get_item("DepartmentId");
       
       var employeeName = employeedetail.get_item("Title");
       
       populateUsersDropDown(employeeName, departmentId);
       
     }
   
 }
   
   function populateUsersDropDown(employeeName, departmentId) {
     
     $('#select-reviewer').append("<option value='" + departmentId + "'>" +
                                  
                                  employeeName + "</option>");
   
 }
   
   // Function to handle the error event.
   
   // Prints the error message to the page.
   
   function errorHandler(data, error, errorMessage) {
     
     document.getElementById("error").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];
     
   }
   
 }

Create Receiver SharePoint Hosted App using Visual Studio

image

Fig 1.4

image

Fig 1.5

Add div tags to Receiver App Part

 <div id="divMessages" style="color:#f00"></div>
 
 <div id="renderDepartment"></div>

Add Script file GetData.js to Script folder and refer it in ReceiverAppPart.aspx

 'use strict';
 
 var departmentId;
 
 var hostweburl;
 
 var appweburl;
 
 var allDepartmentId;
 
 // This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
 
 $(document).ready(function () {
 
 window.addEventListener("message", receiveMessageInApp, false);
 
 function receiveMessageInApp(event) {
   
   var divMsg = document.getElementById('divMessages');
   
   departmentId = event.data;
   
   //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.Runtime.js",
 			  
 			  function () {
 				
 				$.getScript(scriptbase + "SP.js",
 							
 							function () {
 							  $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);
 							}
 							
 						   );
 				
 			  }
 			  
 			 );
   
 }
 
 }
 			   );
 
 // This function prepares, loads, and then executes a SharePoint query to get the current users information
 
 // Function to prepare and issue the request to get
 
 //  SharePoint data
 
 function execCrossDomainRequest() {
 
 // context: The ClientContext object provides access to
 
 //      the web and lists objects.
 
 // factory: Initialize the factory object with the
 
 //      app web URL.
 
 var context = new SP.ClientContext(appweburl);
 
 var factory =
 	
 	new SP.ProxyWebRequestExecutorFactory(
 	  
 	  appweburl
 	  
 	);
 
 context.set_webRequestExecutorFactory(factory);
 
 //Get the web and list objects
 
 //  and prepare the query
 
 var web = context.get_web();
 
 var list = web.get_lists().getByTitle("DepartmentData");
 
 var camlString ="<View>" +
 "<Query>" +
 "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + departmentId + "</Value></Eq></Where>" +
 "</Query>" +
 "<ViewFields>" +
 "<FieldRef Name='Title' />" +
 "<FieldRef Name='DepartmentName' />" +
 "</ViewFields>" +
 "</View>";
 								
 var camlQuery = new SP.CamlQuery();
 
 camlQuery.set_viewXml(camlString);
 
 allDepartmentId = list.getItems(camlQuery);
 
 context.load(allDepartmentId, "Include(Title , DepartmentName)");
 
 //Execute the query with all the previous
 
 //  options and parameters
 
 context.executeQueryAsync(
   
   successHandler, errorHandler
   
 );
 
 }
 
 // Function to handle the success event.
 
 // Prints the data to the page.
 
 function successHandler(data, req) {
 
 var enumerator = allDepartmentId.getEnumerator();
 
 while (enumerator.moveNext()) {
   
   var department = enumerator.get_current();
   
   var departmentTitle = department.get_item("Title");
   
   var departmentDescription = department.get_item("DepartmentName");
   
   divMessages.innerHTML = departmentDescription;
   
 }
 
 }
 
 // Function to handle the error event.
 
 // Prints the error message to the page.
 
 function errorHandler(data, error, errorMessage) {
 
 document.getElementById("renderDepartment").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];
   
 }
 
 }

Deploy both the Apps and browse you share point Team site.

Create one new site page i.e. CreateConnection.aspx and browse and edit the page. Click on Add Web Part and select Script Editor Web Part

Add Script Editor WebPart

 <script>
   
   window.addEventListener("message", receiveMessage, false);
   
   function receiveMessage(event){
     
     procesHello(event.data.msg);
     
   }
   
   function procesHello(msgData){
     
     var iFrame = document.getElementsByTagName("iframe")[1];
     
     
     iFrame.contentWindow.postMessage(msgData,"*");
     
   }
   
 </script>

Add AppPart i.e. Sender AppPart Title and Receiver AppPart Title.

Click on Stop editing with happy ending!!

blog comments powered by Disqus

SharePoint Pals

Pals
SharePoint Pals, a community portal for SharePoint developers, Administrators and End Users. Let's join hands and share the point together.
Read this on mobile

Training

Angular Js Training In Chennai
Advanced Angular Js training with real world developer scenarios
Angular Js, Web Api and Ionic for .Net Developers
All in one client side application development for .Net developers
Angular Js For SharePoint Developers
Get ready for the future. Its no more just C#

Get Connected

SharePoint Resources

SharePoint 2013 and 2010 Web Parts
Free Web Parts with Source Code for SharePoint Community




SharePoint 2013 Books and Tutorials
Collection of free SharePoint 2013 books and tutorials (eBooks, pdfs)

Supported By

Contribute your article and be eligible for a one month Free Subscription for Plural Sight. The Author of the most popular New Article (published in the previous month) will be awarded with a Free One month Plural Sight Subscription. Article can be sent to articles@sharepointpals.com in a word document.

Related Resources

Recent Tweets

Twitter January 15, 00:25
How To Enable Target Value And Actual Value In #D3 Gauge Chart https://t.co/VxSi4QnNrC

Twitter January 15, 00:24
How To Open #SharePoint List Hyperlink Column In Modal #Popup Window https://t.co/EQ7HkoZDkX

Twitter January 15, 00:24
Quick Introduction To #Asp.NetCore And It’s Features https://t.co/zAXObHCFpH

Twitter January 15, 00:22
How To Configure #PerformancePoint Services To Use Secure Store In #SharePoint 2013 https://t.co/LEwnUoI7EY

Twitter January 15, 00:21
How To Block Or Disable #Office365 Services https://t.co/Yvp2VPFIRP

Follow us @SharePointPals
Note: For Customization and Configuration, CheckOutRecent Tweets Documentation