Forum Discussion
Global scope for Javascript variables in Storyline
Hi everyone,
One year later and I'm asked to build a tool that helps tracking user progress, but not through how many slides have been seen/accessed as Storyline allows it, but through how many buttons have been clicked (inside a list of which buttons to track) inside several slides.
This tool (set of scripts) will be used by co-workers who have no skill at all in coding, si I try to make it as easy as possible to use.
I first made an Excel sheet that contains a table they have to fill. The table goes like this :
slide1name | slide2name | etc.
button1A | button2A | etc.
button1B | button2B | etc.
| button2C |
first line contains the slide names we want to track (not storyline names or references, but decided by my co-worker)
Then for each slide name, the column below contains the names of the buttons whose click we want to track (once again, those names are not from storyline but decided by my co-worker).
Note that the number of slides and the number of buttons per slide may change from one project to the other (I based my excel on a 20 slides / 20 buttons per slide max, which is far enough).
Then I use in excel formulas to create the javascript line that declares a multidimensionnal array :
[[list of slide names],[[[list of button names of 1st slide],[list of their states]],[ (same for slide 2) ],[etc.]]]
for example, with 3 slides named "sliA", "sliB" and "sliC" ; sliA contains 2 buttons to track, sliB 3 buttons and sliC 4 buttons, the js declaration of the array is
let tabProgress=[['sliA','sliB','sliC'],[[['butA1','butA2'],[0,0]],[['butB1','butB2','butB3'],[0,0,0]],[['butC1','butC2','butC3','butC4'],[0,0,0,0]]]];
my idea is to call javascript functions I place in a js file loaded thank's to Math globalScript solution :
- to get or set the state for any given button in a given slide,
- to calculate the percentage of buttons clicked for a given slide,
- to calculate the percentage of buttons clicked for all slides.
I added a simple "getGlobalValue" function to Math's globalScript.js to get the array before passing to my functions.
Here's the globalScript file content :
console.log("globalScripts.js loaded");
/*
globObj is a global Object to save data too
*/
const globObj = {};
// we could use multiple objects and pass/read data
const semiGlobObj = {};
/*
Global functions that can be called from anywhere in Storyline.
Any needed functions can be added here and you can call them directly in Storyline.
*/
/*
This function creates properties on any given object that then can be reused anywhere.
Eval is needed to get the proper Object and bracket notation [] is needed to convert
the input to a literal name for the property
*/
function setGlobalValue(_val,_prop,_obj){
console.log("set: "+_obj+" | "+_prop);
let obj2Use = eval(_obj);
Object.defineProperties(obj2Use, {
[_prop]: {
value: _val,
writable: true
}
});
console.log("set: "+_obj+" | "+_prop+" = "+obj2Use[_prop]);
}
/* added by E.Nédélec
*/
function getGlobalValue(_prop,_obj) {
console.log("get: "+_obj+" | "+_prop);
obj2Use = eval(_obj);
console.log ("return : " + obj2Use[_prop].value);
return obj2Use[_prop].value;
}
/*
Function to loop and iterate an Object in Storyline.
Returns a string or an array depending on chosen _desiredoutput
*/
function iterateObject(_obj,_desiredoutput){
const propsArr = Object.getOwnPropertyNames(_obj);
let valuesArr = [];
console.log(propsArr);
let str = "";
for(var i = 0; i < propsArr.length; i++){
let prop = propsArr[i];
console.log("prop: "+prop);
let val = globObj[prop];
valuesArr.push(globObj[prop]);
console.log("val: "+val);
str += propsArr[i]+" "+val+"\n";
}
if(_desiredoutput=="array"){
return propsArr
}else{
return str;
}
}
Now what's driving me nuts is that I can get my array back. Here's what I read in the console :
globalScripts.js loaded globalScripts.js:1:9
1 JS / story_content/WebObjects/6Tdp61PnyWP/globals/globalScripts.js loaded. user.js:28:15
jsProgess.js loaded jsProgress.js:1:9
2 JS / story_content/WebObjects/6Tdp61PnyWP/globals/jsProgress.js loaded. user.js:28:15
set: globObj | tabProgress globalScripts.js:21:17
set: globObj | tabProgress = sliA,sliB,sliC,butA1,butA2,0,0,butB1,butB2,butB3,0,0,0,butC1,butC2,butC3,butC4,0,0,0,0 globalScripts.js:29:17
get: globObj | tabProgress globalScripts.js:35:10
return : undefined
The array seems properly stored through Math's function "setGlobalValue", as shown by "set" message in the console).
My "getGlobalValue" function is called as we can see "get: globObj | tabProgress".
But why does it return "undefined" ?
Related Content
- 9 months ago