Playing with Numbers - part 2


In the previous blog post I introduced you to the common JS API, and you used the method 'setVariableValue' to populate a variable defined in the Captivate project. That value was a random number generated in the JS window, using the Math.random() and the Math.floor methods. The values were integers, between fixed numbers 10 (included) and 100 (not included). In this second article you'll learn to know a new method 'getVariableValue' from the JS API, which lets you transfer a value to JS. We started with the mathematical operation 'Sum', now we'll switch to 'Subtractions' needing again the command 'Expression'. Because CP cannot handle well negative values, we'll have to take care of that as well.

The progress bar introduced with the Sum exercises, will be continued. You'll see that it is possible to change the state of an object, displayed for the rest of the project, from a slide where that object is not inserted. 

Scenario Subtract Slide

Subtraction will be with two terms, always integers. Whereas in the Sum slide I decided that all terms would have to be between 10 and 100, on this slide the user will be able to choose a Maximum number, and if he wants a Minimum number. The minimum number has already a default value of 10, which can be changed by the user, the maximum number is empty. The Max value needs to be bigger than the Min value, if that is not the case, the Max value will automatically be set to 'Min + 200'.
The same sticky figure (with states) and OK button (with state New) are used as described in the previous post for the Sum slide.
This Subtract slide can only be visited when 5 correct Sum exercises have been done, hence the 5 stars on the progress bar are in place on entering this slide. The progress bar is set to display for the rest of the project, and you can change the state (to 6 or more stars) from this Subtract slide, although the progress bar is not visible in the Timeline. New stars can be added after a correct subtract exercise, and after 10 stars, the Next scenario is executed (same as on Sum slide).
Here is a slide preview, after answering the first correct subtract question:

Used objects

The same multistate objects are used as on the Sum slide (see state panels on previous post):

  • Sticky figure with its states and a motion effect for the minus sign
  • OK button, which changes to a New button after the first exercise
  • Progress bar, which has been displayed for the rest of the project.

In this slide I only used TEB's, which I can control due to the presence of the CpExtra widget (InfoSemantics). The consequence is that this description is only valid for HTML output. For SWF output the TEB can be replaced by a Scrolling Text Interaction:

  • TEB_max accepts only numbers and is empty when starting - associated variable is v_max
  • TEB_min accepts only numbers and has a default value of 10 (changeable)  - associated variable is v_min
  • TEB_result accepts only numbers - associated variable is v_result (reused from sum slide)

Two shape buttons, that are alternatively enabled/disabled:

  • SB_Number is the OK/New button, triggers the advanced conditional action SubtractTerms
  • SB_CheckSubtract is the Check button, triggers the advanced conditional action CheckSubtract
To make the next state of the sticky figure interactive, it is covered by a Click box CB_Next2.

This is the Timeline of the slide:


Some variables created for the Sum slide are reused:

  • v_one, v_two, v_three, v_four: are reused for the values of the two terms, which will end up in v_one (first term) and v_two; those variables will be reset by the On Enter action of the Subtract slide
  • v_result: will store the result value typed in by the user in TEB_result, has to be reset as well.
  • v_check: will be calculated and used to validate the result given by the learner. 
  • v_progress: is a counter for the correct answers, will be used to change the state of the progress bar; this variable is not reset but starts with the value 5 (end value after the Sum slide)
  • v_null: empty variable used to clear the content of the displayed result for a new sum (see Where is Null?)
  • xprefTEBUpdateFromVariable:  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 TEB_Result.

New variables are:

  • v_max associated with TEB_max will store the maximum value for the terms

  • v_min associated with TEB_min will store the minimum value for the terms

Advanced Actions

Shared actions were not possible. One Standard advanced action was needed (to reset vars) and two Conditional actions.


This very simple standard action, triggered by the On Enter event of the slide, clears several variables that are reused from the Sum slide:


This conditional action is triggered by the OK/New button SB_Number. It has 3 decisions:

  1. "CheckCorrect" will compare the values stored in v_max en v_min. If the maximum value is not exceeding the minimum value, the maximum value will be calculated by adding 200 to the minimum value.

  2. "RandomNum" will generate two random numbers and store them in the variables v_three and v_four. Reason is that the last decision will have to put the largest number into v_one and  the smallest in v_two. This could have been checked in the JS script window as well, but I wanted to keep the JS as simple as possible and checked with the last decision. 

  3. "CheckMax" compares the values in v_three and v_four. The largest value will be assigned to v_one, the other to v_two. This decision also calculates the result of the subtraction to be stored in the variable v_check (will be used to check the user's entry).


This conditional action is triggered by the check shape button SB_CheckSubtract and has 6 decisions

The first 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_Number is changed to another state and enabled again, while the button SB_CheckSubtract 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_counter and show the appropriate state for the progress bar. The last decision 'ProgressTen' 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 Multiply exercises).


In the previous post you learned to use 'window.cpAPIInterfaceSetVariable (x,y)' method to populate a variable x (to be entered as a string between quotes) with a value y. You calculated y by using a combination of two Math methods in JS: 

  • Math.random() which generates a random number between 0 and 1 (not included)
  • Math.floor() which will convert a decimal number to an integer by rounding it down (cutting off the decimals).

For the sum slide we used a combination of those two methods, to end up with a random number between 10 and 100 (not included):


For the Subtraction, the maximum and minimum values are not fixed, but stored in Captivate variables v_max and v_min. Due to the first decision in SubtractTerms action, we are sure that v_max > v_min. Those value will be transferred to JS variables with the method 'window.cpAPIInterfaceGetVariable(x)' where 'x' is the name of the Captivate variable, entered as a string (between quotes). Example:

var max = window.cpAPIInterfaceGetVariable("v_max");       stores value of v_max in JS variable max

Instead of the fixed values 100 and 10, used for the sum slide, you use this time min and max to generate a random number between min and max. The two random numbers are stored in variables v_first and v_second. Since they are random, we do not know yet which one has the largest value:

var first = Math.floor(Math.random()*(max-min)+min);

var second= Math.floor(Math.random()*(max-min)+min);

You are already familiar with SetVariableValue to store the result of first in v_three - Captivate variable, and second in v_four. 



You earned a second star, soon a third part will be ready, up to multiplications and bit more of randomness.

3 responses
Lots of good things to learn here, I am particularly interested in the xprefTEBUpdateFromVariable, . For mobile applications on tablets and phones data entry requires an extra step to bring up the keyboard, perhaps this could help streamline that process. I did a much less sophisticated version of addition and subtraction as a learning exercise a few months ago, it's on my website, simply called "Numbers", glad to share the project file if anyone interested.
Thanks for the comment. These sequence of articles was meant as a very simple introduction of using JS in combination with advanced actions. Advantage of having several exercises on the same slide is important for mobile apps since it reduces file size a lot.
1 visitor upvoted this post.