Forum Discussion
Creating a pdf file from Storyline running under an LMS
I know there are many excellent examples of how to create a pdf file in Storyline using javascript libraries such as jspdf and I have done this successfully in projects compiled for the web...
...but has anyone tackled this with an lms version? I know you could pass data to the lms using xAPI - but I really just want to click a button and "save" the pdf file created within the course using variables collected during the course.
Any ideas would be welcome.
- JohnCooper-be3cCommunity Member
Happy to help.
Having re-read you question - I guess I should also point out that my original error was not my code - but that I was trying to run the code above from a compiled version of my Storyline course on my local PC.
That won't work because the browser is complying with with the CORS (Cross Origin Resource Sharing) security protocol designed to prevent malicious files being loaded. Ironically, files on the same PC accessed via a file reference i.e. no "http: address" are not assumed to come from the same "origin" and therefore trigger a CORS error when the HTTP request to load the image (addImage) is executed.
When I moved the code and ran it on a server (I have my own cloud server but you could use Amazon or Microsoft Azure Cloud storage) the code runs fine because the file is accessed via it's http: address and the img.CrossOrigin ="": command basically tells the browser to accept an 'anonymous' unauthenticated image i.e. switch off the CORS check in the HTTP request.
Sorry that got a bit technical. In simple terms, you have to load the compiled web code with the image in the root folder onto a server for it to work - it won't work if you run it on your PC.
- JohnCooper-be3cCommunity Member
OK - not trivial JavaScipt as it turns out - but I have solved it and can successfully produce a multi-page 'Notes' pdf document including the learner's own notes collected from text entry boxes through the course.
I will post a separate article on how to do this here on eLearning Heroes and post the link here when I have done it.
- JoaoCastroSilvaCommunity Member
Hey John. Reading through the comments was an emotional roller coaster. Please let me know when you post that article :) I'll be curious to learn from it.
- SarahlewisscottCommunity Member
Hey John! Did you ever get around to posting the article about a multi-page PDF? I successfully have a single page PDF download functionality with learner input and a background image, but I want to have a second page with a different background image and I haven't quite got the code right. Hoping to see yours as a model! Thanks!
- JohnCooper-be3cCommunity Member
Hi Joao
Thanks for the reminder about the article - I will definitely get to it. We have moved forward significantly and done several projects using this approach.
What we have done is develop code that:
A: retrieves the data from the variables in Storyline storing them in a table - one row per page.
B. we then add parameters to each variable in the table - font size, x and y pixel coordinates for the position on the page and the number of characters before we throw a new line
C. The code then processes the table in a loop reading the data associated with each variable creating a new page for each row according to the parameters.
It works fine - and we can produce complex handouts without having to modify the code - just by setting up the parameter table for each project.
All the best, John
- Jürgen_Schoene_Community Member
actionator::exeJavaScript - jsPDF is not defined error
means: .js file is not found or not compatiblecreate a small example (one slide with one button) with your programming and upload the .story file and your modified scorm package here in the forum
- JohnCooper-be3cCommunity Member
Hi Ariff
Can I ask you what your "src = " statement looks like in the index_lms.html file?
You have two option for loading the require jsPdf JavaScript library for your JavaScript code. You can load the latest source library at run-time from one of the on-line source code repositories - something like this:
<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
OR
if you have downloaded a version of the library containing the code you need then you need to add that file to the compiled storyline files and include:
<script src="story_content/jspdf.debug.js"></script>Where the file jspdf.debug.js has been copied to the "story_content" folder in the compiled version.SO - check where your javascript library file is located and make sure the src = is pointing to the right folder.....NOTE: the reason many of us are using the latter "jspdf.debug.js" file is that it is probably V1.5.2 of the library where inclusion of the javaScript modules was done using a "require" statement. After V1.5.2 the jsPdf library changed to a different (more modern) module format ES6. In this case the modules are added using an import statement. I haven't got round to testing my code with the ES6 module format - and I suspect others haven't either.- AriffKhalid-25fCommunity Member
Hi John, after 4 hours of trial and error, i've figured it out.
Apparently jsPDF versions after v1.5.3 simply do not work. I've tested each version working backwards from the most recent (as of this post v2.5.1) and found that v1.5.3 is the most recent one that works.
I was stumped and ended up in a google rabbit hole before stumbling across another thread on the web about trying older versions.
From the changelog for v2.0.0:
Modernized the output bundles: there are now bundles for ES modules, UMD and a special node version. We renamed the files in dist for consistency: jspdf.debug/min.js is now jspdf.umd(.min).js. We also changed the name of the global variable to jspdf (lower case) when using script tags to be consistent with the new es modules format and named imports/exports. For backwards compatibility add this line:
window.jsPDF = window.jspdf.jsPDFYet whenever i add the line "window.jsPDF = window.jspdf.jsPDF" it still doesn't work. So i've just decided to simply use v1.5.3 and baking it locally within the scorm file.
Have you had much success with any of the more recent versions of jsPDF?
- JohnCooper-be3cCommunity Member
Hi Ariff
No. As per my earlier post, I just hadn't got round to testing my code with the later versions of jsPdf. Like you, I used v1.5.2 and, as you say, 'baked' that into the SCORM code.
I may take a look at it and see if I can get the UMD version working. Hopefully, you have got your code working OK now? Albeit with V1.5.3.
I'm also interested in the JavaScript library pdf-lib as this allows you to fill in a pdf form which would be really useful.
If I get anywhere useful I will post here.
Regards, John
- JohnCooper-be3cCommunity Member
I'm wondering if I could include the FS javascript library, do an asynchronous write to create the file somewhere, and then jump to the pdf file? Or is that crazy??
- JohnCooper-be3cCommunity Member
Thanks Matthew
What I'm doing is getting the learner to complete a questionnaire using sliders - I capture their responses and then create a pdf using the javascript jspdf library with their responses in it on a kind of grid .
I then allow the learner to be able to download the pdf with the results in - this is done using the javascript Filesaver library.
The Storyline works fine if loaded to a webpage.
If I compile the course for an lms (and make the necessary changes to include the javascript libraries I'm using) and then run this code from a website (or even my own pc, as I'm not loading an image), It also works fine - I get the prompt to open or save the pdf (see attached screen - client name redacted).
But obviously, the run environment is different when the same code is being run under an lms - I have tested the code loaded into Moodle and the learner doesn't get the prompt.
There's clearly a difference in the way the lms displays the course - presumably in some form of frame - I just wondered if anyone had taken a look at this and could steer me in the right direction?
All the best, John
- AllisaCardellaCommunity Member
Hello Matthew,
That sounds awesome! It has given me an idea for a survey that I'm doing where I was using a traditional Likert scale resulting in the information being very crowded & not much room for anything else. Do you mind me asking how you were able to use the slider & have it transfer to the PDF?
- JohnCooper-be3cCommunity Member
Matthew - great idea - why didn't I think of that?
actionator::exeJavaScript - jsPDF is not defined
(anonymous) @ bootstrapper.min.js:38Not sure why that is though.....
- JohnCooper-be3cCommunity Member
You are correct - I have. At least the
<script src="story_content/jspdf.js"></script>is in there. So the javascript library src= statements should be in index_lms.html??I will move them - if that works, I definitely am deeply in your debt! - JohnCooper-be3cCommunity Member
It works perfectly! Matthew - you are a star!!