Comparing Advanced and Shared Actions

Intro

If you have followed me since a while, you know that I am a great fan of Shared actions.  However I am aware that many developers seem to be afraid of those shared actions. In this post I will try to demystify the 'shared action', and answer some questions.

First of all: the biggest advantage of a shared action is its reusability. Whenever you need an action which will be used multiple times in a project, or which you plan to use in more than one project, it is worthwhile to consider the use of a shared action. Here are some other reasons. You can skip this part and come back to it later:

  • When used within one project, you are using instances of the same shared action. If you prefer using duplicated and edited advanced actions the file size will be bigger. It can be compared with the use of multiple instances of the same graphic/audio clip.
  • Shared actions appear in the Project Library with all the functionalities of Library assets: how many times uses, on which events etc..
  • You can transfer an existing advanced action to a new project using copy/paste of the object triggering the action: a button, click box, TEB (success/Last attempt events), slide (Enter/Exit event). If variables are used in the advanced action, they will be created in the new project. However, in many cases, commands in the advanced actions will revert to Continue if what they are referring to is not available in the new project. Example: missing slides for navigation commands, missing states or even multistate objects...  
  • Transferring a shared action to a new project is a breeze: drag the action from the original Library to the Library of the new project. Variables which are not used as parameters will be created (similar to copy/paste for advanced actions). Since the shared action is not connected with any event, you don't have to bother about having everything in place before transferring the shared action.
  • There is no built-in way to document Advanced actions in Captivate. A shared action however allows to add a description to the action and to the parameters if any are used. 

There are some limitations to shared actions:

  • It is not possible to trigger a shared action from a hyperlink.
  • You cannot attribute a shared action to several events at once, as is possible for an advanced action.

Beware: not all advanced actions are suited as shared action. In a recent post about 'Hint after x failed clicks' I explained a use case which was meant as introduction for Captivate users new to variables and advanced actions. You may have a look at that first blog post:  https://blog.lilybiri.com/automatic-hint-after-x-failed-clicks

Conversion to shared action

It is a good idea to create and test the action as advanced action before creating the shared action. This was the advanced action  created in the mentioned blog post, triggered by the Success event of the  'wrong' hotspots (5) in the example:

Two user variables were used: 

  • v_attempts tracks the number of clicks on the button/hotspot
  • v_failure is used in the Failure feedback message and allows to change the content of that message. The default failure message will be replaced by a Hint message after the defined number of clicks.

First version Shared Action

Open the advanced action in the dialog box, use the button Save as Shared action, and this dialog box will appear:

In the screenshot you see that I have filled in the description. It is important to do so, try to explain in short sentences what the action will do exactly. It may seem a loss of time, but if you reuse the action a couple of months later, you'll understand why I emphasize this.

In the main part you see the 'parameters', and in this particular case all of them show the green check mark. This means that you can save the shared action as it is. Result will be that the parameters remain static, cannot be changed when you attach the action to an event.  They will not need a description neither. Comparing with the advanced action:

Pro

  • The description of the action, which is impossible for an advanced action.
  • Its appearance in the Project Library with all the functionality of other assets.
  • For reusability in another project: you can drag the shared action from this library opened as external library to the Project library of the new project. For an advanced action you would need to copy/paste one of the wrong hotspots to the new project.

Con

  • You cannot attach the shared action to all wrong hotspot events at once, you need to do it one by one. The advanced action could be attached in one workflow by selecting all the wrong hotspots.
  • For another hotspot slide in the same project it will be easier to create a duplicate advanced action, and edit the Hint text (value for the variable v_failure).

Second version Shared action

In the first screenshot I marked two parameters with a question mark:

  • Parameter '2': literal indicating the number of required wrong clicks before showing the Hint.
  • Parameter 'Click on the icon 'Responsive project'': the new value (literal) for the variable v_failure to replace the failure text by the Hint text.

You can make the static parameter dynamic by clicking the check box, and entering a description for the parameter. To me the most important candidate is the Hint text. Making that parameter dynamic, means that you can enter a different Hint text for each new attachment of the action to an event. Beware: the correct checkmark will only appear after confirming the description of the active parameter:

This makes the action flexible: you only have to enter the Hint text as parameter whenever you attach the shared action to an event.

Pro

  • Besides the description of the action, the meaning of the parameter will appear whenever you apply the shared action.
  • Its appearance in the Project Library.
  • Reusability in any new project remains.
  • File size will be lower compared with using duplicate advanced actions.
  • You can edit the Hint text for each instance.

Con

  • You cannot attach the shared action to multiple events at once.
  • You need to fill in the text parameter with each attachment (copy/paste is possible)

Third version Shared action

