Creating HTML5 widgets for Adobe Captivate 6/7

I decided to write this post due to the frustration and lack of information out there on how to make HTML5 widgets for Adobe Captivate. There is almost no documentation on this and the only useful article I could find was riddled with mistakes. My approach may not be the best but this should get you started.

First things first, you will need to make two versions of your widget – a SWF version and a HTML5 version. Even if you don’t plan on using the SWF version, it is required during authortime in Captivate and is where you can provide the edit mode GUI.

These two versions are packaged up into a .wdgt file which is just a zip file with the extension changed to wdgt.

To get started create a folder with the name of your widget, then inside this create two more folders called ‘swf’ and ‘html5’ like so:

dirs

Once you have these folders set up you need to create some xml files that describe the contents of the package. The first one is called ‘description.xml’ and is placed in the root widget folder. Here is a sample of what it contains:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="ISO-8859-1" ?>    
<widget spec="2" name="Certificate" description="Widget description" uri="www.yourdomain.com" version="1.0" type="static">
    <authors>
        <author name="Your name" email="yourname@yourdomain.com" organization="Organisation name" uri="www.yourdomain.com">
            <about>Widget Developer</about>
        </author>
    </authors>
    <license name="CC" description="Creative Commons License" text="Feel free to use this" uri="http://creativecommons.org/licenses/by/3.0/"/>
    <formats>
        <format type="swf">
            <!-- Name of SWF version -->
            <content source="progessBar.swf"/>
        </format>
        <format type="html5">
            <!-- Name of HTML5 version descriptor -->
            <content source="progressBar_oam.xml"/>            
        </format>
    </formats>
</widget>

Your main widget folder should now look like this:
dirs2

In the html5 folder you will now need to create a descriptor for the html5 version. This follows an ‘OAM’ spec which I don’t know anything about, all you really need to know is that it will contain the following. (See this Adobe doc on creating wdgt files for more information on this file). It should be saved in the html5 folder and the name should match the name specified in the description.xml file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<widget name="ProgressBar" id="com.yourdomain.widgets.ProgressBar"
        spec="0.1b" jsClass='ProgressBar' sandbox='true' width='214' height='20'
        xmlns="http://openajax.org/metadata">
    <!-- Required tag specifies any external depencies your widget might have such as images, jQuery etc, see http://helpx.adobe.com/captivate/using/create-wdgt-files.html -->
    <requires/>
    <!-- Main widget JS file -->
    <javascript src="js/progBar.js"/>
    <!-- Properties tag currently not supported -->
    <properties />
    <content type='fragment'>
    <![CDATA[
    <!-- Contents of the widget (HTML that will be added to the widgets 'body' element -->
    ]]>
    </content>
</widget>

Now that we have all the folders and xml files set up we can get started on actually creating the widget. First we will create the HTML5 version. In the html5 folder create a new folder called JS and then inside here create a new JS file. This will be the main JS file for your widget and the name should match the name you specified in the oam xml file. Here is the basic structure of the JS widget file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var ProgressBarWDGT = {
    onLoad: function()
    {
        if ( ! this.captivate ){
            return;
        }

        // get captivate movie props reference 
        this.movieProps = this.captivate.CPMovieHandle.getMovieProps();
       
        if ( ! this.movieProps ){
            return;
        }

        // get any custom widget params xml - returns an xml string
        this.widgetParams = this.captivate.CPMovieHandle.widgetParams();
   
        // get captivate variable handle
        this.varHandle = this.movieProps.variablesHandle;

        // get captivate event handle
        this.eventDisp = this.movieProps.eventDispatcher;
       
        // example of listening to Captivate event 
        this.eventDisp.addEventListener(this.eventDisp.SLIDE_ENTER_EVENT,function(e){
                // do something on slide enter
        });

        // insert all other widget code here
    },
    onUnload: function()
    {
        /*Unload your widget here*/
    }
}

var ProgressBar = function ()
{
    return ProgressBarWDGT;
}

One of the biggest challenges I faced was figuring out how to listen to Captive events in the Javascript version of the widget. I found absolutely no documentation on this and resorted to going through the published Captivate JS files and inspecting using the Chrome dev tools to find anything that referred to events. I decided to document the JS events below so you don’t have to do the same and also since they are slightly different to the AS3 versions.

Using addEventListener you can add your event listeners to the eventDisp handle:

1
2
3
4
// add listener to the eventDisp object, using eventDisp 'constants' as the event type
this.eventDisp.addEventListener(this.eventDisp.SLIDE_ENTER_EVENT,function(e){
    // do something on slide enter
});

Here is a list of the event constants:

  • END_PLAYBAR_SCRUBBING_EVENT
  • INTERACTIVE_ITEMSUBMIT_EVENT
  • MOVIE_FOCUS_IN
  • MOVIE_FOCUS_LOST
  • MOVIE_PAUSE_EVENT
  • MOVIE_RESUME_EVENT
  • MOVIE_START_EVENT
  • MOVIE_STOP_EVENT
  • QUESTION_SKIP_EVENT
  • QUESTION_SUBMIT_EVENT
  • SLIDE_ENTER_EVENT
  • SLIDE_EXIT_EVENT
  • START_PLAYBAR_SCRUBBING_EVENT
  • VARIABLECHANGEDEVENT
  • VARIABLECREATEDEVENT

Once you have created you JS widget you need to create you SWF version. Open up Captivate and go to File > New Project > Widget in Flash to get a new widget template. Here you can create your widget as normal, I am not going to go into this here as there are other resources on creating SWF widgets on the net.

When your widget is ready publish the SWF and paste it into the ‘swf’ folder we created inside our widget folder. Make sure the name matches the swf name in the description.xml file.

With all your required files created you should end up with a folder structure which looks like the following:

cpfiles

Now all that’s left is to package it.

Select the contents of the widget folder and zip it up.

Rename the .zip extension to .wdgt.

Then copy the WDGT file into the Captivate widgets folder (Program Files/Adobe/Captivate [X version]/Gallery/Widgets)

Now you can refresh the Widgets panel in Captivate and insert the widget as normal. Captivate will choose either the HTML5 or SWF version depending on your publish settings.

That is all your should need to get started with a basic HTML5 widget for Captivate.

Posted toCaptivate HTML HTML5 Javascript
  • Pingback: Reverse engineering Captivate for HTML5 widgets | Purple Squirrels()

  • Anders

    Hi Ben. Thanks for a nice tut! Do you have any specific resources on creating SWF widgets you can recommend?

  • Andrew

    Hi there,

    So I’ve followed your instructions and gotten a working widget. I’ve added an image with the id “topImage” via the progressBar_oam.xml file. Everything’s going super swell.
    The issue I have is: nothing I add to the this.eventDisp.addEventListener(this.eventDisp.SLIDE_ENTER_EVENT,function(e){} function ever seems to execute. Any suggestions?