An over view of events and public methods that are Question-specific, rather than assessment-wide.
Introduction
This tutorial is a basic overview of these features and will include code snippets for several of the events and methods discussed in the documentation. As part of our 200 series, this tutorial assumes that you are comfortable with JavaScript, and you are familiar with the Learnosity Items API and/or Questions API.
Binding and Trapping Events
on()
method—a common mechanism found in many frameworks, including Backbone.js, after which this approach was modelled. The on()
method triggers its callback every time a corresponding event occurs, until the listener is explicitly removed using the off()
method.The second approach is to bind a listener to a Question for a single occurrence of the appropriate event, using the once()
method. Instead of you removing the binding at the time of your choosing, the once()
method automatically removes the event listener from the Question after the first event is trapped.
Both methods take two arguments: an event to listen for, and a callback function to execute when that event is received. Both methods can listen for the following Question-level events:
changed
indicates the student initiated or changed a response to the Question,validated
the Question was validated by Learnosity to determine if the student response is correct or incorrect, ormasked
the student masked a distractor, such as striking through it, as a visual cue to eliminate it from consideration while working through the Question.
Snippet 1: Viewing Question and Response Data
Note Uses the validated
event, and the once()
, getQuestion()
, and getResponse()
methods
The following snippet shows a jQuery each
loop using the once()
method to apply a listener to every Question in the itemsApp
instance of the Items API. The first time the listener detects the validated
event, the sample showQuestionAndResponse
function is triggered and logs to the console the Question and response JSON returned by the getQuestion()
and getResponse()
public methods:
$.each(itemsApp.questions(), function( responseID, question ) {
question.once("validated", showQuestionAndResponse);
function showQuestionAndResponse() {
console.log(question.getQuestion());
console.log(question.getResponse());
}
}
This can be handy for debugging, as you can inspect the Question data and validation object along with the student response. Because this snippet uses the once()
method, you don’t need to remove the callback manually.
Snippet 2: Show Score Upon Validation
Note Uses the on()
, isValid()
, getScore()
, getMetadata()
, and off()
methods.
The snippet below binds the validated event to each Question using the on() method. When validated, the score
and max_score
are retrieved from the Question data using the getScore()
method. The isValid()
method is also used to check to see if the student’s response is correct. If so, a congratulatory message is prepended to the score.
The getMetadata()
method is used to parse the metadata object from which the sheet_reference
(the ID of the DOM element containing the item) is retrieved. If the required div already exists, the score is added to the div. Otherwise, the div and score are both appended to the Item parent.
$.each(itemsApp.questions(), function(responseID, question) {
question.on("validated", showScore);
function showScore() {
var score = question.getScore();
var scoreString = (question.isValid()) ?
"Congratulations! " : "";
scoreString += "Score: " + score.score + " of " +
score.max_score;
var meta = question.getMetadata();
var item = $(".learnosity-item[data-reference=" +
meta.sheet_reference + "]");
var scoreDiv = item.find("div.score");
if (scoreDiv.length) {
scoreDiv.html(scoreString);
} else {
item.append('<div class="score">' + scoreString +
'</div>');
}
}
});
Event listeners bound with the on()
method can be removed with the off()
method. The latter takes two arguments: the event and listener pair you want to remove.
$.each(itemsApp.questions(), function( responseID, question ) {
question.off("validated", showQuestionAndResponse);
});
Snippet 3: Confirming that All Questions are Attempted Before Submitting
Note Uses isAttempted()
method
The Assess rendering type offers the option of automatically warning a student if any Questions remain unattempted when submitting an assessment. This feature is not provided when rendering assessments inline, but you can use the isAttempted()
method to add this feature on your own.
The intent of inline rendering in the Items API is to give developer and designer control over all facets of the assessment, including buttons. As such, buttons for submit, save, and so on, are not automatically provided. The snippet that follows uses a simple custom button to submit the assessment after first checking to see if every Question has been attempted. If not all Questions have been attempted, it prompts the user to be sure he or she wants to submit the assessment. If so, the submit() method of the Items API instance is called.
$("#submitBtn").click(function() {
var okToSubmit = true;
$.each(itemsApp.questions(), function(responseID, question) {
if (!question.isAttempted()) {
okToSubmit = confirm("One or more questions have not been
attempted. Are you sure you want to submit?");
return false;
}
});
if (okToSubmit) { itemsApp.submit(); }
});
You can also optionally react to submission successes and failures by adding a submit settings object to the submit()
method above. The following lines log a message and the response IDs submitted when successful, or a message and event data when the submission fails.
$.each(itemsApp.questions(), function( responseID, question ) {
question.off("validated", showQuestionAndResponse);
});
To use this object, just pass it to Learnosity as an argument of the aforementioned submit()
method, as shown in the edited line below (change in bold):
if (okToSubmit) { itemsApp.submit(submitSettings); }
Note Users of the Assess rendering type can also customize this feature. As part of the configuration property, developers can prevent submission until a threshold percentage (0-100) of Questions are attempted (or valid). The JSON below requires that all Questions are attempted before submitting.
"submit_criteria": {
"type": "attempted",
"threshold": 100
}
Triggering Events Manually
Using Learnosity’s Provide Instant Feedback feature, a student can validate a Question at will by clicking the Check Answers button that appears with each Question. If you would rather build your own control for this purpose, you can manually trigger validation using the validate()
method.
Snippet 4: Validate All Questions Manually
validate()
method, and discusses the trigger()
method.The following snippet uses a custom button to validate an entire inline assessment at once, rather than Question by Question as is common with the Provide Instant Feedback feature.
$("#validateBtn").click(function() {
$.each(itemsApp.questions(), function(responseID, question) {
question.validate();
});
});
Additionally, you can trigger the changed event manually using the trigger()
method.
question.trigger("changed");
(You can also trigger the validated event separately, or the masked event when working with distractor masking. We’ll talk about masking in a moment.)
Special Use Cases
Specific Question types support additional Question-level public methods. (For each of the following quick snippets, ‘60001’ is a sample response ID for an applicable Question.)
begin()
, pause()
, stop()
: Self-explanatory methods used to control audio Questions.
var audioQuestion = itemsApp.question("60001");
audioQuestion.begin();
mapValidationMetadata()
: This method is commonly used when displaying distractor rationale—in particular, a per-response rationale when Questions that include more than one distractor (such as multiple choice) appear in an assessment. The method creates an object that maps distractor rationale to its corresponding distractor in correct, incorrect, and unattempted responses. Check out Tutorial 202: Displaying Distractor Rationale to see this method in action.
isMaskable()
, masking()
: These methods are used with Question types, such as multiple choice, that support masking distractors—visual cues that make it easier to eliminate choice by process of elimination. The first method seeks a boolean that describes if the Question type is maskable. The second method enables/disables masking with a given mask ui-style.
var question = myLearnosityApp.question("60001");
if (question.isMaskable()) {
question.masking(true);
}
What you learned
In this tutorial we learned how to use events and public methods to parse Question-specific data, and react to events at the Question level, rather than at the assessment level. This overview demonstrated code use via basic snippets, and points to additional uses of this approach for further discussion.
Where to Next?
In Tutorial 202, we’ll put these skills to work by building an assessment that uses Question-level events and public methods to display distractor rationale.