Toggle on and off (working with advance actions and variables)

Hi y’all,

So I was looking through youtube for tutorial videos on Adobe Captivate, and I came across this very helpful video:

It teaches you how to work with Variables and Advance Actions to Toggle a Button State and Show/Hide an Object, and I thought it might be nice to share.

I went ahead and recreated this “toggle on and off” interaction using these following steps:


Created a variable (on and off) under project -> variable with the value of 1 (True).

Advance Action:

Created an advance action with conditions (If/else) under project -> Advance Actions.

Here is the zip file/result of this mini project:  Play

Hope you guys are able to benefit from this, and are able to apply this to some of your works!



The post Toggle on and off (working with advance actions and variables) appeared first on eLearning.

Calculate Expiry Date (Expression, variables)


Today a user asked for help with coding to get an expiry date for a certificate slide,  see thread

It is a nice use case for the use of both system and user variables, and the use of the mysterious Expression command which is only available in the Advanced Actions dialog box (not as simple action in the Actions tab of the Properties panel). If  you are totally new to the use of variables, here are some links:

Using System Variables – part 1

Using System Variables – part 2

User Variables – Intro

Workflow described here step-by-step will show how to get the expiry date, 3 years from the present date can be calculated and stored in a user variable. It can of course also be done with JS, but I kept to one advanced action. Since I live in Belgium, I used the date format ‘day/month/year’. It is rather easy to change this to another sequence like the one used by ISO or in the USA.  Maybe I’ll post an interactive output, where you can choose the sequence of the 3 parameters. It is also possible to go for another way of presenting the date, but that is not treated here. Insertion in the Learning Interaction  ‘Certificate’ is not included neither.


1. Variables

You will be using these system variables, all from the category System information:

  • cpInfoCurrentYear: its value is a 4-digit number, at this moment 2019
  • cpInfoCurrentMonth: its value is a 2-digit number, still January at this moment, will be 01
  • cpInfoCurrentDate: its value is a 2-digit number, for me at this moment it will be 29; it may seem bit confusing that I don’t use cpInfoCurrentDay, but that gives a 1-digit number for the sequence in the week. Monday will result in 2 if t Sunday is considered to be the first day of the week in your OS settings.

You need two user variables (how to create them, see third link in the Introduction ‘Why?’)

  • v_year: will be used to calculate the expiry year, which would be 2022 for this user (3 years from now).
  • v_date: will have the full date of expiration after the calculations explained later.

The third variable v_choice has been used to offer a choice between the sequence for the date numbers. That is not part of this workflow.

2. Advanced action – creation

You need to create this advanced action, which is non-conditional I will explain each command:

  1. First Expression calculates the expiry year from the present year (cpInfoCurrentYear) and stores it in the user variable v_year. This is possible since the system variable can be seen by Captivate as a number, and using the mathematical operator +. Result will be of course 2022.
  2. The mathematical operator becomes here a ‘concatenation’ operator: it will add the string “/” to the day number. Do not forget the quote marks, because / is a mathematical operator. Result after this expression is the text:    29/   which will be stored in v_date
  3. Another concatenation replaces the value in v_date  by 29/01   
  4. Third concatenation results in v_date = 29/01/
  5. Last expression gives the final result v_date = 29/01/2019

The need for 4 expressions to get to the final value for v_date is due to the fact that the Expression command can have only one operator. You can use the Copy/Paste functionality in the Advanced Actions dialog box to speed up the process.

3. Assign action to Slide On Enter event

Attach the Advanced Action to the On Enter event of the slide, where you need to insert the variable v_date.

How you can insert a variable has been explained in the very first link I posted under ‘Why’.


  • Change the Advanced action to present the date in another sequence, like ‘Year/Month/Day’. If you are on CP2017 or later, maybe this blog could help.
  • For the fans of conditional actions: try to create a version where the learner can choose the sequence. You’ll need probably another user variable in that case and a multiple decision conditional action.
  • Which dangers exist for ‘cheating’ (I am a former professor) in the use case as described here? How would you cope with those dangers?

The post Calculate Expiry Date (Expression, variables) appeared first on eLearning.

Custom, Accessible Quiz: Development Highlights