You can make the action even more flexible by declaring the number of wrong clicks to be a dynamic parameter.  Using that shared action you'll be able to change the number of wrong clicks before showing the Hint instead of the Failure message.  Like increasing the number for a more complicated hotspot slide. I don't have to explain this screenshot anymore:


More tips

I may write out a third blog about using this shared action as template for advanced actions, including possible enhancement by adding graphical (audio) assets to the Hint text message.

If you want to learn more about using Shared actions, please have a look at my 'crash course'. 

Shared Actions : intro

Lesson 1 (video)

Lesson 1 (step-by-step)

Lesson 2 (video)

Lesson 2 (step-by-step)

To circumvent the "Con" of shared actions not being able to apply to multiple events at once, remember that you can easily create an advanced action from a shared action. Here is an example:

Using Shared action as template



Replay (slide) Button

Update:

A new version of these workflows (for CP2019) can be found in a new post and in an interactive Captivate tutorial.

Replay or Reset Slide

Replay/Reset (Captivate course)

Intro

This pretty short article will explain several ways to create a button that will replay a slide from its first frame and is functional on that slide only. The reason is that I have been asked about this use case multiple times. 

Questions

First thing to check is: does this slide have an On Enter action? The default On Enter action for a slide is 'No action'. On Enter actions are however the way to go if you want to reset a slide to its initial configuration, to clean up the 'mess' that can happen on that slide by the user or by the interactivity on that slide. On example: maybe the user has popped up objects  using a hyperlink on a word or iimage? In that case you'll need an On Enter event. The action needed for a Replay button will have to make sure to 're'- enter the slide, in order to have that On Enter action done. To better understand what I mean, I created a short example movie.

Example movie

Watch this movie, which I have been testing both for SWF (version here) and for HTML5 output. You'll see two slides:

  1. Slide 'Title': it has an On Enter action to play an audio clip.

  2. Slide 'Pills': a user variable v_counter is used (and displayed) to store the number of clicks on the 'pills'. The timeline of this slide looks like this

    Each of the pills (shape buttons) triggers a shared action, that will show a state (with explanation), increment v_counter, wait for 2 seconds before releasing the playhead.

On both slides you'll see two buttons: 'Replay1' will restart the slide from its first frame, without re-entering the slide. That means that the On Enter action is not executed again. The second button 'Replay2' will re-enter the slide. Listen and watch the difference (look at the counter on the second slide). Refresh the browser when you are ready to watch this example. Refreshing will also get you back to the start of the movie.

'Replay1' - On Enter action is not repeated

If you do not need a resetting action On Enter, a replay button can be coded very simple. If you are on the slide with the label 'Intro', this simple code will do the trick:

    Jump to slide Intro

However you'll not find the slide 'Intro' in the dropdown list for the 'Jump to' command in the Actions tab. You need to choose 'Execute Advanced Action', and create a one-line standard advanced action.

It is simple but I do not recommend to use this work flow. It means creating a new advanced action for each slide. A first alternative would be a shared action, defining the slide name (or number) as a parameter.

If you need this action for many, even all slides in a project, there is a much better work flow. Create this advanced action:
  
Why do you need an expression to subtract 1 from the number of the current slide, which is stored in cpInfoCurrentSlide? The index of the system variable cpInfoCurrentSlide starts by 1 That way it can be inserted on a slide indicate the slide number. Its value for slide 3 is '3'. To show the slide number you insert cpInfoCurrentSlide in a text container on the master slide or timed for the rest of the project.

The index of system variable cpCmndGotoSlide starts not by 1, but by 0 (usual in programming languares). If you want to navigate to slide 3, you have to give a value '2' to cpCmndGotoSlide.  So far the reason for that Expression in the advanced action Replay1.

This command is functional both for SWF and HTML5 output. I tested this in several browsers.

This action is triggered by both Replay1 buttons in the Example movie. The On Enter action is not executed with this Replay, which results in:
  1. For slide 'Title': the audio clip will not be heard.
  2. For slide 'Pills': the variable v_counter is not reset to 0, and will continue to increment.
Watch the variables I inserted top left of the slides: they show the current frame, and the frame number stored in the user variable v_enter.  If you wonder why the frame number never starts with 1, read the explanation under the next subject 'Replay2'.

TIP

be sure to create this action as a shared action, no need to define the system variables as parameters. Store that action with much used shared actions in a separate project. In any project you can open the Library of that project as an external Library and drag that Replay action to the library of the new project.

Replay2 - On Enter action is repeated


As explained under 'Questions', you'll have to enter the slide in this case, not just jump to the first frame as was done with the Expression in the scenario for 'Replay1'.

