Workaround To Setting A “cmi.interaction.n.student_response” Reference

Published on
-
2 min read

One the drawbacks of using SCORM 1.2 is the inability of being able to read a “cmi.interaction.n.student_response” reference. In my mind this is very strange. Why allow a value to be written to but not read? Being able to read a users response to a question is an important feature. If anyone knows the answer to why this is the case, then please leave a comment.

I guess under normal circumstances having a student_response reference that is write only would suffice. Unfortunately, my SCORM content required user’s to review all questions along with their submitted answers.

Even though SCORM 2004 has corrected its previous error of misjudgement, what are developers who are forced into using SCORM 1.2 (like me) to do? Thankfully, there is a really useful reference called “cmi.suspend_data” that allows us to store any string value we want (up to 4096 characters). This is what I will use to store all users responses. I created a “semi-colon delimited string” to parse into the suspend_data reference. For example:

q1=a;q2=1,4,7;q3=d;q4=air;q5=c

The following code can be used to add/update values within the suspend_data:

/*******************************************************************************
**
** Functions to Add/Update CMI.suspend_data field
**
*******************************************************************************/
function EditSuspendData(suspendId, suspendValue) {
    var suspendData = doGetValue("cmi.suspend_data");

    if (!SuspendDataExists(suspendId)) {
        AddSuspendData(suspendId, suspendValue, suspendData);
    }
    else {
        UpdateSuspendData(suspendId, suspendValue, suspendData);
    }
}

function AddSuspendData(suspendId, suspendValue, sdList) {
    if (sdList == null || sdList.length == 0) {
        sdList = suspendId + "=" + suspendValue;
    }
    else {
        sdList += ";" + suspendId + "=" + suspendValue;
    }

    doSetValue("cmi.suspend_data", sdList);
}

function UpdateSuspendData(suspendId, suspendValue, sdList) {
    var sdArr = sdList.split(';');

    for (i = 0; i < sdArr.length; i++) {
        pieces = sdArr[i].split('=');
        if (pieces[0] == suspendId) {
            pieces[1] = suspendValue;
            sdArr[i] = pieces[0] + '=' + pieces[1];
            break;
        }
    }

    //put the string back together;
    var sdList = '';

    for (i = 0; i < sdArr.length; i++) {
        marker = (i == 0) ? '' : ';';
        sdList += marker + sdArr[i];
    }

    doSetValue("cmi.suspend_data", sdList);
}

function GetSuspendDataValue(suspendId) {
    var sdArr = doGetValue("cmi.suspend_data").split(';');

    var answer = "";

    if (sdArr != "") {
        for (i = 0; i < sdArr.length; i++) {
            var qPieces = sdArr[i].split('=');

            if (qPieces[0] == suspendId) {
                answer = qPieces[1];

                NavButtonInactive("submit-button", false);
                break;
            }
        }
    }

    return answer;
}

function SuspendDataExists(suspendId) {
    var sdArr = doGetValue("cmi.suspend_data").split(';');

    var sdFound = false;

    for (i = 0; i < sdArr.length; i++) {
        var qPieces = sdArr[i].split('=');

        if (qPieces[0] == suspendId) {
            sdFound = true;
            break;
        }
    }

    return sdFound;
}

You can now easily add/update/get your question values or any other values you store in your suspend_data. The functions you will need to use are:

  • GetSuspendDataValue() – to retrieve a value.
  • EditSuspendData() – to add/update a value.

Before you go...

If you've found this post helpful, you can buy me a coffee. It's certainly not necessary but much appreciated!

Buy Me A Coffee

Leave A Comment

If you have any questions or suggestions, feel free to leave a comment. Your comment will not only help others, but also myself.