QuizScoring1.png

CUSTOM QUIZ SCORING IN ADOBE CAPTIVATE

Steven Warwick
February 25, 2017

Adobe Captivate 9 has a selection of built-in quiz processes that are designed to cover the majority of scenarios. Multiple choice, true/false, blank fill, matching and a few other types are supported. Incorporating quizzes is always a bit of a struggle, not only in developing good quiz concepts, but in developing user feedback, structuring the user journey through the course given the results, scoring strategies, and ensuring that any reporting functions to the LMS capture the right information and can be easily searched and interpreted. Adobe can only anticipate a limited range of cases to be modeled in the Captivate user interface as, after a point the UI becomes unworkable. As designers delve into more unique user experiences, the only practical strategy is to dive “behind the scenes” and develop JavaScript-controlled user interactions. This is a very rich area for creativity, as through JavaScript, pretty much any user interaction can be developed, but is hampered by the fact that Adobe provides no documentation on the very extensive quiz control library that is loaded as part of the course player. With work, it is possible to gain an understanding of this very rich set of tools, and with that comes the ability to circumvent the limitations of the Captivate UI in creating unique experiences. Here, we will show how to override the internal scoring process. This has been tested on multiple choice quizzes so far, but the concepts may be applicable to the other quiz types. The function that we will show will enable you to assign any point value to the users answers. There need not be a single “right” answer. Scores can also be based on other real-time parameters, such as how many times the user has taken the quiz, and how long they have taken to submit. Scores are reported to the LMS through Captivate, no special communication is needed.

The following information is targeted to folks with a relatively good background in JavaScript.

WHERE TO PUT THE JAVASCRIPT?

We use an external file to incorporate all JavaScript in our applications. It is far easier to manage and to make changes in near-real time. To do this, we use the “Execute Javascript at On Enter” function with the following small script to the first page of captivate presentation:

$(‘body’).append(‘<script src=”/<path to file>/myscript.js” async=”false”></script>’);

This path is from the root of the webserver and in our case, we don’t include the “http://url/…” to make this work wherever the course module is loaded

TAKING OVER THE SCORING FUNCTION

We will skip the majority of the gory details of how Captivate structures the quiz data and all the functions needed to manage the interaction. For the purpose of getting to the heart of the matter, you only need to know the following: Quiz pages have an “ID” that is needed to find the quiz data. The IDs all start with “Slidexxxxx” To get this ID, the easiest is to just find it using jQuery:

var slideID = $('[id^=Slide]').attr("id");

The quiz data is easily accessed using the following Captivate function:

var quizObject = cp.getQuestionObject(slideID);

The quizObject is very rich. It not only contains all of the quiz data, but also all of the functions necessary to manage this data. There is one critical function that, after everything, decides on what score to give a question. A question is scored regardless of whether the answer is “right or wrong” so this function is always called. quizObject.getQuestionScoredPoints() It is not necessary to know anything about the rest of the Captivate code, only that the value returned by this function will be captured as the score for a quiz question. By “overloading” this function, we can create an arbitrary function that determines score based on any information we wish. The following provides an example of how to overload this function, and information on the most likely variables one would use to create a custom scoring function:

// save a reference to the original function
saveGetScore = quizObject.__proto__.getQuestionScoredPoints
//overload the function
quizObject.__proto__.getQuestionScoredPoints =function () {

console.log('---- question Info -----');
console.log("question interaction id:" + this.questionData.iid);
console.log("answered correctly:" + this.getAnsweredCorrectly());
console.log("correct answer:" + this.getCorrectAnswerAsString());
console.log("chosen answer:" + this.getChosenAnswerAsString());
console.log("current attempt:" + this.currentAttempt);
console.log("number of attempts:" + this.numberOfAttempts);
console.log("end Time:" + this.endTime);
console.log("start Time:" + this.startTime);
// the question text
console.log("question text:" + this.questionData.qt);
// some internal ID information
console.log("question number:" + this.questionData.qnq);
console.log("slide number:" + this.m_slideIndex);
console.log("question object name:" + this.questionObjName);
console.log("answergroup:" + this.questionObjName);
console.log("-------------------");
// a returned score
return 100;
}

A typical output from this, after submitting a quiz question looks like:

---- question Info -----
question interaction id:10686
answered correctly:true
correct answer:B
chosen answer:B
current attempt:1
number of attempts:1
end Time:Sat Feb 25 2017 12:03:29 GMT-0500 (Eastern Standard Time)
start Time:Sat Feb 25 2017 12:03:20 GMT-0500 (Eastern Standard Time)
question text:Choose which is the right answer
question number:0
slide number:0
question object name:Slide10662q0
answergroup:Slide10662q0

A COMPLETE EXAMPLE

The “interaction ID” shows up on the Captivate quiz tab when you are making the quiz page and can be set to a convenient value if you want. With the variables listed above, it is possible to develop a wide range of scoring systems. The following shows the code for a complete partial credit scored question assuming there are five possible answers. ‘C’ is the best at 5 points, ‘A’ and ‘E’ are the worst at 1 point:

var slideID = $('[id^=Slide]').attr("id");
var quizObject = cp.getQuestionObject(slideID);
var saveGetScore = quizObject.__proto__.getQuestionScoredPoints;
quizObject.__proto__.getQuestionScoredPoints =function () {

var iid = this.questionData.iid;
if ( iid != "10686" ) {
// call the regular scoring function if not this question
return saveGetScore.call(this);
}
var chosen = this.getChosenAnswerAsString());
var score = 0
if (chosen == "A") { score = 1;}
if (chosen == "B") { score = 2;}
if (chosen == "C") { score = 5;}
if (chosen == "D") { score = 3;}
if (chosen == "E") { score = 1;}

return score;
}

From here, all kinds of interesting scoring techniques can be devised! Although the Captivate code base is not for the feint-hearted, with some work, we can use this base to create all kinds of interesting interactions!