View All Variables for debugging

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)
7 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);
}
Bart Van den Brande

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?