This is a bit more complicated. I had to use 'micro-navigation', a term introduced by me in this old  blog post: navigating between frames. Look at the advanced action created for the 'Replay 2' buttons:
This is the work flow:
  • Create a user variable v_enter that will be reused on each slide that needs a Replay button of this kind. That variable will store the number of the first frame of the slide. To achieve that I have to add a command to the already existing On Enter actions. Here are the actions for both slides:

  • When the Replay button is clicked, there is first navigation to 2 frames before the first frame of the present slide. Why 2? Theoretically 1 frame should be OK, but for HTML5 output (slower) I learned that it is better to use
  • Although I use the system variable cpCmndGotoFrameAndResume for navigation, which should release the playhead and navigate very quickly to the next slide, I detected that adding the second command 'Go to Next Slide' made the process more fluent (again for HTML5 output). 
The result is very clear in the Example movie:
  1. For slide 'Title': the audio clip is played
  1. For slide 'Pills': the variable v_counter is reset to 0.

Frame enigma - TIP

If you watched the frame number closely, you will have seen that the 'first' frame (on slide 'Title') is not 1 but 3 or 4. Here is the explanation: since I wanted the Replay2 button to be active on this first slide, I needed a slide before that first slide for the micro-navigation. That slide will not be visible to the user because it is only 0,1 sec long. At a frame rate of 30fps, that means ...3 frames.



Dynamic Buttons

Guidance

If you’re planning on attending the Adobe Learning Summit, DevLearn, or both this fall, read on….   (If you can’t make it this year, there’s a consolation! Skip to the bottom of this post to get a tip about dynamic buttons.)

Most of you know that I frequently blog and post about Adobe Captivate. Well, Adobe has given me the wonderful opportunity to offer free in person peer-to-peer Captivate project help at the MGM Grand Las Vegas on September 29th and 30th. Since I’m flying from my home in Belgium to present at the Adobe Learning Summit, this is a great chance to meet and help you face to face, not virtually.

My friend and fellow Captivate user, Alice Acker, will host this event. To see as many Captivate users as possible, we’ve limited each appointment to a maximum of 30 minutes.  If you are part of a project team, we can accommodate your team at the appointment. These times are designed to limit disruption of your Adobe Learning Summit or DevLearn schedule. We’re co-located with the conferences at the MGM Grand, so there is no need to Uber or bike to us. We’ve made this super convenient for you.

Please bring me your most headache-inducing project, and I’ll do my best to solve your quandaries.  Since these spots are limited, make sure to sign up now with your top 3 appointment choices. The slots will be filled on a first come, first served basis. We’ll do our best to schedule you for one of them. If you just want to drop in to say hi, I’d love to see you. But, please make sure that you register so we get an idea of how many Captivate users to expect.

Once you’re successfully registered, you’ll get an email confirmation of your appointment, directions to the session, and a link to upload the project. It will really help if I can review it before the session. All information will be kept confidential. What happens in Las Vegas, stays in Las Vegas.

Looking forward to meeting you. Tot weldra in Vegas!

Lieve a.k.a. Lilybiri

This is the link to the registration form Form to complete


Dynamic buttons

