Connected SharePoint App Parts
Last year I authored a post on using SharePoint 2013's embed code web part as an alternative to custom app parts. The embed code approach has the advantage of not using IFRAMEs, but isn’t repeatable, relies on the client for all application logic, and eliminates the use of server-side technologies like ASP.NET and MVC. But is the fact that app parts use IFRAMEs really that bad? IFRAMEs provide a nice security boundary/sandbox and doesn't mean the user experience has to be compromised. You see, apps parts can reference styling from the host web and can even communicate to the host web for resizing. But can they support complex web part capabilities such as connections with other app parts? In this post, I will outline an approach to communicate between app parts using HTML5 technologies that should work in any modern browser.
[View:https://www.youtube.com/watch?v=QLQWVOWmTEo]
Window/IFRAME Communication
The HTML5 postMessage API enables sending data between windows/IFRAMES, even across domains. This is the same method used by SharePoint for resizing app parts and communication to/from pages displayed in the SharePoint dialog. The postMessage API is a safe approach to cross-domain communication because the window/IFRAME must explicitly "listen" for messages, else they are ignored.
Listening for messages between window/IFRAME is identical and uses the script window.addEventListener as seen below:
Listening for message
if (typeof window.addEventListener != 'undefined') { window.addEventListener('message', processMessage, false);} |
Posting messages between window/IFRAME is slightly different. From the IFRAME, you call window.parent.postMessage and from the host page you post to the IFRAME by calling the script iframe.contentWindow.postMessage as seen below:
postMessage from IFRAME to parent page
window.parent.postMessage(message, document.referrer); |
postMessage from parent page to IFRAME
document.getElementById('myIframe').contentWindow.postMessage(data, '*'); |
Applying to App Parts
In order to get app parts communicating with each other, the host page needs script to broker all the communication between app parts. This can be achieved with the new Script Editor web part, but I prefer the Content Editor, as it can be exported with our script and re-imported into the web part gallery for reuse. This allows an average end-user (who has no business messing with script) to place the elements on the page. In this host page script, I use JQuery to find all the app parts to post messages to:
Finding all App Parts on page
$('.ms-WPBody').find('iframe').each(function (i, e) { e.contentWindow.postMessage(data, '*');}); |
Conclusion
I’m actually not a big fan of connected web part as I think they are too complex for the average end-user to configure. However, this post was more about illustrating the flexibility of app parts even though they are loaded in IFRAMEs. The complete solution used in this post (and video) is available HERE.
Comments
Anonymous
May 11, 2014
Hi, Thanks for sharing this useful information If the source of one of the Iframes comes from another domain then contentWindow.body throws "access denied" how do I solve it.Anonymous
May 13, 2014
The comment has been removedAnonymous
August 25, 2014
the main challenge with iFrames is responsive design