Tutorial: Creating a Dynamic Printable Workbook

[Edit: Here is an updated tutorial]

Here is a Dynamic Workbook that I built with the help of an experienced javascript developer. It allows for a custom workbook to be assembled based the choices a user makes, which will help them take their notes and other relevant information and references away from the course.

There is a bit of work involved to get this set up properly, but it’s not too tricky. Promise.

Here is a demo of the functionality.

Here is a .zip that contains the files you’ll need.

I’ll start by outlining the basic steps for those who just want a quick overview and then I’ll provide a more detailed description.

Here are the basic steps to make it work:

  1. Figure out how many of the users' responses you want to track and create a variable to store each response. These variables should be titled Q1, Q2, Q3, Q4 and so on. 
  2. Set up the printUserTitle and printUserName variables. These control the title and name shown at the top of the workbook.
  3. Modify the print.html file to include your desired content. Note that the users' responses will be inserted wherever this exists:
    <div id="answer1" class="answer"></div>
  4. Create a ‘Workbook’ button in your course using the following javascript: window.open("print.html","_blank","width=800,height=600,menubar=no,scrollbars=1");
  5. Add the jquery folder and the print.html, process.js and style.css files to your published output.
  6. If you are using a LMS, see here
  7. Upload and test.

-----

Here is a more detailed description.

It is best if you build the bulk of your course before you add this functionality. Although when building the course you’ll want to keep the following in mind:

  • Any responses that you want sent to the workbook should be stored in a text variable that starts with a capital Q followed by a number. For example, Q1, Q2, Q3, Q4 and so on. The variables must be named this way so that they can be found by the workbook. (If you don’t know what variables are, I suggest you read this article before continuing.)

Once your course is built, you’ll want to add the following to your Storyline file:

  • Create a text variable called printUserTitle. Its value will determine the title that is displayed in the workbook. 
  • Create a text variable called printUserName. Its value will determine the name that is displayed in the workbook. 
  • Create a text entry field at the start of your course where the user can enter their name and set it to adjust the value of the printUserName variable.
  • Create a button in your course that will be used to open the workbook. It should execute the following javascript when clicked:
    window.open("print.html","_blank","width=800,height=600,menubar=no,scrollbars=1");

Then you can publish your course as per normal (although you don’t want to zip the files just yet).

-----

The next step is to edit the print.html file.

You’ll need a text editor to do this, such as Notepad.

When you open the file, you’ll be greeted with the following beautiful sight:

<!DOCTYPE html>
<html>
<head>
<title>Workbook</title>
<script src="jquery/jquery-1.11.0.min.js"></script>
<script src="process.js"></script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style media="print">
#printDiv {display:none;}
</style>
</head>
<div id="container">
<div id="printDiv"><button id="print"></button></div>
<div id="staticContent">Name: <span id="userName">.....</span></div><br/>
<div id="staticContent">Date: <span id="date">.....</span></div>
<div>
<h1 id="title">.....</h1>
</div>
<div id="staticContent">This is static content that will be the same for everyone. You can provide as much of this as you need in the workbook. Did you know that a group of toads is called a knot? Apparently you love the below more than a knot of toads.
</div>
<div id="answer1" class="answer"></div>

<div id="staticContent">If you live in Virginia and have a bathtub outside your house, you are currently breaking the law. Now, your thoughts on pickles.
</div>
<div id="answer2" class="answer"></div>

<div id="staticContent">At this exact moment in time, there are at least 1,800 thunderstorms in progress over the earth's atmosphere. Anyway, back to pickles.
</div>
<div id="answer3" class="answer"></div>

<div id="staticContent"> Did you know that most lipstick contains fish scales? Well, herring scales to be precise. You were asked not to type anything for one of the questions so you can see what happens.</div>
<div id="answer4" class="answer"></div>

<div id="staticContent">Did you know that dolphins sleep with one eye open and that jellyfish are 95% water? Or was that the other way around? Wait ... do jellyfish even have eyes?</div>
<div id="answer5" class="answer"></div>

