Supporting each other

Community forums

Welcome, Guest
Username: Password: Remember me
This is the place for questions about learning design and pedagogy; how to use different page types for different purposes.
  • Page:
  • 1

TOPIC:

Jumping between one PDF and various pages 4 years 6 months ago #6518

  • ForteanOrg
  • ForteanOrg's Avatar Topic Author
  • Visitor
  • Visitor
Hi, folks.

In my LOs I want to give learners access to a textbook. This textbook is stored on the XOT server as a PDF. I had a number of requirements (see below), but when I tried to implement these requirements using Xerte I ran into some difficulties. I have been able to create a solution and it all works as I want it to work now. I will share my solution here, either to learn from the honourable audience here how to do this with standard Xerte solutions - fully expecting roars of laughter about my lack of knowledge as I'm relatively new to XOT - and be taught a better way - or, if there is no alternate solution within XOT to fulfil my requirements: to help others that may be in need of this functionality too.

These were my requirements:

  1. The learner should be able to read the PDF online, in the LO, without the need for additional software.

  2. I wanted to have ONE page in my LO where the learner could read the PDF. The PDF display page should be the last page of the LO, somewhat similar to an appendix in a book.

  3. If you navigate to the last page directly (e.g. using the hamburger menu in the footer) the coursebook should simply open on its first page, as you would expect

  4. The author of the course should be able to create links to the PDF and specify the page on which the PDF will open. When the learner clicks these links, he (1) should be taken to the display page, which should open the PDF on the proper page

  5. When the learner is done reading he should merely need to click the 'back' button in the lower right corner and be taken back to the page he was on when he clicked the link.

The learners workflow hence would be: start the course, sequentially go through the materials one page at a time by using the "next" and "back" buttons. If there is a referral to the course book somewhere, the learner can simply click the link (or icon), be brought to the proper page in the PDF, read the section, when done the hit the 'back' button and be taken back to the page he was on to continue learning.



First problem: the PDF page did not work as I expected.
I started by trying to use the XOT PDF page type (+) → media → pdf file but that was a bit disappointing as all that does (at least here) is to show me a link that I can click to download the page. I therefore opted to use the excellent ViewerJS code (See: nlnet.nl/project/viewer/) which I downloaded and extracted in the root of my Xerte installation, to be found as '/viewerjs/'. I uploaded the pdf as usual. To display the PDF I created a (+) → Navigators → Embed Content page and in the embed code/url field pasted the url to the PDF:
/viewerjs/#../USER-FILES/path-to-media/media/name-of-pdf.pdf
Works fine, solved.

Second problem: how to navigate to the proper page
Well. that's relatively easy: when you use viewerjs, you can give it a startpage where it should begin displaying, for example say you want the learner to go to the fourth page:
/viewerjs/?startpage=4#../USER-FILES/path-to-media/media/name-of-pdf.pdf
So, that's not really hard, solved. Or is it? Well, yes, but only if you find a way to make the startpage a variable. See next section.

Third problem: how to convert the static URL to a dynamic one
Say I wanted to redirect the learner to page 4 in the PDF every time, well then I'm done. I simply put the static reference to the URL (including its pagenumber) in the embed field of the media page and we're good. But I want to be able to send the learner to different pages, not always (say) page four. I could of course create a specific PDF display page for each specific page number, but that would probably confuse the learner as he would be confronted with more that one page on which he could read the pdf. And it would go against my requirement that I only want ONE subpage where the learner can study the coursebook.

It proves that the source url of the JSviewer can be set using jquery. The id of the iframe that contains the PDF viewer is - aptly - "iFrame". So, to change the url you can use code like this:
$( "#iFrame" ).attr('src','the-url-goes-here');
That's all fine and dandy, but how do you specify which URL to use - and on which page to open it? Firstly, the author should be at liberty to specify any PDF name, so you can't simply assume one. And the author should be able to specify - on a per link basis! - which page should be opened.

The solution I found was to introduce a special string in the embed URL, and have some Javascript code to replace it with the actual page number. I choose to use the string ${Page} to denote the variable, but you can use any string you like, as long as it is uniquely occuring in the URL to the viewer. Put this string in the spot where you normally would fill in the page number by hand. For example, if you employ viewerjs:
/viewerjs/?startpage=${Page}#../USER-FILES/9-henk-Nottingham/media/CSSLP-Exam-Outline-Sept2020-1.pdf
Now, there are two things left to do: the author should be able to specify the pagenumber so the learner will end up on the proper page and the string ${page} should be replaced by the proper value and the iframe source should be replaced with that.

Fourth problem: how can the author provide the page number in the link to the PDF page?

The way the author specifies the link, including the page number to display, is by having him create a plain old Xerte Page link first, which points to the (only) PDF display page. If you then switch to source code editing, you will see the link displayed as someting like this:
<a href="#" onclick="x_navigateToPage(false,{type:'linkID',ID:'PG1588238774441'}); return false;">The link to the PDF</a>