In the archive you'll find several articles about shape buttons, which appeared with version 6. I used to call them 'chameleon', because they can be useful as shapes (images), text containers, buttons, and recently also for the automatic feedback text appearing on question slides and with interactive objects. Maybe you are not yet aware of this aspect of shape button? You can insert a variable as a label on the button. On runtime the value of the variable will appear. That value can be changed by actions, and the label will change in that case, hence my title 'Dynamic'. Some ideas to use this feature?

  • Localisation: if you use custom shape buttons on master slides (or timed for the rest of the project) to replace the play bar, you can change the label on those buttons based on the language choice. If the language is chosen from a dropdown list (learning interaction) or with radio buttons (learning interaction), insert the variable associated with that interaction. Combine this with the work flow explained in Branch Aware Quiz

  • Custom Question Slide: if you want to allow a limited number of attempts, you can add the attempt number on the Submit button, or you can change the label to 'Continue' after the last attempt. Of course you'll need a companion conditional action to change the functionality of the button as well.

  • Navigation: if you use shape buttons on the master slide, they cannot be hidden/shown. But you can change the value of the variable that acts as label on each slide. Using a Back/Next button, put a null value to the label on the first slide for the Back button, and change the Next button to an Exit or Return button on the last slide (you'll need to create a conditional action in that case as well).


Windows 10

Just a short warning: do not hurry with upgrading to Win10.  Be patient, Captivate 8 is not guaranteed to be fully functional in this new OS. Personally I will wait to see eventual issues on forums and in groups.

Force first view - Captivate 8

Update: if you are on a more recent version, please check out this article:

Forcing First View with micro-navigation (shared action)

Intro

As a former college professor I don't like to push students/trainees to watch everything in an eLearning course. After all, you can watch without really seeing as well, that doesn't prove anything about the real 'learning' process. Apparently not everyone agrees with my personal opinion and again a question popped up on the Captivate forums in this thread: Force navigation upon FIRST view....

Problem

The course was totally linear, which is a requirement for the simple work flow I will propose here. To force the student the first time to have the slide played totally before being able to continue is simple: use a custom Next button, timed at the end of each slide, do not use a playbar but a TOC for navigation to previous slides. And set up the TOC settings to allow navigation only to already visited slides.
To improve the user experience, when he is coming back to an already visited slide, the Next button should appear from the start of the slide. That way he can skip part of the slide if wanted. The easiest way to solve that problem is by using an extra, replacement Next button. Because timing from start till end of a slide is the same for all slides, this can be a shape button put on the first slide that is timed for the rest of the project, always on top. It is not possible to use a shape button on the main master slide because such a button has no ID, which means it cannot be controlled, shown/hidden which is necessary for our use case.
The initial buttons can also be shape buttons and for a seamless user experience I'd recommend to use the same look for both the initial and the replacement Next button. However those initial buttons need to be individual buttons on each slides because not all slides will have the same duration, especially when they have VO attached as slide audio.

Example movie

Watch this movie to check the solution. To make the switch between the initial Next buttons and the replacement Next button clear I used a different style. Moreover I inserted a text container with two variables: the system variable cpInfoCurrentFrame and a user variable v_frames (see later) that are used to solve the problem. To navigate back to already visited slides, open the TOC with the red curved arrow top left. The TOC close button has a similar look. Refresh the browser to start the movie again. I didn't check AutoPlay, you'll have to click on the (ugly) arrow in the middle of the slide.


Events and Variables

I created one user variable: v_frames. The system variable cpInfoCurrentFrame will be used as well.
This variable will be used to store the current frame number when the user clicks on an initial Next button. Example: on the first slide the initialNext button Bt_One will appear at 5 secs and pause at 5.5 secs. When you click that button, you'll see that on the second slide the variable has the value '166' which is about the frame number of 5.5 secs at a speed of 30FPS. It is never totally exact (should be 5.5*30 which is 165, but index starts at 0, the exact number should be 164). But for the purpose it will be used, this is OK.

The used events are:
  1. Success event for the initial Next buttons: rBt_One, Bt_Two, Bt_Three, Bt_Four. I don't need a Next button on the last, fifth slide. Those button will trigger the same advanced action NextAction:
  2. On Enter event of slides 1-4 will trigger a shared action Show_Next:
  3. Success event for the replacement Next Shape button SB_Next executes a simple action: "Go to Next Slide"
  4. On Enter event of slide 5 (last slide) will trigger a simple action: "Hide SB_Next"

Advanced/Shared Actions

Advanced Action "NextAction"

This action, triggered by the initial next buttons on each slide except the last slide, has only two statements:
The frame number of the pausing point (which is where the action is executed by design) will be stored in the user variable v_frames. Then the Go to Next Slide command is done. 
Why did I prefer to use an advanced action over my favorite shared action? I don't need to change this action when applying to another button. You could create a shared action if you expect this action to be used in other projects because it is easier to transfer them using the library. In that case the shared action will not need any parameters. When you transfer it to another project, the user variable v_frames will be created automatically. That is certainly an advantage!

Shared Action "Show_Next"

This is the action that does the trick! It is a conditional action: 
When a user enters a slide for the first time, the frame number of the first slide frame will be greater than the frame number stored in the user variable v_frames. That user variable has in that case the frame number of the Next button pausing point that was on the previous slide. But if the user comes back to this slide, v_frames will store a frame number of a similar Next button pausing point on a later slide. In that case the condition in this shared action will be correct, v_frames will be greater than the cpInfoCurrentFrame. The appropriate button is shown or hidden. It is necessary, for an unknown reason (was not the case in CP6, when I blogged about toggle buttons), you also have to enable/disable as well. This is probably due to the buttons being in exactly the same location, but it was not necessary in a previous version. 
I defined only two parameters in this shared action:
It is not necessary to define the user variable v_frames as a parameter because it is always reused. It is a pity that objects have always to be a parameter, because in this particular case it would have saved some time to be able to deselect SB_Next (the replacement Next button, timed for the rest of the project) as a parameter. Maybe in a future version? Some will prefer advanced actions and duplicates to be edited for each button but remember: multiple instances of a shared action do not increase the file size, whereas multiple duplicates of an advanced action do increase file size. And I like the presence of the shared actions in the Library, and easy way to use them in other projects.

Conclusion

I love to solve this kind of problems, trying to find an easy solution that can be reused over and over again. If you ever are stuck with such a problem, please contact me. I am available as a freelance consultant, and having taught for many years in college, be sure to get some training on top.