<div id="staticContent">Please remember that while it is possible to lead a cow upstairs, it will not be possible to lead a cow downstairs in the future. This could create a problem. Are pickles sounding interesting yet?</div>
<div id="answer6" class="answer"></div>

<div id="staticContent">100% of lottery winners gain weight. So there's that. In other news. </div>
<div id="answer7" class="answer"></div>

</div>
</body>
</html>

You’ll need to change some of this, but it isn’t as scary as it seems. You can start by ignoring all of this stuff at the top (it’s just telling the browser what’s up and displaying the info at the top of the workbook):

<!DOCTYPE html>
<html>
<head>
<title>Workbook</title>
<script src="jquery/jquery-1.11.0.min.js"></script>
<script src="process.js"></script>
<link rel="stylesheet" href="style.css" type="text/css" />
<style media="print">
#printDiv {display:none;}
</style>
</head>
<div id="container">
<div id="printDiv"><button id="print"></button></div>
<div id="staticContent">Name: <span id="userName">.....</span></div><br/>
<div id="staticContent">Date: <span id="date">.....</span></div>
<div>
<h1 id="title">.....</h1>
</div>

You’ll want to start making changes where it says:

<div id="staticContent">This is static content [etc.]

If you want text displayed at the top of the workbook, this is where you enter it. Simply put the text you want shown between these two things:

<div id="staticContent">
</div>

So it looks like this:

<div id="staticContent">This is exactly where your beautiful words should be.
</div>

Then you’ll notice the next line down in the print.html file, says:

  <div id="answer1" class="answer"></div>

This is where the response that is stored in variable Q1 will be displayed. You don’t need to make any changes to this.

The part below has some more static content:

<div id="staticContent"> If you live in Virginia and have a bathtub outside your house, you are currently breaking the law. Now, your thoughts on pickles. 
</div>

And then there is some code that will result in variable Q2 being displayed:

  <div id="answer2" class="answer"></div>

This pattern continues throughout the print.html file. Essentially, static content should be wrapped in:

<div id="staticContent">
</div>

And responses from Storyline Q# variables will be shown wherever these exist:

  <div id="answer#" class="answer"></div>