To specify a page number, alter the link as follows:
<a href="#" onclick="x_navigateToPage(false,{type:'linkID',ID:'PG1588238774441'}); hwk_pdf_page=4; return false;">The link to page 4 fo the PDF</a>

As you see, you are introducing a global Javascript variable here: hwk_pdf_page and set it to the proper page. Pick any name you like, as long a you are sure it is not in use yet, so don't use, for example, a variablename that starts with 'x_' as they are reserved for Xerte.

Now, on the page that contains the PDF viewer, add a script container and put the following block of code in there:
// code to set the URL for the JSviewer including page number
function hwk_pdf_page_override() {
  if (typeof hwk_pdf_page==='undefined') {
     hwk_pdf_page=1;
  }
  if (typeof hwk_remembered_uri==="undefined") {
       hwk_remembered_uri=$('Iframe').attr('src');
  }
  var str=hwk_remembered_uri;
  var res = str.replace('${Page}',hwk_pdf_page);
  $( "#iFrame" ).attr('src',res);
}

// execute the code when the page load
hwk_pdf_page_override;

This code will replace the string ${Page} that you put in the URL with the value of the variable you put in the link and sets the target url for the iframe where the viewer will run. Solved.

Fifth problem: how to get the learner back from the PDF page to where he was before
Now, we have one issue left: how to ensure that the learner is returned to the LO page he was on when he clicked the link, simply by hitting the back button.

To be able to do this, add this section of code to the script container on the PDF display page:
function hwk_bbn_override() {
  $( "#x_prevBtn" ).unbind( "click", hwk_bbn_override);
  if (typeof hwk_anchor === 'undefined') {
      hwk_anchor=1;
   }
  x_changePage(hwk_anchor);
}

// and run it when the page loads
$( "#x_prevBtn" ).bind( "click", hwk_bbn_override);

Similarly to the way you defined the page number in the link, you should also define the return page there. This is how it's done:
<a href="#" onclick="x_navigateToPage(false,{type:'linkID',ID:'PG1588238774441'}); hwk_anchor=x_currentPage; return false;">The link to the PDF and you will be taken back here when you're done there and hit the back button</a>

Note that in this example you set the global variable hwk_anchor to x_currentPage, which contains the current page number. This is probably what you'd want, but you can have the learner return to any page you want by setting the value to some other page number.

Final remarks

Most of what I wanted has been realized now, but there are some details to keep in mind:
  • Ensure that the code in the script container runs "every time page is viewed". That's a setting of the script container.
  • Switch on the "Navigation buttons" option and ensure that only the option "back button" is checked.

All of it in one convenient section

When you combine both pieces of code, this is what should go into the script container on the page that displays the PDF:
function hwk_pdf_page_override() {
  if (typeof hwk_pdf_page==='undefined') {
     hwk_pdf_page=1;
  }
  if (typeof hwk_remembered_uri==="undefined") {
       hwk_remembered_uri=$('Iframe').attr('src');
  }
  var str=hwk_remembered_uri;
  var res = str.replace('${Page}',hwk_pdf_page);
  $( "#iFrame" ).attr('src',res);
}

function hwk_bbn_override() {
  $( "#x_prevBtn" ).unbind( "click", hwk_bbn_override);
  if (typeof hwk_anchor === 'undefined') {
      hwk_anchor=1;
   }
  x_changePage(hwk_anchor);
}

$( "#x_prevBtn" ).bind( "click", hwk_bbn_override);
hwk_pdf_page_override();

And this is an example of setting a link to return to the current page and open page 12 of the PDF, of course the ID may be different on your system:
<p>Please read the corresponding section in the course manual: see <a href="#" onclick="x_navigateToPage(false,{type:'linkID',ID:'PG1588238774441'}); hwk_anchor=x_currentPage; hwk_pdf_page=12; return false;">page 12</a>.</p>

Notes:
(1) the reader is kindly requested to substitute the proper pronoun associated with the gender of the learner where I use the male variation.

Please Log in or Create an account to join the conversation.

Last edit: by ForteanOrg. Reason: reshuffled text for claritie's sake

Jumping between one PDF and various pages 4 years 6 months ago #6524

  • tom
  • tom's Avatar
  • Offline
  • Administrator
  • Administrator
  • Posts: 1284
  • Thank you received: 324
A very nice solution.

We've got problems with the current PDF viewer, that doesn't work on all devices, therefore the link (so that we at least have something)

I'll have a look again.

I also looked at viwer.js, and regrettable it has a agpl license, and I need to check whther that is acceptable by Apereo.

Please Log in or Create an account to join the conversation.

  • Page:
  • 1
Moderators: ingdon
Time to create page: 0.052 seconds
Copyright © 2024 The Xerte Project.
Xerte logo Apereo logo OSI Logo

Search