So you want to have total control over how a PDF opens in SharePoint? You're probably like me in that your implementation has Office Web Apps (OWA), and your organization is using Firefox, IE, maybe Safari and Chrome.
All these browsers have different ways of handling PDFs, with OWA having another method on top of all that. But if you want to take advantage of signing / active forms in PDFs, you'll need to force SharePoint to use the Adobe client to open the files.
Luckily, there's an easy way to do this. Javascript to the rescue.
First, take the Javascript below, save it as pdffix.js, and put it in the C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\TEMPLATE\LAYOUTS directory of each Web Front End server on your farm:
(function () {
if (typeof SPClientTemplates === 'undefined')
return;
var PdfCtx = {};
PdfCtx.Templates = {};
PdfCtx.Templates.Fields = { 'LinkFilename': { 'View': PdfClientLinkFilenameNoMenu } };
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(PdfCtx);
})();
function GetExtension(szHref) {
var sz = new String(szHref);
var re = /^.*\.([^\.]*)$/;
return (sz.replace(re, "$1")).toLowerCase();
}
var stsOpen = null;
function IsPdfClientInstalled() {
if (stsOpen == null) {
if (Boolean(window.ActiveXObject)) {
try {
stsOpen = new ActiveXObject("PdfFile.OpenDocuments");
}
catch (e) {
stsOpen = null;
}
}
}
return (stsOpen != null);
}
function OpenPdfInClient(pdfFileUrl) {
var fRet = true;
try {
fRet = typeof stsOpen.ViewDocument2 != "undefined" && stsOpen.ViewDocument2(window,
pdfFileUrl, '');
}
catch (e) {
fRet = false;
};
if (event != null) {
event.cancelBubble = true;
event.returnValue = false;
}
return fRet;
}
function PdfNewGif(listItem, listSchema, ret) {
if (listItem["Created_x0020_Date.ifnew"] == "1") {
var spCommonSrc = GetThemedImageUrl("spcommon.png");
ret.push("<span class=\"ms-newdocument-iconouter\"><img class=\"ms-newdocument-icon\"
src=\"");
ret.push(spCommonSrc);
ret.push("\" alt=\"");
ret.push(Strings.STS.L_SPClientNew);
ret.push("\" title=\"");
ret.push(Strings.STS.L_SPClientNew);
ret.push("\" /></span>");
}
}
function PdfClientLinkFilenameNoMenu(param1, param2, listItem, listSchema) {
var ret = [];
var fileUrl = listItem.FileRef;
if (fileUrl != null && typeof fileUrl != 'undefined' && TrimSpaces(fileUrl) != "") {
if (listItem.FSObjType == '1') {
if (listSchema.IsDocLib == '1') {
RenderDocFolderLink(ret, listItem.FileLeafRef, listItem, listSchema);
}
else {
RenderListFolderLink(ret, listItem.FileLeafRef, listItem, listSchema);
}
}
else {
ret.push("<a class='ms-listlink' href=\"");
ret.push(listItem.FileRef);
ret.push("\" onmousedown=\"return VerifyHref(this,event,'");
ret.push(listSchema.DefaultItemOpen);
ret.push("','");
ret.push(listItem["HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon"]);
ret.push("','");
ret.push(listItem["serverurl.progid"]);
ret.push("')\" onclick=\"");
var appInstalled = IsPdfClientInstalled();
var szExt = GetExtension(listItem.FileRef);
if (appInstalled && szExt == 'pdf' && browseris.ie) {
ret.push("return OpenPdfInClient('");
ret.push("http://");
ret.push(window.location.hostname);
ret.push(listItem.FileRef);
}
else {
ret.push("return DispEx(this,event,'TRUE','FALSE','");
ret.push(listItem["File_x0020_Type.url"]);
ret.push("','");
ret.push(listItem["File_x0020_Type.progid"]);
ret.push("','");
ret.push(listSchema.DefaultItemOpen);
ret.push("','");
ret.push(listItem["HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon"]);
ret.push("','");
ret.push(listItem["HTML_x0020_File_x0020_Type"]);
ret.push("','");
ret.push(listItem["serverurl.progid"]);
ret.push("','");
ret.push(Boolean(listItem["CheckoutUser"]) ? listItem["CheckoutUser"][0].id :
'');
ret.push("','");
ret.push(listSchema.Userid);
ret.push("','");
ret.push(listSchema.ForceCheckout);
ret.push("','");
ret.push(listItem.IsCheckedoutToLocal);
ret.push("','");
ret.push(listItem.PermMask);
}
ret.push("')\">");
var fileRef = listItem["FileLeafRef"];
if (fileRef != null) {
var index = fileRef.lastIndexOf('.');
fileRef = index >= 0 ? fileRef.substring(0, index) : fileRef;
}
ret.push(fileRef);
ret.push("</a>");
PdfNewGif(listItem, listSchema, ret);
}
}
else {
ret.push("<nobr>");
ret.push(listItem["FileLeafRef"]);
ret.push("</nobr>");
}
return ret.join('');
}
****
Now, we Powershell.
Run the following Powershell commands, on a per-Library basis, to force PDFs to use this Javascript to open the files in the client.
add-pssnapin microsoft.sharepoint.powershell
$web = Get-SPWeb http://somesharepointsite.com/sites/teamsite
$list = $web.Lists["My PDF Documents"]
$field = $list.Fields.GetFieldByInternalName("LinkFilename")
$field.JSLink = "/_layouts/15/PdfFix.js"
$field.Update($true)
***
Once that script runs, it'll be active. No need to IIS reset or recycle application pools.
ONE IMPORTANT NOTE: You're dumping customizations directly to the /15 hive. This means Cumulative Updates / Service Packs will ALMOST CERTAINLY break this function.
We had the unfortunate experience of enabling this, then immediately patching to the May Cumulative Update the following weekend. We had to re-run the Powershell script to re-enable the function (the .js file was not deleted).
This is not working Edge, Chrome and another, only IE.
ReplyDelete