I have a requirement for a webapp to implement the following behavior:
After a webform is opened with an embedded PDF object is shown in the browser the user needs to be able to select a text in the document with a ctrl + mouse click after which the selected text is copied to an inputfield in the same webform that the embedded PDF object is shown.
Are there API's out there (preferably open source) that implement this behavior? Can I meet this requirement using techniques like JSP, JSF, PrimeFaces, Javascript or HTML5 and how would I do that?
In the example I'll use
Steps:
Download PDF.js, after the download is complete unzip it, you would see the following folder hierarchy
.
├── LICENSE
├── build
│ ├── pdf.js
│ └── pdf.worker.js
└── web
├── cmaps/
├── compatibility.js
├── compressed.tracemonkey-pldi-09.pdf
├── debugger.js
├── images/
├── l10n.js
├── locale/
├── viewer.css
├── viewer.html
└── viewer.js
Assuming you have a JSF project with a resources
folder inside webapp
, copy the following files from web folder (from the unziped file) into resources
in which they would look like this :
webapp/resources folder
├── css
│ └── viewer.css (web/viewer.css)
├── images
│ └── pdfjs
│ ├── ** All the images inside (web/images)
└── js
└── pdfjs
├── compatibility.js (web/compatibility.js)
├── l10n.js (web/l10n.js)
├── pdf.js (web/pdf.js)
├── pdf.worker.js (web/pdf.worker.js)
└── viewer.js (web/viewer.js)
Edit viewer.css to resolve all the required images, replace each url
with
"#{resource['images/pdfjs/correspondingImageName']}"
here's a full resolved viewer.css
Create xhtml file with the content of viewer.html
(web/viewer.html from zip), which would represent the viewer markup, the reason that I'de use the viewer with all the html 5 markup is the ability to select text, not like the canvas only example
Here's a full copied example of viewer.html
into viewer.xhml
Notice in the end I've included the libraries in the following order:
<h:outputScript name="js/pdfjs/compatibility.js" target="head" />
<h:outputScript name="js/pdfjs/l10n.js" target="head" />
<h:outputScript name="js/pdfjs/pdf.js" target="head" />
<h:outputScript name="js/pdfjs/viewer.js" target="head" />
To get PDF.js
running you need to specify two things, the pdf.worder.js
location and the pdfURL
(see in viewer.xhml)
<script>
var DEFAULT_URL = "#{pdfURL}"; //pdf should be hosted on your domain name (ajaxly loaded)
PDFJS.workerSrc = "#{resource['js/pdfjs/pdf.worker.js']}";
</script>
Define an inputText
or inputTextArea
<p:inputTextarea id="inputTextArea" />
Now register an event of keydown or whatever that fit, example:
$('.pdfZone').keydown(function(event) {
if (event.which == "17"){ // CTRL key
$('#inputTextArea').text(window.getSelection().toString())
}
});
.pdfZone
is a div
container of the pdf viewer
You can find a full example on github [1] [2], and an online Demo.
Note: I didn't use CTRL + Click because in my Mac OSX would trigger the Right Click, anyhow you could change the event handling.
Suggestion to use CTRL + Click (but the demo would use only CTRL)
$('.pdfZone').on('mouseup',function(e) {
if (e.ctrlKey) {
$('#inputTextArea').text(window.getSelection().toString());
}
});