(Note that you’ll need to swap that # with a number in the code above).

Make sense? Cool. Save your print.html file and let’s move on.

-----

Okay, next up we need to check the date. I’ve set it to display properly, but I’ve heard that some of you do weird things like have the month before the day… So if 30/10/14 looks weird to you then you’ll want to open process.js in your text editor and change this:

  $("#date").html(curr_date + "-" + curr_month + "-" + curr_year);

To this:

  $("#date").html(curr_month + "-" + curr_date + "-" + curr_year);

Or if that doesn't work, maybe even this:

  $("#date").html("Dance Like" + "-" + "It's" + "-" + "1999");

Actually, ignore the last example, that's just silly.

If you are publishing to a LMS, you'll also need to replace:

var player = opener?opener.top.GetPlayer():{} ; 

with

var player = opener?opener.GetPlayer():{} ;

Save your process.js file. 

Now, if you are comfortable with CSS, you can change the look of the workbook by editing the style.css file. 

I won’t go into detail here, but if all you want to do is change the green text colour to something else, open style.css in your text editor and change the last line from:

.answer p {color:green;} 

to 

.answer p {color:red;}

Right, so now it’s just a matter of copying the jquery folder, and the print.html, process.js and style.css files to the same folder that contains your published output.

This needs to run from the web, so if you try and test it locally, it won't work. Upload it to your LMS or server or secret lair or whatever and you should be good to go.

As far as known issues go:

  • This won’t work Articulate Mobile Player (as it's allergic to javascript) 

I hope that this is helpful. 

Edit 11/10/18: If you'd prefer a PDF option, see here.

81 Replies
Bj Wilson

Wow, thank you so much. I have also saved this post as a PDF and I attach it here if anyone else wants to download it. Great instructions and the demo works well. Just one point, the link to the zip files doesn't work but I found the correct link here. Thanks again Matthew for all the work you have put into this and for sharing it.

Matthew Bibby

While I haven't tested it with 50 entries, I don't think that will cause any problems.

What environment will you be using this in Adam?

I've been told by another person here that this didn't work properly when they tested it in a SCORM environment and I haven't had a chance to figure out why (it may be as simple as listing the included files in the SCORM manifest). Anyway, just thought I'd mention it as I'd hate for you to build it all only to find it doesn't work as anticipated in your environment.

Let me know how you get on.

Adam Judge

Hi Matthew.

Thanks for the fast response.

This is not going to be in a SCORM LMS; actually not in an LMS at all - we're developing it as an optional supplement to a classroom course.

My question was prompted by a recollection I had that there was either a character limit or a limit to the number of entries that could be stored in a JavaScript array (and pardon me if I've mangled the terminology - this foggy memory is from when I coded websites by hand in Notepad - a long, long time ago).

 

Adam Judge

I was able to get it working with a larger number of entries. I did encounter a problem, and worked around it. It's an improvisation, but it works. I'm sure there is a more elegant fix - and I'd be glad to learn what it is.

The course has almost 100 questions (it grew) spread across 4 lessons, so I set up a workbook for each lesson. Instead of a single workbook button pointing to "print.html", each lesson has its own button pointing to "lesson1.html, lesson2.html" and so on.

The numbered dynamic responses (with matching static text for the questions) in each workbook pick up where the previous one left off. The Lesson 2 Workbook’s responses, for example, start with this answer DIV:


<div id="staticContent">Dr. Koop mentions the Executive Secretariat of the Department of Health and Human Services as being responsible for the censorship and suppression of the Surgeon General's ability to communicate with the American public. Read the description available from HHS.
<BR>18. Based on this, do you think Dr. Koop's view of the Executive Secretariat is accurate? </div>
<div id="answer18" class="answer">.....</div>

I ran into trouble at the 50th entry. The dynamic text didn't appear in the published HTML page, showing only the static text from #50 onward:

....
50. If you were defending the Bush administration following representative Waxman's list, what questions would you have asked?
....

I looked at the .js files, but saw nothing that looked like I wanted to monkey around with it (though I did re-order the date fields to suit my US audience).

I wondered if there was bad code in the first offending entry, but deleting the 50th entry from the workbook HTML page just moved the glitch to #51. Similarly, deleting #49 also only moved the glitch.
My next idea was that maybe I’d failed to close a DIV tag somewhere, but the code looked balanced, the page was displaying correctly (apart from the dynamic text after #50), and tacking a </div> on at the end just in case didn't help.

As the issue seemed to revolve around the answer DIVs, I added an empty one after entry #50 and previewed to see what happened.

<div class="answer"></div> 

Bingo. For every empty answer DIV I added, another dynamic entry would appear. It does add empty space, but it isn't too much of a problem. I added the extra DIVs at the end of the workbook pages with text suggesting that the user use any extra space for notes. I think I could also move them to be in between the dynamic responses to minimize the appearance of extra white space.  

So - if anyone knows what the right way to handle this was (because I'm pretty sure my  solution wasn't it), please let me know.

Laura Brunning

We only needed 11  text boxes, so didn't encounter the problems as described above - however, as mentioned in an earlier post, when I uploaded this as a SCORM to our LMS - it didn't work  (although works as expected when the zip is uploaded to tempshare). 

Through the LMS - the print.html file just shows the static text that we entered as a heading to the answers and there are just dots .... where the answers/name/date should be. 

Also the actual print button turns into a tiny grey square that does nothing when clicked (although the save as text button we added does appear and works).

Does anyone have any idea of how to fix it so it works when uploaded as a SCORM?  Any help would be much appreciated as this is just what we need!!

Attached are the screen shots of LMS version and Web

Cheers, Laura

Adam Judge

I'm not working in a SCORM environment at present. When I've worked in a SCORM LMS in the past, though, I recall that uploads to our SCORM server occasionally had seemingly random javascript issues similar to what you're describing. In that case, this could be as simple as formatting code being carried over when text was copy-pasted into the course from Word, for example.

Since your "SAVE" button is displaying correctly, I would compare the code on the "SAVE" button to the code on the "PRINT" button, and tinker with the code to try and get the "PRINT" button to display. That might provide a clue.

Best of luck.

 

-Adam

Midi Prefix

Is there not the problem that you can't really viably store line breaks in text variables in Storyline? I guess you could try using a 'When button pressed' set to the enter key, to add a <br> into the variable using javascript before passing it back. I guess it would work for single line entries, but paragraph answers would probably come out looking odd.

 

This is a really awesome piece of work even so.

Matthew Bibby
Laura Brunning

Does anyone have any idea of how to fix it so it works when uploaded as a SCORM?  Any help would be much appreciated as this is just what we need!!

 

Sorry Laura, I'm not sure why this doesn't work in SCORM. I original developed this as a proof of concept for a project that was subsequently cancelled and I haven't had a chance to develop this functionality further since then. Good luck getting it sorted! Do you have anyone on your team who is familiar with javascript and SCORM?

Matthew Bibby
Midi Prefix

Is there not the problem that you can't really viably store line breaks in text variables in Storyline? I guess you could try using a 'When button pressed' set to the enter key, to add a <br> into the variable using javascript before passing it back. I guess it would work for single line entries, but paragraph answers would probably come out looking odd. 

This is a really awesome piece of work even so.

Yes, this is an issue. I spent ages trying to get the line breaks working with no success. Although, I'm sure it can be done...

Thanks. 

Midi Prefix

The strange thing is, Storyline evidently DOES save them in some way, somewhere, because if you set a variable using a text entry box, and bring that back into another text entry box elsewhere, the line breaks are retained, but if you then put this same thing into a text box (using %VARIABLENAME%) as a reference, the line breaks are lost in this instance.

Matthew Bibby
Midi Prefix

The strange thing is, Storyline evidently DOES save them in some way, somewhere, because if you set a variable using a text entry box, and bring that back into another text entry box elsewhere, the line breaks are retained, but if you then put this same thing into a text box (using %VARIABLENAME%) as a reference, the line breaks are lost in this instance.

Yeah I know, I just can't figure out how to get it to work.

I'm really hoping that someone here will find a way to retain the line breaks... anyone, anyone?

Daniel Bolia

Hi Matthew,

Thank you for a very thorough, detailed, and informative example of adding notes and printing in SL. I read your post with GREAT interest but was discouraged at the end to see the words "Line breaks aren’t supported".

I do not have any experience with JS but I have also been searching for the solution to "line breaks" problem in SL. I think I may have found a possible solution that I'm hoping you or others in the community will be able to sort out and develop a workable solution.

In my research I learned that the JS code for adding a line break is "\n". I also learned that it is possible to convert JS line break ("\n") to HTML line break ("<br/>") by using the JS function "replace", which would look something like this

.replace(/\n/g, "<br/>")

I learned this information from James Kingsley's eLearning enhanced Blog https://elearningenhanced.com/blog/2013/08/05/append-new-text-storyline-variable-and-print-variable, which he also provided all the resources (demo, SL file, and JS codes).

I'm hopeful that someone in the community will be able to confirm this possible solution; "anyone, anyone?"

 

 

Matthew Bibby

Hi Daniel,

I'm glad this tutorial was helpful. I agree that the lack of line breaks does limit the use of this and it's something I've been meaning to investigate further, but I just don't have time at the moment.

There is another thread that discusses the same code that you've included above and this may also be of interest. 

I am planning on looking into this more in the future, but at this stage it won't be for at least a month. Do you know anyone who is good with JavaScript?

Daniel Bolia

Hi Matthew,

Thank you for pointing out the additional thread, I will have a look at it. In the meantime, I'm trying to work with a programmer that knows several programming languages so hopefully I'll be able to find a solution to this. I'm also looking at your example on this thread to incorporate the print button into the pop up window, shown in the example posted on the eLearning Brother blog, http://elearningbrothers.com/6-steps-on-how-to-make-a-printable-results-page-in-articulate-storyline/. I'll post more once I learn more.