Automatically resize SharePoint App Parts Iframe in AngularJS

facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

The Problem: Iframes do not resize height or width automatically

Regardless of the hosting type of your SharePoint app (SharePoint Hosted or Provider Hosted), when using App Parts, the SharePoint’s host web site will display your app content/page inside an iframe. Iframes need a static width and height to be set. The static width and height for your iframe is first set in your App Part elements.xml file. This is problematic because it would often cause unnecessary horizontal and vertical scroll bars around your app part.

<ClientWebPart Name="Slack for SharePoint" Title="Slack for SharePoint"  DefaultWidth="300" DefaultHeight="200">

Now, if your SharePoint App Part displays any content dynamically (Async calls, DOM manipulation, etc), its window size will change but unfortunately its container iframe will not. I ran into this issue while developing a SharePoint online app (Slack for SharePoint). There are multiple articles online explaining in detail the issue and resolution to this problem but I could not find a reusable AngularJS solution that would work without listening to events.

The Solution: Automatically Resize Iframe when DOM content changes

It all comes down to leveraging HTML5’s post message to communicate with the parent window hosting the app part iframe.

window.parent.postMessage('<message senderId=12345ABCD>resize(100%,800px)</message>', '*'); 

From the example above, senderId is the app part id sent to your app page as a query string parameter, 100% is the desired width and 800px is the desired height. Now, to automatically resize your SharePoint app part when your window size changes, you would need to listen to the window resize event, calculate your new height and send the message to the parent window. Not too shabby right? Except that window resize only trigger when your browser window is manually resized, not when content is loaded. If you are using AngularJS, I created a directive that will check your app container’s height on every $digest cycle, in other words, every time your content changes, and automatically resize the parent iframe.

 <ng-app-frame minheight="80">
.directive('ngAppFrame', ['$timeout', '$window', function ($timeout, $window) {

    return {
        restrict: 'E',
        link: function (scope, element, attrs) {

            element.css("display", "block");
            scope.$watch
            (
                function () {
                    return element[0].offsetHeight;
                },
                function (newHeight, oldHeight) {

                    if (newHeight != oldHeight) {
                        $timeout(function () {
                            var height = attrs.minheight ? newHeight + parseInt(attrs.minheight) : newHeight;
                            var id = getQsParam("SenderId")
                            var message = "<message senderId=" + id + ">resize(100%," + height + ")</message>";
                            $window.parent.postMessage(message, "*");
                        }, 0);// timeout needed to wait for DOM to update
                    }
                }
            );
        }
    };

Hope this helps anyone!

facebooktwittergoogle_plusredditpinterestlinkedinmailby feather
Posted in Office 365, SharePoint, SharePoint 2013, SharePoint Online Tagged with: , , ,
3 comments on “Automatically resize SharePoint App Parts Iframe in AngularJS
  1. I’m trying to make this work on a regular sharepoint iFrame web part. I’m probably doing something wrong, where should I put the snippet of code and how?

  2. Marcus, this solution is specific to SharePoing Apps. It depends on the senderId query string parameter. For Regular iframes you would need to bind to a windows resize event and/or iframe load to calculate width and height dynamically. If you are using the page viewer web part for your iframe this might help you: http://sharepointcore.blogspot.com/2011/08/sharepoint-pageviewer-webpart-resize.html

  3. Thank you for your answer, though I realised the issue was cross-domain. The iFrame contains pages from an old intranet and a system that at the time won’t be converted to Sharepoint.. any clues on how to read the height on the iFramed page even though it’s on another server?
    Best regards, M

Leave a Reply

Your email address will not be published. Required fields are marked *

*