Force PDF.js viewer

I’m trying to force the use of the PDF.js viewer via PDFObject, instead of the browser’s integrated viewer, as stated here.

I enabled “Embed PDF documents” in the advanced settings. Downloaded the PDF.js library and installed in /pdfjs.
Added to the page’s client script:

ew.PDFObjectOptions = {
    forcePDFJS: true,
    PDFJS_URL: "/pdfjs/web/viewer.html"
};

It works (showing the PDF where intended), but apparently it’s just using the browser’s integrated viewer, as I get a different viewer for each browser. I think the forcePDFJS directive is being ignored.
I’m getting no errors (even in debug no messages or exceptions), so I don’t know how to pinpoint the problem. Any takers?

The viewer.html uses:

<script src="../build/pdf.mjs" type="module"></script>

Make sure you have uploaded the “build” folder to the correct location also.

The path PDFJS_URL: "/pdfjs/web/viewer.html" is absolute, make sure you upload the pdfjs to the correct location (i.e. the root of your site).

Build folder is present and path is absolute and correct.
I dug deeper and added a console.log(options) to /js/pdfobject.js, below this line:

    let embed = function(url, targetSelector, options){

found out that options are always undefined. I think the problem lies in function initPdfObjects(e) in /js/ew.js.

You may post your complete code for discussion.

Also press F12 in your browser, check if there is any JavaScript error from your code.

I tried both options, startup script and client script; same result: pdfobject’s options always undefined.
My code works because the PDF is loaded into the desired element (not pdfjs, however).
F12 shows no error besides the ‘undefined’ from my console.log(options) in /js/pdfobject.js, as I said before.
This is my code in the view page startup script:

ew.EMBED_PDF = true; //tried with and without this
ew.PDFObjectOptions = {
    forcePDFJS: true,
	PDFJS_URL: "/pdfjs/web/viewer.html"
};
var myelem = $("main").first();
myelem.parent().addClass("row"); 
myelem.addClass("col-md-6");
myelem.after('<div class="col-md-6 ew-pdfobject pdfobject-container"></div>');

I also tried setting ew.PDFObjectOptions at the end of the script, but got the same result.

  1. If you add your own DIVs, you need to init them yourself by calling ew.initPdfObjects().
  2. You should remove pdfobject-container which should be added by pdfobject.js.

If I remove pdfobject-container, the PDF loads into a new browser window, not the div.
I ran ew.initPdfObjects() after adding the div; same result.
The ew.PDFObjectOptions array is still not being fed into the pdfobject’s embed function: still coming as undefined.

Proving my point, I edited /js/pdfobject.js. Starting from line 248, I changed this:

    let embed = function(url, targetSelector, options){

        //If targetSelector is not defined, convert to boolean
        let selector = targetSelector || false;

into this:

    let embed = function(url, targetSelector, options){

		options = {
			forcePDFJS: true,
			PDFJS_URL: "/pdfjs/web/viewer.html"
		};
		// options = ew.PDFObjectOptions; //also works

        //If targetSelector is not defined, convert to boolean
        let selector = targetSelector || false;

Now, pdfjs loads! QED.
So, I think there is something wrong in the PDFObject.embed call.

Note that ew.PDFObjectOptions are added by ew.initPdfObjects(). If you add your own DIVs later than the page calling ew.initPdfObjects() (e.g. you add it in Startup Script), it won’t work. In that case you need to init your DIVs by ew.initPdfObjects() yourself.

You better put your options in Page_Head server event, see Example 4.

If it still doesn’t work, you may post your complete code for discussion, including:

  1. Which page are you working with? Built-in page? Your custom file?
  2. Where did you add your DIVs? Startup Script? How did you call ew.initPdfObjects()?
  3. Your Page_Head server event.

I wasn’t able to add the options in Page_Head server event. Kept getting syntaz error with this:

<script <?= Nonce() ?>>
		ew.PDFObjectOptions = {
			forcePDFJS: true,
			PDFJS_URL: "../pdfjs/web/viewer.html"
		};

My complete code is in the client startup script of the master/detail view page of a database table (not custom file). Page_Head server event is empty. This is the code in the view page startup script:

	var myelem = $("main").first();
	myelem.parent().addClass("row"); 
	myelem.addClass("col-md-6");
	myelem.after('<div class="col-md-6 ew-pdfobject pdfobject-container" style="position: sticky; top: 0px !important; height: calc(100vh - 51px) !important;"></div>');
	ew.EMBED_PDF = true;
	ew.PDFObjectOptions = {
		forcePDFJS: true,
		PDFJS_URL: "../pdfjs/web/viewer.html"
	};
	ew.initPdfObjects();

One thing I noticed is that if I add any data-url to my div, like this:

	var myelem = $("main").first();
	myelem.parent().addClass("row"); 
	myelem.addClass("col-md-6");
	myelem.after('<div class="col-md-6 ew-pdfobject pdfobject-container" data-url="dummy.pdf" style="position: sticky; top: 0px !important; height: calc(100vh - 51px) !important;"></div>');
	ew.EMBED_PDF = true;
	ew.PDFObjectOptions = {
		forcePDFJS: true,
		PDFJS_URL: "../pdfjs/web/viewer.html"
	};
	ew.initPdfObjects();

…PDFJS loads up but, as soon as I click a PDF link, it falls back into PDFObject. Maybe this can help.
Thanks a lot for your interest in the matter and help.

  1. Your Page_Head is missing the closing script tag, i.e. </script>. (Press Ctrl + F5 to reload the docs.)
  2. You should remove pdfobject-container which should be added by PDFObject.js.
  3. You can remove ew.EMBED_PDF = true; if you have enabled Embed PDF documents.
  4. You should remove ew.PDFObjectOptions from Startup Script since you have already added in Page_Head.
  5. You of course need to provide data-url attribute or the JavaScript does not know which PDF file your DIV (added by your jQuery code) wants to load.
  6. Not sure what you meant by “PDF link”. You have embedded the PDF in your DIV, which link is the “PDF link”?
  1. Thanks. I added it and syntax error is gone, but made no difference re. PDFJS.
  2. If I remove it, PDF object stops working on my div altogether.
  3. True. I added it to check if that was the problem, but it is redundant.
  4. Removed. Actually it works either way, buy only if modify /js/pfdobject.js as I previously wrote.
  5. I only need to provide data-url attribute if I want to load a PDF automatically when the page is loaded.
  6. My view page is a master/detail. Each detail line has a file field. As I click on each one, the pdf loads into the div.

I stress that this code works if I modify /js/pdfobject.js as stated above, forcing ew.PDFObjectOptions into the options variable, which is always undefined. I just wish I didn’t have to modify that script. My current code:

Page_Head (server side)

<script <?= Nonce() ?>>
    ew.PDFObjectOptions = {
        forcePDFJS: true,
        PDFJS_URL: "/pdfjs/web/viewer.html"
    };
</script>

Startup script (view page, client side)

	var myelem = $("main").first();
	myelem.parent().addClass("row"); 
	myelem.addClass("col-md-6");
	myelem.after('<div class="col-md-6 ew-pdfobject pdfobject-container" style="position: sticky; top: 0px !important; height: calc(100vh - 51px) !important;"></div>');
	ew.initPdfObjects();

/js/pdfobject.js (line 248+)

    let embed = function(url, targetSelector, options){
		if (options === undefined) options = ew.PDFObjectOptions; //MY_CUSTOM_CODE

That’s probably the problem. You may post your code for the link for discussion. I guess you just add the data-url to your DIV when you click the link. If so, that won’t work.

Be reminded that you have already initiated the DIV by ew.initPdfObjects() in the Startup Script. At that time there is no data-url yet, so it embeds no PDF file. When you add or change the data-url, the PDFObject will not automatically embeds again itself, calling ew.initPdfObjects() again won’t work either because it will not repeatedly initiate DIVs. So you should embed the PDF file yourself:

  1. Again, remove pdfobject-container. If you need to add it yourself, your code is incorrect.
  2. In the onclick event for your links, embed the file to your DIV, you better give it an id, e.g. “my-id”
PDFObject.embed("my/path/myfile.pdf", "#my-id", ew.PDFObjectOptions);

Read PDFObject.embed for more info.

You are right. The problem was in the custom attributes of my file field.
I added an id for my div, and removed class pdfobject-container.
Now, the field’s custom attributes are:

"onclick=\"if ($('#my_pdf_viewer').length) { PDFObject.embed($(this).attr('href'), '#my_pdf_viewer', ew.PDFObjectOptions); return false;}\""

…which will work whether #my_pdf_viewer exists or not (meaning I can disable the viewer and just download the file).
Everything works now. Thanks a lot!
Cheers