Intro
How to use Adobe Captivate to create a course for simple calculations, has been popping up on the forums several times. You can use Text Entry Boxes, MCQ's to reach that goal, but that is pretty limiting. Some examples can be found in this older blog post where the real goal was to have the score being linked to the attempts.
I started using JavaScript in Captivate projects since the release of the common API for JS (version 8) whenever the advanced actions did lack the wanted functionality. For those who want to start using JS, I wanted to explain some very simple use cases in a sequence of 4 articles that will focus on the 4 basic operators that are available in the Expression command: sum, subtract, multiply and divide. Each of the posts will introduce a JS example. The Expression command is not available as a simple command from the dropdown list in the Actions tab, it is only available in advanced/shared actions.
This article will focus on the Sum operator, and introduce JS to make it possible to generate random numbers. You'll also see how to assign that generated number to a Captivate variable with the function setVariableValue from the API. That will allow to use the same slide for several sum questions. I will use the Multi-state object feature of Captivate 9 several times as well. In the next parts you'll also learn about retrieving a Captivate variable value with getVariableValue, how to format a number to specific number of decimals, how to avoid dividing by 0 (zero).
Scenario Summing slide
User will be allowed to choose for sums consisting of 2 up to 4 terms. The number of terms can be changed after completion of one exercise.
For a correct answer, the stick figure will change to another state, and a star will be added to the progress bar (also a multi-state object). For an incorrect answer the stick figure also changes to a state but no star will be ended to the progress bar.
After completion of 5 correct sums, the stick figure will change to a Next button. The user could still add more questions, but no more 'stars' will be added to the progress bar.
In this screenshot, from HTML output, you'll see the situation after one successful answer, second sum has been created with 4 terms:
Used objects
Multi-state objects
Stick Character: see image Object States in Library below
OK/New shape button: see image Object States in Library below
Progress bar: see image Object States in Library below
Special objects
Radio buttons - works perfectly for SWF output but formatting is not preserved for HTML output; labeled "Wd_TermNumber"
Scrolling Text interaction for SWF output, labeled "Wd_SumResult". It is possible to change the shown content in this interaction by changing the associated variable (v_result). However that functionality only works for SWF, not for HTML output. For that reason I needed an alternative which is a
Text Entry Box, labeled "TEB_result" combined with the CpExtra widget and a specific command variable for HTML output. Since there is a bug in Captivate 9, which prevents using a TEB multiple times on a slide, I used a workaround. The default Submit button was deleted. It was replaced by a custom shape button (SB_CheckSum in the timeline) to trigger an advanced action. In this case an easy workaround, since I used that same shape button for the Scrolling Text Interaction for SWF output. The associated variable for the TEB is the same as for the Scrolling Text Interaction (v_result). Nothing had to be changed to the advanced action 'CheckSum' when replacing the Scrolling Text Interaction by a TEB.
Variables
v_one, v_two, v_three, v_four: will get the values for the (possible) 4 terms of the sum which are generated by the advanced action 'SumTerms'
v_result: will store the result value typed in by the user in the Scrolling Text interaction (SWF) or the TEB (HTML)
v_check: will be calculated and used to validate the result given by the learner in the advanced action 'CheckSum'
v_progress: is a counter for the correct answers, will be used to change the state of the progress bar
v_null: empty variable used to clear the content of the displayed result for a new sum (see Where is Null?)
xprefTEBUpdateFromVariable: only for HTML output, one of the CpExtra variables. When assigning the value 1 to this variable (with CpExtra widget loaded either in the file, or headless) it is possible to change the associated variable of a TEB by an action, and it will be reflected immediately in the TEB. I used this to clear the result when defining a new sum.
Advanced Actions
In this particular case it was not possible to use shared actions. Two advanced actions, both conditional, were needed:
SumTerms, triggered by the OK button (SB_Terms) after choosing the number of terms
CheckSum, triggered by the Check button (SB_CheckSum) to validate the answer
This conditional action has 7 decisions.
The first decision 'Always' will calculate the sum. It doesn't matter that it always sums four terms, since the lacking terms are empty.
The second decision 'Checker', will check the entered value (v_result) with the correct value (v_check). It is the only decision with a Then and Else part. For correct answer, the state of the sticky character is changed, the counter (v_progress) is incremented, the state of the button SB_Terms is changed to another state and enabled again, while the button SB_CheckSum is disabled. For an incorrect answer, the counter is not incremented, and the sticky character is changed to another state.
The 5 other decisions 'ProgressXxxx' check the value of v_progress and show the appropriate state for the progress bar. The last decision 'ProgressFive' will also change the sticky Character to its state GoNext and enable the click box to proceed to the next slide (subject of the next blog post, with Subtract exercises).
JavaScript for random numbers
In the documentation provide by the Captivate team about using the common JS interface, you'll find a description of creating random numbers:
In this example I wanted to generate a random number between 10 included) and 100 (not included). The script window for the decision 'TwoTerms' of the action SumTerms (see above) had to generate two random numbers, to be stored in v_one and v_two; for the decision 'FourTerms' 4 variables had to get a random number:
Short explanation of this code:
The JS method Math.random() generates a decimal number between 0 (included) and 1 (not included).
The multiplication Math.random()*(100-10) will result in a random (decimal) number between 0 (included) and 90 (not included).
The sum Math.random()*(100-10) + 10 will result in a random (decimal) number between 10 (included) and 100 (not included).
The JS method Math.floor(e) will cut off the decimals of the argument e, round iit down to the nearest integer. As a result the full expression used in the JS window Math.floor(Math.random()*(100-10) + 10) will result in an integer between 10 (included) and 99 (included).
The method from the common API setVariableValue(x,y) allows to assign the value from the second argument to the variable indicated in the first argument. Beware: the variable name has to be identified as a string (text) by putting it between single or double quotes. For the value, which is a number, you can use the expression explained above. It is a method of the cpAPIInterface which is in the window object. That explains the total line of code, which in JS always ends with a semicolon:
window.cpAPIInterface.setVariableValue("v_one", Math.floor(Math.random()*(100-10) + 10));
Conclusion