View All Variables for debugging

Oct 09, 2019

Is it possible to easily view the values of all Storyline variables during a preview? This would be helpful while debugging.

 

I do currently have a method of doing this, but its a bit annoying and was hoping for something automatic or built-in.

 

My current method:

  1. Create a layer on the Slide Master
  2. Trigger that layer to appear when user presses a key (I use F12)
  3. In that layer, manually enter a reference to each variable in a text box. Make sure you update it as your project grows. (this is the annoying part)
11 Replies
Orest Mykyta

Hi Luis,

I actually have to thank you for resurrecting this thread. I have since created a better way to view all variables using some JavaScript, and I don't think I've shared it. So thanks for the reminder.

A disclaimer: This solution is a little bit "hacky" so be sure to remove it when you are ready for publishing. I also can't guarantee that it will continue to work with future releases of Storyline, but I'll try to remember to update it here if needed.

 

Here's what I do nowadays:

Create a trigger on the slide master to run when the user presses a key (I use the F9 button, since it's typically not used for anything else.) The trigger will execute the JavaScript shown in the code block below.

Since it uses JS, it won't work in preview, so you have to publish.

Then, at anytime, press F9 (or whichever key you assigned it to) and a window pops up with a list of all variables and their values. You can even use this window to change the value of whichever variable you like.

But note: it does not automatically refresh the variable values. So if you have the debugger window open and you do something in your Storyline presentation that changes the variable, it will not show the new value until you hit the refresh button at the top.

 

JavaScript for the trigger:


//Opens a Storyline variable debugger window
//Add this JavaScript to some Storyline trigger (ex: when user presses F9 in the slide master)

"use strict";
var pl = GetPlayer();
var debugWin = window.open(undefined, "debug", "width=600,height=800,toolbar=no,location=no");
var debugDoc = debugWin.document;
debugDoc.body.innerHTML = "";
debugDoc.title = "Storyline Debugger";
var refreshButton = debugDoc.createElement("INPUT");
refreshButton.value = "Refresh";
refreshButton.type = "button";
refreshButton.addEventListener("click", refreshVars);
debugDoc.body.appendChild(refreshButton);
var tableElem = debugDoc.createElement("TABLE");
debugDoc.body.appendChild(tableElem);
getStorylineUserVariables(function (slVars) {
slVars.sort(function(x, y){return x.name > y.name;});
for (var a = 0; a < slVars.length; a++) {
var v = slVars[a];
var trElem = debugDoc.createElement("TR");
if (a % 2 == 1) trElem.style.backgroundColor = "#dddddd";
var tdElem = debugDoc.createElement("TD");
tdElem.innerHTML = v.name;
tdElem.style.padding = "10px 2px";
trElem.appendChild(tdElem);
var inputElem = debugDoc.createElement("INPUT");
inputElem.storylineVarName = v.name;
if (v.type == "number") {
inputElem.type = "number";
inputElem.step = undefined;
inputElem.value = pl.GetVar(v.name);
} else if (v.type == "boolean") {
inputElem.type = "checkbox";
inputElem.checked = pl.GetVar(v.name);
} else {
inputElem.type = "text";
inputElem.value = pl.GetVar(v.name);
}
tdElem = debugDoc.createElement("TD");
tdElem.appendChild(inputElem);
trElem.appendChild(tdElem);
tableElem.appendChild(trElem);
}
} );
tableElem.addEventListener("change", function (e) {
var inputElem = e.target;
var slVarName = inputElem.storylineVarName;
var newVal = "";
if (inputElem.getAttribute("type") == "checkbox") {
newVal = inputElem.checked;
} else {
newVal = inputElem.value;
}
pl.SetVar(slVarName, newVal);
} );

function refreshVars () {
var inputs = tableElem.querySelectorAll("input");
for (var a = 0; a < inputs.length; a++) {
var elem = inputs[a];
var val = pl.GetVar(elem.storylineVarName);
if (elem.type == "checkbox") {
elem.checked = val;
} else {
elem.value = val;
}
}
}

function getStorylineUserVariables(callback) {
//Overide Storyline's globalProvideData function temporarily
var origGlobalProvideData = window.globalProvideData;
var scriptElem = document.createElement("SCRIPT");
scriptElem.src = "html5/data/js/data.js";
window.globalProvideData = function (foo, data) {
var dataObj = JSON.parse(data);
var variableList = [];
for (var a = 0; a < dataObj.variables.length; a++) {
var varObj = {name: dataObj.variables[a].name, type: dataObj.variables[a].type, defaultValue: dataObj.variables[a].value};
if (varObj.name.match(/^[0-9a-zA-Z]{11}_RetryModeInteractionIncompleteOnLoad$/) == null &&
varObj.name.match(/^LastSlideViewed_[0-9a-zA-Z]{11}$/) == null &&
varObj.name.match(/^PrintPromptUsername_[0-9a-zA-Z]{11}$/) == null &&
varObj.name.match(/^PrintPromptWindowQuizVar_[0-9a-zA-Z]{11}$/) == null){

variableList.push(varObj);
}
}
document.body.removeChild(scriptElem);
window.globalProvideData = origGlobalProvideData;
callback(variableList);
}
document.body.appendChild(scriptElem);
}
Raf Van Ermengem

This is awesome! Thank you for this script!
Could it work to add a setInterval() to the refreshVars() so that the variables get updated automatically?

Edit: I have been looking into creating a Chrome/Edge extension out of your code but my javascript knowledge is to low. The extension runs in a separate browserthread and I can not access the Articulate player function. Would you be interested in creating such an extension?

Alex del Solar

For debugging/tracking Storyline variables, take a look to SCORM Debugger. It is an online service that lets you upload your SCORM content and debug/test it. 

But the best thing is that supports content created with Storyline and it detects the project's internal variables. While you play your content, you can see the value of all variables in real-time, so it is perfect to see what is happening.

Also you can setup "breakpoints", for instance, you can tell the debugger to alert you when a certain variable changes its value. And you can setup "restore points" to get back to any previous state of your course.

This is the website of the debugger: scormtools.net

I hope this help you!

Orest Mykyta

Sorry for the very late reply.. i must have missed the notification..

Yes, adding a setInterval on the refreshVars variable should work to auto refresh. However, it might make it annoying if you are trying to type in a value to change the variable - it will keep reverting the value as you try to type. Maybe if you make the refresh rate slow enough you could sneak in a change before it refreshes.

 

Adding this line will make it refresh every 5 seconds:

setInterval(refreshVars, 5000);