Forum Discussion
Text entry variables and xAPI
Client wants a comment box on each question in a course. Then he actually wants to know what was written in that box. I'm hoping someone will say I'm doing this the hard way and offer easier alternative(s).
I've been sending an xAPI statement for each textentry variable, adjusting each statement to capture the unique variable name. I have over 130 variables for these comments. I asked ChatGPT for help using JS and she thought she had a solution but then agreed GetVarNames is not a viable function. She gave me code that might work if I type in each variable name. She thinks there is no way to download a list of variable names. That can't be? Please help me before I retype all these variable names.
7 Replies
- SamHillSuper Hero
Hi ElizabethPat123 this is more of a thought bubble than a solution.
I'm wondering if rather than using a Storyline variable you could use the Slide.Id variable to associate the use note with the relevant slide. Each slide has a unique ID, for example 5rUJg6NfRQQ.
Could use use this with xAPI to Set/Get the comments for each slide?
- PhilMayorSuper Hero
I like Sam's idea, for your xAPI statement you could either send all the statements at the end, use numbered variables and loop through that would save loads of time rewriting. Or you could use numbered variables in storyline and then set a number variable at timeline start that corresponds to the variable being used and use code to combine the two, so you in effect use the same code on every slide and it pulls the right variable. Both would save time.
- NedimCommunity Member
We can dynamically gather these variables and values (key | value pair), store variables and their values in a single variable (xapiResponse), and send that information in an xAPI format but only with a consistent naming pattern (e.g., comment_1, comment_2, comment_3, ... comment_n). Then we can use JavaScript to retrieve each variable’s value and build a response that will be sent in the xAPI statement.
Example JavaScript:
var totalVars = 130; // less or more var responses = []; for (var i = 1; i <= totalVars; i++) { var varName = "comment_" + i; var varValue = getVar(varName); if (varValue && varValue.trim() !== "") { responses.push(varName + ": " + varValue); } } var jointResponse = responses.join(" | "); setVar("xapiResponse", jointResponse); console.log("xapiResponse set to:", jointResponse);
xAPI statement:
In this example, I used the JavaScript code above along with a single xAPI statement, which is executed on the master slide when it loads.
However, this approach can be further optimized by modifying the script to only include variable | value pairs relevant to the current slide, rather than sending all comment variables and values at once.
I personally prefer sending the xAPI statement at the end, after all text entry fields have been filled. This ensures that all user inputs are captured, reducing redundant xAPI calls.
Again, this approach is only possible if a structured variable naming convention is planned ahead and followed from the beginning.- PhilMayorSuper Hero
This was exactly what I meant. And if you append _# then you can quickly create your variables by copy and paste.
- ElizabethPat123Community Member
I'm liking the idea of one statement at the end because it's too easy to have a typo in 130 different statements. Thank you for the code.
Right now I'm using the question name (e.g., Comment_Mary1, Comment_Mary2, Comment_Mark1) as the comment name. The questions are named not numbered because we are pulling from a test bank (learner confused if they get questions 37, 45, 63?).
If I rename all the comments 1, 2, 3, and pull them in a list at the end, how will I know which comment refers to what question?
- NedimCommunity Member
Now it’s getting more complicated. The script above assumes a specific pattern and stores comments based on their index number. However, I see that your comment variables follow a different, more complex pattern, which seems harder to target. I’m concerned I might lose control over this as it becomes more dynamic. Here is updated script that we can try to target all comments based on your pattern:
var totalVars = 130; var people = ["Mary", "Mark"]; var responses = []; for (var p = 0; p < people.length; p++) { var person = people[p]; for (var i = 1; i <= totalVars; i++) { var varName = "Comment_" + person + i; var varValue = getVar(varName); if (varValue && varValue.trim() !== "") { responses.push(varName + ": " + varValue); } } } var jointResponse = responses.join(" | "); setVar("xapiResponse", jointResponse); console.log("xapiResponse set to:", jointResponse);
This way, you can add as many names as needed to the 'people' array variable. For example, if you have variables like Comment_John1, Comment_John2, etc., the 'people' variable should be updated to ["Mary", "Mark", "John"]. Again, all variables need to follow the same pattern for this to work properly. In this case, you would not have to rename your variables. If your question name is Comment_Mary1 it will show in the statement followed by response. With this update, my xapiResponse statement would appear as:
- NedimCommunity Member
Moreover, we could download all responses into a CSV file to make them more readable. Is this an option for you? The data could be sent to the server or processed server-side LMS, but I can't assist with that. In the example below, I used a button to download all responses in CSV format