Storyline 2 Example - Generating a PDF Certificate for users who successfully complete a quiz

Aug 27, 2015

Hi all,

I've been experimenting with a JavaScript PDF library (pdfmake) to generate PDF certificates client side for learners who have successfully completed a quiz in Storyline 2.

You can see an example at http://rlowry.github.io/certificate/story.html

The 1st slide of the example provides a brief overview of how this works. I've tested this successfully in Internet Explorer, Chrome, Firefox, Chrome on Android and Safari on iOS.

I've attached a simple source file that contains a basic .story file as well as a folder (certificate) that includes the required HTML and JavaScript that needs to be included within a web object within the project. Feel free to have a look and re-use if it's useful.

The generated PDF certificate is very basic at the moment, you'll need to refer to the pdfmake documentation to update the design.

UPDATE: Originally this example only worked with the HTML5 output. I've tweaked it so it now works with the Flash output as well. I've updated the attached files to reflect this change.

UPDATE 2: I've updated the attached source files so they now use the latest version of pdfmake (v0.1.27).

Cheers,

Ryan

152 Replies
Nicky A
Kevin Brake

Hi Ryan,

Nice work getting this done, I had a long and painful sample created for PHP to PDF.

My question to you is:  How do you customize the background?

Specifically, change your certificate graphic to my certificate graphic ?

Ideally with a vector based image would be great!

I have tried several edits to the code and it just does not execute.

Any help would be great.

Thanks,

Kevin

Ryan just answered this a few posts up

Kevin Brake

Hi Ryan,

My question to you is: How do you customize the background?

Specifically, can an existing PDF be imported into the background?

I would like to avoid using the online conversion tool, referred to in your previous posting.

This does not seem to work?

// under NodeJS (or in case you use virtual file system provided by pdfmake)
// you can also pass file names here
image: 'myImageDictionary/image1.jpg'

Ideally with a vector based image would be great!

Thanks,

Kevin

Ryan Lowry
Kevin Brake

Hi Ryan,

My question to you is: How do you customize the background?

Specifically, can an existing PDF be imported into the background?

I would like to avoid using the online conversion tool, referred to in your previous posting.

This does not seem to work?

// under NodeJS (or in case you use virtual file system provided by pdfmake)
// you can also pass file names here
image: 'myImageDictionary/image1.jpg'

Ideally with a vector based image would be great!

Thanks,

Kevin

Hi Kevin,

As I mentioned in my previous post images must be converted to base64 strings and included as data uri's. You don't need to use an online converter, you can do this locally. I'm not going to go into how to do this, a quick google should point you in the right direction.

The following example demonstrates how you can use filenames when using pdfmake with NodeJS locally / on  a server.

// under NodeJS (or in case you use virtual file system provided by pdfmake)
// you can also pass file names here
image: 'myImageDictionary/image1.jpg'

There's no way to directly import a PDF, it would need to be converted to an image.

Unfortunately pdfmake doesn't support vector based images.

If you want to do something more advanced I think you'll have to do it server side. We use TCPDF to generate certificate PDF's server side with PHP in our VLE. This PHP class is much more advanced than pdfmake and the other javascript pdf libraries. Another benefit of generating server side is that you can keep a record of all issued certificate pdfs, 

Cheers,

Ryan

Ryan Martin

Nested iframes

Will the code still work?

If in an LMS, we have nested iframes. First iframe is for the lms <iframe class="tl-scorm-frame"... inside that we have the the web object...

Should this be updated to target the nested iframe:

var iframeElements = document.getElementsByTagName("iframe"); iframeElements[0].contentWindow.generatePDF();

If so, lil'help ;)

Late of night of google'n "nested iframe targeting" ...

/life of a gangster

Ryan

P.S. Great job Ryan

Ryan Lowry

Hi Ryan,

I don't think this is an issue, at least it hasn't been for me when testing in Moodle.

The page structure when viewing a Storyline SCORM package in Moodle is as follows:

moodle page
--> iframe
----> frameset
------>frame
--------> storyline
----------> iframe (webobject)

Tthe JavaScript targeting the webobject iframe is called from the Storyline content so the 1st child iframe will still be the webobject.

Cheers,

Ryan

Ryan Lowry

Hi Karin,

Here's one possible solution for you. The following code would replace what's currently in the JavaScript trigger.

Instead of targeting the 1st webobject (iFrame) on the page it targets a specific webobject based on the name of the src file.

Set the variable certFilename to the name of the certificate html file.

UPDATE: Fixed bug preventing this working in certain browsers

// Name of the certificate html file
var certFilename = 'certificate.html';

// HTMLCollection of elements of type iFrame
var iframeElements = document.getElementsByTagName("iframe");

// Iterate over the iFrameElements HTMLCollection
for(var i = 0; i < iframeElements.length; i++){
/* If src of current iFrame element equals the filename set in
** variable certFilename call the generatePDF() function.
*/
var src = iframeElements[i].getAttribute('src');
if (src.indexOf(certFilename) !=-1) {
iframeElements[i].contentWindow.generatePDF();
}
}
Ryan Lowry

Hi Karin,

Sorry the code I posted previously wouldn't have worked in IE or Chrome...

The following should do the trick.

// Name of the certificate html file
var certFilename = 'certificate.html';

// HTMLCollection of elements of type iFrame
var iframeElements = document.getElementsByTagName("iframe");

// Iterate over the iFrameElements HTMLCollection
for (var i = 0; i < iframeElements.length; i++) {
/* If src of current iFrame element equals the filename set in variable
** certFilename call the generatePDF() function.
*/
var src = iframeElements[i].getAttribute('src');
if (src.indexOf(certFilename) != -1) {
iframeElements[i].contentWindow.generatePDF();
}
}
Daniel Bolia

Hi Ryan,

Thank you for sharing this method and for taking time to answer questions posted in this forum.

I was able to create a custom certificate solution using your method and technique. However, Once the SL output was loaded on a Gov webserver the PDFmake function would not work. Nothing happens when the function is called.

I noticed that there is a server-side version of the PDFmake, however, the organization I work for will not allow the PDFMake package to  be installed on the server. I wonder if you might have experience with this issue and more importantly, a solution.

Thank you for your time,

Dan

Daniel Bolia

Hi Ryan,

Allow me to clarify, your method and my SL file worked as designed. It is only when it's accessed from a government computer, which is running IE-11 on Windows 7 that it doesn't work. From the same government computer using Chrome, it also worked as designed.

The trigger I have for calling the html and pdfmake function doesn't do anything. Because I also have a trigger to advance to the next slide immediately after the pdf trigger, I can't really trouble shoot for error messages.

I have also tested two other certificate methods posted on the forum; https://community.articulate.com/discussions/building-better-courses/create-a-course-certificate-in-storyline-with-java-and-html?page=3#reply-359742 and https://community.articulate.com/discussions/articulate-storyline/saving-storyline-variables-to-a-pdf. In both of these cases, I am also experiencing problems with creating the certificate as designed when I used IE-11. But as in the case above, the certificate function worked as designed in Chrome.

I'd be very pleasantly surprised if you would have any trouble-shooting tip for my problem, as I think it's all related to the configuration of IE-11 installed on the Government computers.

Thank you for your time,

dan