I recently posted a showcase – a Custom, Accessible Quiz. This was a shorter, rewritten and rebranded version of a fully customized, yet accessible quiz I created for a client.
In this article I want to share some highlights of the development process. If you haven’t tried it already, it will help to understand the rest of this article if you try out the quiz before reading further. It’s at:

Multiple Introductions

Multiple text for introductions overlaid on a single slide.

In the course, there are two possible scenarios in which a learner may start the quiz:

  • A first attempt;
  • Re-taking after a failed attempt.

For both scenarios, I used a single slide to communicate the introduction to the quiz. Structurally, this means that the quiz always starts from a single location. Through experience, I have learned that this simple decision will help to simplify any debugging that might be necessary later as it reduces the number of non-essential branches in the course.

Advanced action showing how cpQuizInfoAttempts is used to determine which text to display.

For both scenarios, I used a single slide to communicate the introduction to the quiz. Structurally, this means that the quiz always starts from a single location. Through experience, I have learned that this simple decision will help to simplify any debugging that might be necessary later as it reduces the number of non-essential branches in the course. To determine which scenario was in play, I used Captivate’s cpQuizInfoAttempts system variable to track whether the quiz had previously been attempted. cpQuizInfoAttempts reports the number of times a quiz has been attempted; If the quiz has not yet been taken, its default value is zero.

Learn more about Captivate’s system variables at:

Custom Options

I created the custom options using Smart Shapes as buttons. Each option has only two states: Normal and Visited.

The highlighted True button for question 1 with its Smart Shape properties visible in the Property Inspector.

In terms of accessibility, this was perhaps one of the trickier areas of the quiz because unlike regular buttons, smart shapes are not automatically accessible. It was therefore necessary to add Accessibility Names to each state.

Quizzing Logic

The quiz contains only accessible question-types: true or false, multiple-choice (pick one, and select all that apply) and fill-in-the-blanks.
I created separate advanced actions to implement the logic for each of these question types, and then saved them as shared actions so that I could reuse the same advanced action for multiple questions containing similar objects.

A shared action
In each question, every option has an advanced action associated with it which defines the following:

  • The score to assign to the option – 10 for the correct answer, 0 otherwise (in most cases. Select all that apply works a little differently).
  • Any options that must be deselected once this specific option is selected (for true or false and pick one question types).
  • The specific variable that should be updated when at least one option has been selected –to indicate that it is time to enable the Submit button.

It’s also worth mentioning that every question slide also has an On Enter advanced action that resets all the options to their Normal state and clears the score from the Submit button before the slide is displayed –-if the quiz is being retaken.

A Little Branching

As I mentioned earlier, through experience, I have learned that it is generally best to limit branching to only when necessary to achieve pedagogical objectives i.e. when distinct structural paths need to be defined. This situation fits that definition in that after the learner has completed the quiz, they are automatically directed along one of two distinct paths:

  • Pass the quiz and go to the course conclusion;
  • Fail the quiz and go back to the beginning of the quiz (to retake it).

So, this was a perfect situation to implement a little branching by creating a conditional advanced action which determined where to direct the learner based on the outcome of the quiz. It did this by determining which Next button and message group to display to the learner on the Quiz results slide.

The Branching View showing the branches from the Test Results slide.

Similar to the introduction, I used On Enter to attach the advanced action to the slide. This is the branch you can see in the image.

The post Custom, Accessible Quiz: Development Highlights appeared first on eLearning.

Hiding Custom Navigation buttons – Advanced or Shared Action


I have been writing multiple articles about Shared actions (and Advanced actions), have presented webinars. Someone even labeled me as ‘Empress of Shared Actions’ but I still see this feature ignored by the big majority of even advanced Captivate users.  I will create a list of resources in another blog for those who want to learn more about them. This short showcase is an answer to a question posted today in the portal. A typical use case for shared, actions, but the user tried to do it with one Advanced action. Since I couldn’t ask him for permission to use his question (I am respectful of his privacy as an European), I will not point to the thread but explain the use case here:

  • The navigation in the course is not accomplished by a default playbar but by custom navigation buttons. To make it simple, I will use only three buttons in my example: SB_Next,  SB_Back and SB_Home.
  • On some slides the navigation buttons have to be hidden, maybe because  dedicated buttons will appear at the end of the slide, thus forcing viewing the slide.
  • Because of that request, it is not possible to have the shape buttons on the master slide because they wouldn’t have an ID, twhich means you cannot control their visibility.
  • The Shape buttons have to be on the first slide, Timed for the rest of the project, always on top. This is only possible with shape buttons not with the trhee old types of buttons. Beware: if you use a responsive project developed with Fluid Boxes, objects timed for the rest of the project are not allowed.

