A while back, we combined all our coordinating templates, layouts and awesome interactions into one download file—a Course Starter. Each course starter has a different design and is packed with features like xAPI reporting, responsive mobile design, and pre-built interactions, so you can get more done in less time.
In the past, we set up custom xAPI templates to give you as much control over individual statement elements as possible (for a refresher on the components that make up xAPI statements, visit here: https://xapi.com/statements-101/).
Since each xAPI statement has at least 3 parts—and, each of those have at least 2 values themselves—this can get cumbersome quickly. We felt this to be true in our templates. And, so did a few of our users.
Now, all you need to do to get custom xAPI statements from your eLearning Brothers templates is enter a verb ID and a verb display variable on an interaction, and you're good to go. Nothing else needed. Really.
We're tapping into the information that each tool is already providing with its out-of-the-box statements to avoid needing to enter redundant information; or, in the case of Storyline, performing a sacrificial publish and manually checking the output XML.
We use the activity identifier that you enter in the publish settings as the basis for all our custom statements.
Make sure this value is something unique to your organization, descriptive, and consistent.
Then, set it and forget it. We'll pick it up from there.
We use the activity ID variable together with the system variable for the current slide name to create a unique ID for the slide the learner is on. It matches the slide ID that Captivate uses on its "experienced" statement for the current slide.
We use this slide ID: as the base for individual object statements; as the object ID for any slide-level statements (like, "Susan mastered the drag and drop interaction"); and as the parent element in our custom statements' context blocks. This last bit allows us to map each custom statement to the slide it lives on, so you can get some deep, object-level analytics from your LRS.
(The above image is the context element from the dashboard of our Org Chart Click to Reveal interaction template. It gives us an at-a-glance indicator of the content usage on that particular interaction. In this case, it's nearly evenly split.)
Now is where things get tricky.
To make our object-level IDs for custom statements, we basically just need to take our activity ID, add the current slide name to that, then tack on the name of the item that our learner is interacting with, and URL-itize it.
In a small interaction, this is no biggie.
In something like a glossary, where you're tracking 26 different button names (or more), this can be a big headache. That's potentially 52 different touch points on 26 different actions to set 1 value.
But again, no system variable to pull those values from.
Basically, we're taking advantage of how Captivate outputs its files.
Captivate's output is HTML5—it basically creates a web page for each slide in a course.
That web page is made of individual DIV elements.
Each object on screen in an interaction gets its own DIV element.
Each DIV element gets an ID value, which Captivate generates using the related object's name/label properties.
We take advantage of that to automate the object-level IDs of our statements.
We use some simple Javascript to get the value of a div's ID based on the last element a learner interacted with. That value is then URL-itized and used as the Display and the tag for our ID value for the object*.
As of now, this is a free-form field; put whatever you want into the variables here.
Check here for a full list: http://xapi.vocab.pub/verbs/index.html
One thing we've done to make this easier though, is add the actions that set these values to Shared Actions, instead of Advanced Actions.
This keeps the advanced actions pane decluttered, and allows you to get at the parameters in an object's actions more easily.
Just click the parameters button adjacent to the object's assigned action in the properties pane, then start adjusting.
We've tried to add clear descriptions to each parameter.
After you've set the verb values, publish to xAPI and deploy as you would.
Easy peasy.
We still rely on the values you enter into the xAPI configuration pane at publish, but we just can't directly access them afterward.
Because Articulate doesn't expose its system variables for many things, we had to get a little crafty.
The first thing we do in a Storyline interaction is initialize our xAPI.
We do this by using an xAPI Initialize shape that sets our verb ID and Display values for the entire slide once the slide loads.
Since most learner actions in an interaction are pretty similar, it makes sense to template-ize this and set it once, for everything on that slide.
If you prefer to have unique values for each of the objects you're tracking on an individual slide, just add custom triggers to those objects, or wherever we've indicated the triggers run from.
Once those values are set, the initialize shape executes a little Javascript to get some information about where our learner is in the course:
We query the LRS to get the ID of the last slide the current learner "experienced," as well as its parent. (These values come from whatever you enter in at publish. We're just backdoor accessing them.)
We then store those values to some SL variables for later use.
If you allow the learner to start interacting with trackable objects before this info is back and stored in Articulate, you may get some errors on your statements.
Specifically, they may map to the wrong slide!
(Usually the leftover slide data from the previous interaction gets used here because it isn't being overwritten with new stuff.)
To combat this, just wait a second or two to load your interaction elements into the slide. This gives the two tools time to talk, and most always fixes the potential error before you encounter it. Popping some hotspots with no triggers over top of your interact-able objects for a time is another simple way to do the same thing.
Alternatively, you could get crafty with the script in the initialize shape and set an error-checking variable that flags something in your course.
That might be a topic for a future post if we have enough comments requesting it. Let us know below if you think it's something we should cover.
Back to it!
After we successfully query the LRS and store the values we retrieve, we pause.
In that case, you're done—enter one set of variable values at the top of the slide, and then publish.
Feel free to stop reading now, even.
It's that easy.
Object-specific actions get sent when a learner interacts with that object.
When a learner clicks tab 01, we send a statement that says they did just that.
The verb value and basis for our statement come from the initialize shape, but the individual statements are typically on the objects themselves.
Before the statements are sent though, we still need to gather object names.
In the old version, we did it with variables.
Now, we pick up the object names in Storyline very similarly to how we do it in Captivate: we use Javascript to grab the ID of the last object the learner interacted with, and use that for our object ID and display value.
This is due to how Storyline outputs its files; the two tools handle things a little differently in this regard as well.
Make sure you use the accessibility labels to title whatever objects you're tracking as intended in the LRS.
Double-check that "tab 01" object does in fact show that way in the accessibility pane.
Beyond that difference, the approach is very similar.
Object-level statements use the slide ID as their parent and the course as their group in context; any success or general statements are mapped to the slide and will report as slide-level data.
Once you have your course built, and verbs added to each slide, just publish to xAPI and deploy as you would with standard Storyline file.
We've tried to make it so you can get super-detailed, useful reporting out of your courses without having to know much at all about xAPI, and without having to do much setup either.
We think you'll like the new approach!
Comment on this blog and let us know, or reach out to us through our contact form, or on social media.
*In a few select cases, this may be a variable value, but this is the exception to the rule.