RSS
Twitter
LinkedIn

 

SharePoint 2013 - Custom CallOut with File Preview

In addition to the standard 'Modal Dialog' windows in SharePoint 2010, SharePoint 2013 introduced new 'Call Out' windows.

There are plenty of good posts out there detailing how to implement and utilise the new 'Call Out Framework' ('callout.js')

..to name just a few.

However, I was surprised to find that none provided a working example of the 'File Preview' layout which is used in the 'Call Outs' of standard Document Libraries.

 

So here's a working example of how it can be implemented....

 

function getCallOutFilePreviewBodyContent(urlWOPIFrameSrc, pxWidth, pxHeight) {
    var callOutContenBodySection = '<div class="js-callout-bodySection">';
    callOutContenBodySection += '<div class="js-filePreview-containingElement">';
    callOutContenBodySection += '<div class="js-frame-wrapper" style="line-height: 0">';
    callOutContenBodySection += '<iframe style="width: ' + pxWidth + 'px; height: ' + pxHeight + 'px;" src="' + urlWOPIFrameSrc + '&amp;action=interactivepreview&amp;wdSmallView=1" frameborder="0"></iframe>';
    callOutContenBodySection += '</div></div></div>';

    return callOutContenBodySection;
}

 

function OpenItemFilePreviewCallOut(sender, strTitle, urlWopiFileUrl) {
    RemoveAllItemCallouts();
    var openNewWindow = true; //set this to false to open in current window
    var callOutContenBodySection = getCallOutFilePreviewBodyContent(urlWopiFileUrl, 379, 252);
    var c = CalloutManager.getFromLaunchPointIfExists(sender);
    if (c == null) {
        c = CalloutManager.createNewIfNecessary({
            ID: 'CalloutId_' + sender.id,
            launchPoint: sender,
            beakOrientation: 'leftRight',
            title: strTitle,
            content: callOutContenBodySection,
            contentWidth: 420
        });

        var customAction = new CalloutActionOptions();
        customAction.text = 'Open';
        customAction.onClickCallback = function (event, action) {
            if (openNewWindow) {
                window.open(urlItemUrl);
                RemoveItemCallout(sender);
            } else {
                window.location.href = urlItemUrl;
            }
        };

        var _newCustomAction = new CalloutAction(customAction);
        c.addAction(_newCustomAction);
    }

    c.open();
}

 

 

The above function "OpenItemFilePreviewCallOut" could then be used as follows:

 

<a id="CallOutExample" onclick="OpenItemFilePreviewCallOut(this, 'My Title','<WopiFileUrl>')" title="CallOut With File Preview" h ref="#">
Call Out with File Preview</a>

 

Where the "<WopiFileUrl>" parameter is provided in the format:

"https://yoursite.sharepoint.com/_layouts/15/WopiFrame2.aspx?sourcedoc=<SPFile Relative Url>"

 

 

Probably also worth mentioning that both the '_layouts/15/WopiFrame2.aspx' and the '<SPFile Relative URL>' need to refer to the same SPWeb

Correct Example:
https://yoursite.sharepoint.com/TeamSite1/_layouts/15/WopiFrame2.aspx?sourcedoc=/TeamSite1/Shared Documents/test1.docx

Incorrect Example:
https://yoursite.sharepoint.com/_layouts/15/WopiFrame2.aspx?sourcedoc=/TeamSite1/Shared Documents/test1.docx

 

...and if you're wondering why I've referred to 'WopiFrame2.aspx' (instead of 'WopiFrame.aspx') above - see the following explanation from Wictor Wilén:

http://www.wictorwilen.se/an-explanation-to-to-start-seeing-previews-please-log-on-by-opening-the-document-in-sharepoint-2013

 


Finally, here are a few helper functions which can be used to Close and/or Remove existing Call Outs:
(fyi - the 'RemoveAllItemCallouts' and 'RemoveItemCallout' functions are called/used in the 'OpenItemFilePreviewCallOut' example above)


function RemoveAllItemCallouts() {
    CalloutManager.forEach(function(callout) {
        // remove the current callout
        CalloutManager.remove(callout);
    });
}

function RemoveItemCallout(sender) {
    var callout = CalloutManager.getFromLaunchPointIfExists(sender);
    if (callout != null) {
        // remove
        CalloutManager.remove(callout);
    }
}

function CloseItemCallout(sender) {
    var callout = CalloutManager.getFromLaunchPointIfExists(sender);
    if (callout != null) {
        // close
        callout.close();
    }
}

 

 

Happy Coding....

 

 

Published by aobi

Comments

 

Jane said:

Thanks for filling the gap.

February 24, 2014 1:03 PM
 

Jim Bury said:

This was exactly what I needed and very much appreciated. Is there any way to get the default footer actions back into the footer instead of a static "Open"?

Thanks,

Jim

January 16, 2015 2:14 AM
 

aobi said:

Glad you found it useful Jim.

I believe you have to re-create the default footer actions accordingly unfortunately...

See MSDN link listed at top of this post, or gluckdavid.wordpress.com/.../callouts

January 16, 2015 6:02 PM
 

Torben said:

Thanks for this very useful tutorial. I am however getting "Uncaught TypeError: Cannot read property 'stop' of null" on the very first launch after page refresh. All subsequent launches are fine.

This seems to happen during the

CalloutManager.remove(callout);

call and i haven't found a way around it. Any clue on this?

December 1, 2015 11:15 AM
 

aobi said:

Glad you found it useful Torben,

Haven't come across that particular error myself.

But can I suggest ensuring "callout.js" has loaded correctly.

For example, try using 'SP.SOD.executeFunc'

msdn.microsoft.com/.../ff409592%28v=office.14%29.aspx

Believe it should be something along the lines of

SP.SOD.executeFunc("callout.js", "Callout", function () {});

December 1, 2015 7:43 PM
 

dee said:

Thanks for the article.

Is there a way to use wopiframe.aspx in embedview mode but have the in page links clickable?

embedview does not have links on the document clickable.

December 22, 2015 5:20 PM
 

aobi said:

Glad you found it useful Dee.

Don't know of a way of enabling hyperlinks in embedview mode unfortunately though

social.technet.microsoft.com/.../wopi-frame-issues-on-the-bread-crumb

December 22, 2015 8:51 PM
 

Angie said:

Thank you SO much for sharing!  

Could you please tell me where the urlItemUrl is set?  

Thanks again

Angie

August 4, 2016 10:13 PM