One Advanced Action? Possible but cumbersome

The user proposed a solution where the value of the system variable cpInfoCurrentSlide was checked, and based on that number the buttons would be hidden or shown.  One great advantage of this system variable: the index starts with 1, which is exceptional because all the other incrementing system variables start with 0. Hence the Expression needed to restart a slide from its first frame (index of cpCmndGotoSldie starts with 0):

Expression  cpCmndGotoSlide = cpInfoCurrentSlide – 1

To make the use case specific: if I have  50  slides, and I want to hide the buttons on slides 5, 10, 15, 20, 25, 30, 35, 40 and 45 that could be done with one Advanced action like this:

IF cpInfoCurrentSlide is equal to 5     OR
cpInfoCurrentSlide is equal to 10   OR
cpInfoCurrentSlide is equal to 15   OR
cpInfoCurrentSlide is equal to 20   OR
cpInfoCurrentSlide is equal to 25   OR
cpInfoCurrentSlide is equal to 30   OR
cpInfoCurrentSlide is equal to 35   OR
cpInfoCurrentSlide is equal to 40   OR
       cpInfoCurrentSlide is equal to 45   

Hide Gr_Buttons


Show Gr_Buttons

You see that I grouped the three buttons in Gr_Buttons.

Pretty cumbersome, right? Moreover this long condition has to be attached On Enter for each slide, and evaluated (will be fast, but I don’t like that type of long conditions). Moreover, if you change the sequence of slides, add or delete slides, you’ll have to check the advanced action and change the literals: those slide numbers will change. If you need to use this action for another course, you have to edit the condition.

Shared action

I have already blogged a lot about the advantages of shared actions. The action I designed for this use case, may seem bit complicated but it needed a lot of testing and understanding of the use of parameters which are literals. You can have a look at this published file. There is no content on the slides, I just indicated in the title if the buttons had to be visible or invisible. The used master slides is different as well. Reason: when you hide all buttons, there is no pausing point on the slide anymore. That is the reason why I added a transparent shape button covering the slide, and the mention ‘Click the slide to go to the next slide. A shape with two variables is inserted to follow the changes.


I used three variables in this action:

  • v_show: has a default value of 1, because in the default setting the buttons are visible. This value is the only non-compulsory parameter, can be changed to 0 if the buttons have to be hidden.
  • v_visib: one of my popular variables which I import with a shared action as described in my recent post.
  • v_null: because I had to avoid double use of the literal 0, I used this variable with a default value of 0, it is also described in the same post.

The only variable that will be changed is the first one, you don’t have to bother about the other two variables.

The Shared Action, filled in with the two parameters looks in the Preview window as follows:

You have to add this shared action On Enter for each slide. This cannot be done for all slides at once. I’m sorry, but you always have to define the Button group as parameter, my request to be able to promote a non-variable/literal to the status of being always the same is not yet heard. The other parameter (value of v_show) has to be 0 for the slides where the buttons have to be hidden, and 1 for those where you want them visible. Here is an example for a slide where they have to be invisible.

In the Library you can check the usage of the action, 10 instances were used:


As a gift for 2019 you can grab this shared action:


Import it into your course, the variables will be created automatically. You have to create only what you want to hide/show on the slides, group those objects and name them. Now you are ready to use that action On Enter for each slide. The group to be hidden/shown doesn’t have to be buttons, but they have to be displayed for the rest of the project.

The post Hiding Custom Navigation buttons – Advanced or Shared Action appeared first on eLearning.

Automatic next slide while having Play/pause button

Hi – I have a play/pause button created via a shape in the Master slide. It calls an advanced action (below) but at the end of the slide it does not automatically progress to the next slide as I want it to.

– On the button I have “Pause project until user clicks” UNCHECKED

– The advanced action being called on the button is:

Perform actions:  If cmCmndPause is equal to 0

Actions: Assign cpCmndPause with 1

Else: Assign cpCmndResume with 1

The post Automatic next slide while having Play/pause button appeared first on eLearning.