Update: 10th June 2012
A few people have posted comments about the script not working for SharePoint 2010. This code was built for SharePoint 2007. However I have been through the code and an updated version can be found below.
Apologies that it has taken a while to respond.
The SharePoint 2010 Code version works slightly differently and uses the jQuery Live method and JavaScript OnMouseOver event to update the PDF’s a tags.
Introduction
One of our clients wanted a way to ensure that Adobe PDF’s did not open in the current browser window.
By default a PDF opened into Adobe Acrobat will open in the current browser window.
This presents a usability problem as user’s lose the reference to the site they were in also other applications, such as Word and Excel, do not behave in this way.
How Acrobat opens a document is controlled within the Acrobat client. Unfortunately to change this through a mechanism such as Group Policy is not a simple task and hence did not meet their timescales.
Just so you know, Acrobat’s PDF browser behaviour is adjusted here :-
- Open Acrobat Reader (C:\Program Files (x86)\Adobe\Reader 10.0\Reader\acrord32.exe)
- Click Edit->;;Preferences
- Choose Internet (down the left-hand side)
- Unselect “Display PDF in Browser”
- Click OK
;
Unfortunately this was not possible for the client, so I started to look at alternative solutions. First thing is that the client wanted something that was quick (the fix was required in a day) as they had committed to launching the internal site quickly. The requirement was for a single page and therefore the solution did not need to scale.
The idea that I came up with was to use jQuery to find the PDF hyperlinks on the page and then add a target attribute with a value of “_new”.
This was pretty straightforward and using a content editor web part the JavaScript was quickly added to the page to prove the approach.
;
Of course its never as simple as that and when this approach was tried then it worked well for a standard document library but the page had views that were grouping content by certain columns and the jQuery could not find the ; link to bind to.
When the grouping function is used on a view then the content within a group is lazy loaded using JavaScript functions within the init.js SharePoint library. So therefore the jQuery will not find the ; tags because they don’t exist yet.
One option I thought of was to try and run the code as late as possible. So I starting to look into how SharePoint JavaScript function were called. One thing I had noticed was how the content within a group was loaded in after the document had loaded.
Looking at the SharePoint JavaScript files I found init.js. SharePoint seems to add functions to an array called ‘_spBodyOnLoadFunctionNames’ using the function _spBodyOnLoadFunctionNames.push(). This array is passed into a function called “ProcessDefaultOnLoad()” within init.js. These functions are then called one at a time by looping through the array.
So another line within the $(document).ready() function was added :-
_spBodyOnLoadFunctionName.push(refreshPDFLinks());
However, this still didn’t work.
The grouping function when it expands a node updates the html to display these links to the various documents, so I wanted to find a way to bind to an event which would be called when changes to the html were made. After some more research I couldn’t find a way to throw an event which would work in IE and Firefox.
I then thought we’ll why don’t we delay the call to look for the PDF links by a second or two. The important thing was that the delay was an asynchronous call that did not block the other scripts from running.
In the end the setTimeout() JavaScript function was used. This function was bound to all the expanders for the document library. Fortunately with jQuery the binding was pretty straightforward with the line:-
$(documentLibExpGroup).bind('click', function(){ refreshPDFLinkTimeOut = setTimeout("refreshPDFLinks()",1500); });
This approach works though it is not great for the following reasons :-
- it is not scalable and need to be added to each page that the functionality is required for.
- the timeout needs to be long enough to load the PDFs but not so long so that the link is not updated in time.
Anyway with those caveats in mind here is:-
The SharePoint 2007 Source Code.
<script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.4.min.js"> </script> <script language"javascript" type="text/javascript"> /* PDF Link to new window function */ $(document).ready(function () { var refreshPDFLinkTimeOut=null; //bind function to document library expand events bindToDocumentLibraryEvents(); //_spBodyOnLoadFunctionNames.push("refreshPDFLinks"); refreshPDFLinks(); }); function bindToDocumentLibraryEvents() { var documentLibExpGroup=$("a[onclick*='ExpCollGroup']"); $(documentLibExpGroup).bind('click', function(){ refreshPDFLinkTimeOut = setTimeout("refreshPDFLinks()",2000); }); alert"Bound to " + documentLibExpGroup.length + " Document Lib Group Switch"); return true; } function refreshPDFLinks() { fixPDFUrls(); //var pdfTags = getPDFUrls(); //updatePDFUrls(pdfTags); //alert("Found " + pdfTags.length + " PDF Links"); return true; } function getPDFUrls() { var pdfUrlTags = $"a[onclick*='DispEx'][onfocus*='OnLink'][href*='pdf']"); var fixTags = new Array(); for (var i = 0; i <;; pdfUrlTags.length; i++) { fixTags.push($(pdfUrlTags[i])); } return fixTags; } function fixPDFUrls() { var pdfUrlTags = $("a[onclick*='DispEx'][onfocus*='OnLink'][href*='pdf']"); alert("Found " + pdfUrlTags.length + " PDF Links"); $(pdfUrlTags).live('click', function() {updatePDFUrls(this);}); return true; } function updatePDFUrls(pdfUrlTags) { for (var i = 0; i <;; pdfUrlTags.length; i++) { $(pdfUrlTags[i]).attr('target','_new'); } return true; } function updatePdfTargetUrl(e) { $(e).attr('target','_new'); return false; } /* PDF Link to new window function */ </script>
The SharePoint 2010 Source Code
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.7.1.min.js"> </script>; <script type="text/javascript" language="javascript"> /* /* PDF Link to new window function */ $(document).ready(function () { var refreshPDFLinkTimeOut=null; //bind function to document library expand events bindToDocumentLibraryGroupByEvents(); refreshPDFLinks(); }); function bindToDocumentLibraryGroupByEvents() { var documentLibExpGroup=$("a[onclick*='ExpCollGroup']"); $(documentLibExpGroup).live('mouseover', function(event){ refreshPDFLinkTimeOut = setTimeout("refreshPDFLinks()",2000); }); //alert("Bound to " + documentLibExpGroup.length + " Document Lib Group Switch"); return true; } function refreshPDFLinks() { fixPDFUrls(); return true; } function fixPDFUrls() { var pdfUrlTags = $"a[onclick*='DispEx'][onfocus*='OnLink'][href*='pdf']"); $(pdfUrlTags).live('mouseover', function (event) { updatePdfTargetUrl($(this)); }); return true; } //updates the tag, adding the _new property to the target to open new window // and disabling the SharePoint DispEx onclick function to stop the pdf from being opened in the current browser window. function updatePdfTargetUrl(e) { $(e).attr('target', '_new'); $(e).prop('onclick', null).attr('onclick',null); return false; } /* PDF Link to new window function */ </script>
Usage
To use this piece of JavaScript do the following:-
- Download the Source code JavaScript file
- Browse to the SharePoint page that you wish to add the PDF functionality to.
- Edit the SharePoint Page
- Add a Content Editor Web Part to the page
- Edit the Content Editor Web part and open its source view
- Open the source code file, copy the contents of the javascript
- Paste the contents in the Content Editor Web part’s source.
- Save the Web part and the Page
- Test out the functionality.
- If nothing happens then check that the jQuery library can be accessed as it uses the Microsoft AJAX site to get the appropriate version.
Great !!!
But the pdf is still open in the sharepoint window, and of course in a new window . I have change a little bit your code to solve this issue:
function updatePDFUrls(pdfUrlTags) {
for (var i = 0; i < pdfUrlTags.length; i++) {
$(pdfUrlTags[i]).removeAttr('onclick').attr("target","_blank");
}
return true;
}
This new code works fine for me.
Thks !!
Thanks for your comments and taking the time to post your alternative script. I dont remember the script opening two version of the PDF but then I haven’t tested this in SP2010 for a while!
I will take a look at your change over the weekend.
Regards
Simon
Why is such a basic feature not part of the standard options?
I’ve followed the discussion above and have the jquery file and the script in a ‘ScriptLibrary’ folder but when I go into my document library and double-click on a PDF it still opens in the same window.
What am I missing?
Hi Greg,
Which version of SharePoint are you using? Do you see any JavaScript errors in the status bar?
Simon
Hi All
I can’t get this to work in in SP 2010 when PDF’s are grouped. Works fine when not grouped. Has anyone been able to achieve this?
Regards,
Michael
Hi Michael,
Thanks for taking the time to post this issue. I haven’t looked at the code recently and have a bit of time this week and will look at the approach that I have taken for SharePoint 2010. This code was originally released for SharePoint 2007. I will update the post and be in touch when I have updated the code for SharePoint 2010.
Regards
Simon
Hi Michael,
I have taken a look at this for SharePoint 2010 and have updated the source code to work slightly differently now. Can you try again with the new version and let me know how you get on.
Regards
Simon
Hi Simon,
Thanks for looking into this – I will take a look and let you know.
Regards,
Michael
Hi Michael
No problem look forward to hearing how you get on.
Regards
Simon
Hi Simon – where is this new code you speak of? And one comment you made has me confused:
“If nothing happens then check that the JQuery library can be accessed as it uses the Microsoft AJAX site to get the appropriate version.”
My question is HOW do I do this – the code above doesn’t work for me so maybe this is the issue?
Hi Murray
There are two versions of the code the older SharePoint 2007 version and the new SharePoint 2010 version.
If you re read the post you will see that the two different code bases are marked.
The code uses a copy of the jQuery library which is hosted by Microsoft on their Ajax site.
This is the line that has the line
If the machine that you are trying this out on is on a corporate network with strict policies then the machine might not be able to access the site.
If that’s the case then you will need to store a copy of the jQuery on your SharePoint farm. I suggest this is a path under the /_layouts folder such as /_layouts/jquery.js so that it can be shared. The script link should then be updated to point to that local location.
Hope that helps
Regards
Simon
Reblogged this on iThink SharePoint and commented:
Updated with SharePoint 2010 Version of Script
Hi Simon – did you get my email to simon@ithinksharepoint I sent last week? I had to send there as I could not paste screenshots into this forum…
Can this script be modified to work with xml files?
Juli,
I dont see why not though it depends on the application that is going to display the XML files. What are you looking to do?
Regards
Simon
HI Simon,
The download link for 2010 is broken. Could you please confirm and correct the same?
THanks
Mahesh
Hi Mahesh,
Thanks for taking the time to let me know. Looks like its back up, looks like there was an issue with my other hosting provider but all up and running now. Let me know if you need any further help.
Regards
Simon
Hmm is anyone else having problems with the images on this blog loading?
I’m trying to determine if its a problem on my end or if it’s the blog.
Any suggestions would be greatly appreciated.
Hi thanks for taking the time to post a comment about the issue with images. When I checked last night it all seemed to be working fine.
Please let me know if you are still having troubles.
Regards
Simon
Hi Simon,
Its a nice blog. I used http://images.ithinksharepoint.com/itspblog/images/Opening_131AA/itsp.sharepoint2010.openpdf.txt script, its working fine for normal library files. But for the files in Project sets, its not working. Let me know if any changes are required in the script.
Hi,
do you mean document sets? I haven’t tried the script on those. I would imagine it would work with a bit of tweaking.
Can’t promise that I will look immediately but will try and take a look over the next couple of weeks.
Regards
Simon
Yes Simon, I am looking for document sets also.
Present script is not working for files in document sets. I will be waiting for new script.
Regards,
Venkat
Hi Venkat,
Like I said in previous comment, you might be waiting a while. Why not have a go and see if you can tweak the script to what you want?
Regards
Simon
[…] https://blog.ithinksharepoint.com/2011/02/21/open-pdf-files-from-a-document-library-in-a-new-window/ […]
Hi Simon,
Thanks a lot for this excellent post. I was wondering if you could tweak the script to work with SharePoint 2013 ?
Thanks
Paul
A small tip, if you’re using JQuery version over 1.7, method “.live()” was deprecated for versions over 1.7. JQuery suggest use “.on()” method instead of.
Thanks for the tip – one of the issues with having old code on your blog I suppose.
Hello, I am using SP2013 and got a Document Library filled up with .docx and .pdf > currently the docx are opening either in edit or read mode but the pdf opens straight in the current browser – which is ok if the library is opened as a full page but I use the dialog box option and is very irritating. I tried the code but did not work in my case 😦 suggestions?
Hi
Sorry I never had a look at this for 2013. The problem is that the markup that the JavaScript is looking for will have changed.
Have you got Office Web App Server? I would suggest looking at configuring that for viewing PDFs so you get a similar experience as you do for Word.
See Wictor’s post for more information
http://www.wictorwilen.se/sharepoint-2013-enabling-pdf-previews-in-document-libraries-with-office-web-apps-2013
Regards
Simon