mirror of
https://github.com/andre-wojtowicz/elearning-scorm-exam-template.git
synced 2024-11-03 13:55:28 +01:00
290 lines
9.1 KiB
JavaScript
290 lines
9.1 KiB
JavaScript
/*
|
||
Source code created by Rustici Software, LLC is licensed under a
|
||
Creative Commons Attribution 3.0 United States License
|
||
(http://creativecommons.org/licenses/by/3.0/us/)
|
||
|
||
Want to make SCORM easy? See our solutions at http://www.scorm.com.
|
||
|
||
This example demonstrates the use of more advanced runtime calls in a multi-page SCO. It
|
||
includes a demonstration of reporting interactions (question results), and progress
|
||
towards specific learning objective. It also demonstrates using the manifest to specify
|
||
a passing score rather than hard coding the passing score within the content.
|
||
*/
|
||
|
||
|
||
//Include the standard ADL-supplied API discovery algorithm
|
||
|
||
|
||
///////////////////////////////////////////
|
||
//Begin ADL-provided API discovery algorithm
|
||
///////////////////////////////////////////
|
||
|
||
var nFindAPITries = 0;
|
||
var API = null;
|
||
var maxTries = 500;
|
||
|
||
// The ScanForAPI() function searches for an object named API
|
||
// in the window that is passed into the function. If the object is
|
||
// found a reference to the object is returned to the calling function.
|
||
// If the instance is found the SCO now has a handle to the LMS
|
||
// provided API Instance. The function searches a maximum number
|
||
// of parents of the current window. If no object is found the
|
||
// function returns a null reference. This function also reassigns a
|
||
// value to the win parameter passed in, based on the number of
|
||
// parents. At the end of the function call, the win variable will be
|
||
// set to the upper most parent in the chain of parents.
|
||
function ScanForAPI(win)
|
||
{
|
||
while ((win.API == null) && (win.parent != null)
|
||
&& (win.parent != win))
|
||
{
|
||
nFindAPITries++;
|
||
if (nFindAPITries > maxTries)
|
||
{
|
||
return null;
|
||
}
|
||
win = win.parent;
|
||
}
|
||
return win.API;
|
||
}
|
||
|
||
// The GetAPI() function begins the process of searching for the LMS
|
||
// provided API Instance. The function takes in a parameter that
|
||
// represents the current window. The function is built to search in a
|
||
// specific order and stop when the LMS provided API Instance is found.
|
||
// The function begins by searching the current window<6F>s parent, if the
|
||
// current window has a parent. If the API Instance is not found, the
|
||
// function then checks to see if there are any opener windows. If
|
||
// the window has an opener, the function begins to look for the
|
||
// API Instance in the opener window.
|
||
function GetAPI(win)
|
||
{
|
||
if ((win.parent != null) && (win.parent != win))
|
||
{
|
||
API = ScanForAPI(win.parent);
|
||
}
|
||
if ((API == null) && (win.opener != null))
|
||
{
|
||
API = ScanForAPI(win.opener);
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////
|
||
//End ADL-provided API discovery algorithm
|
||
///////////////////////////////////////////
|
||
|
||
|
||
//Create function handlers for the loading and unloading of the page
|
||
|
||
//Constants
|
||
var SCORM_TRUE = "true";
|
||
var SCORM_FALSE = "false";
|
||
var SCORM_NO_ERROR = "0";
|
||
|
||
//Since the Unload handler will be called twice, from both the onunload
|
||
//and onbeforeunload events, ensure that we only call Terminate once.
|
||
var terminateCalled = false;
|
||
|
||
//Track whether or not we successfully initialized.
|
||
var initialized = false;
|
||
|
||
function ScormProcessInitialize(){
|
||
var result;
|
||
|
||
GetAPI(window);
|
||
|
||
if (API == null){
|
||
$.toaster('Could not establish a connection with the LMS.\n\nYour results may not be recorded.', 'Error', 'danger');
|
||
return;
|
||
}
|
||
|
||
result = API.LMSInitialize("");
|
||
|
||
if (result == SCORM_FALSE){
|
||
var errorNumber = API.LMSGetLastError();
|
||
var errorString = API.LMSGetErrorString(errorNumber);
|
||
var diagnostic = API.LMSGetDiagnostic(errorNumber);
|
||
|
||
var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
|
||
|
||
$.toaster("Could not initialize communication with the LMS.\n\nYour results may not be recorded.\n\n" + errorDescription, 'Error', 'danger');
|
||
return;
|
||
}
|
||
|
||
initialized = true;
|
||
}
|
||
|
||
function ScormProcessTerminate(){
|
||
|
||
var result;
|
||
|
||
//Don't terminate if we haven't initialized or if we've already terminated
|
||
if (initialized == false || terminateCalled == true){return;}
|
||
|
||
result = API.LMSFinish("");
|
||
|
||
terminateCalled = true;
|
||
|
||
if (result == SCORM_FALSE){
|
||
var errorNumber = API.LMSGetLastError();
|
||
var errorString = API.LMSGetErrorString(errorNumber);
|
||
var diagnostic = API.LMSGetDiagnostic(errorNumber);
|
||
|
||
var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
|
||
|
||
$.toaster("Could not terminate communication with the LMS.\n\nYour results may not be recorded.\n\n" + errorDescription, 'Error', 'danger');
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
The onload and onunload event handlers are assigned in launchpage.html because more processing needs to
|
||
occur at these times in this example.
|
||
*/
|
||
//window.onload = ScormProcessInitialize;
|
||
//window.onunload = ScormProcessTerminate;
|
||
//window.onbeforeunload = ScormProcessTerminate;
|
||
|
||
//There are situations where a GetValue call is expected to have an error
|
||
//and should not alert the user.
|
||
function ScormProcessGetValue(element, checkError){
|
||
|
||
var result;
|
||
|
||
if (initialized == false || terminateCalled == true){return;}
|
||
|
||
result = API.LMSGetValue(element);
|
||
|
||
if (checkError == true && result == ""){
|
||
|
||
var errorNumber = API.LMSGetLastError();
|
||
|
||
if (errorNumber != SCORM_NO_ERROR){
|
||
var errorString = API.LMSGetErrorString(errorNumber);
|
||
var diagnostic = API.LMSGetDiagnostic(errorNumber);
|
||
|
||
var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
|
||
|
||
$.toaster("Could not retrieve a value from the LMS.\n\n" + errorDescription, 'Error', 'danger');
|
||
return "";
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
function ScormProcessSetValue(element, value){
|
||
|
||
var result;
|
||
|
||
if (initialized == false || terminateCalled == true){return;}
|
||
|
||
result = API.LMSSetValue(element, value);
|
||
|
||
if (result == SCORM_FALSE){
|
||
var errorNumber = API.LMSGetLastError();
|
||
var errorString = API.LMSGetErrorString(errorNumber);
|
||
var diagnostic = API.LMSGetDiagnostic(errorNumber);
|
||
|
||
var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
|
||
|
||
$.toaster("Error - Could not store a value in the LMS.\n\nYour results may not be recorded.\n\n" + errorDescription, 'Error', 'danger');
|
||
return;
|
||
}
|
||
|
||
}
|
||
|
||
function ScormCommitChanges(){
|
||
|
||
var result;
|
||
|
||
if (initialized == false || terminateCalled == true){return;}
|
||
|
||
result = API.LMSCommit("");
|
||
|
||
if (result == SCORM_FALSE){
|
||
var errorNumber = API.LMSGetLastError();
|
||
var errorString = API.LMSGetErrorString(errorNumber);
|
||
var diagnostic = API.LMSGetDiagnostic(errorNumber);
|
||
|
||
var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
|
||
|
||
$.toaster("Error - Could not commit changes to the LMS.\n\nYour results may not be recorded.\n\n" + errorDescription, 'Error', 'danger');
|
||
return;
|
||
}
|
||
|
||
}
|
||
|
||
function ScormLessonCompleted()
|
||
{
|
||
if (ScormProcessGetValue("cmi.core.lesson_status") == "completed")
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
function ScormLessonPassed()
|
||
{
|
||
if (ScormProcessGetValue("cmi.core.lesson_status") == "passed")
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
function ScormLessonNotAttempted()
|
||
{
|
||
if (ScormProcessGetValue("cmi.core.lesson_status") == "not attempted")
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
function ScormMarkAsCompleted()
|
||
{
|
||
ScormProcessSetValue("cmi.core.lesson_status", "completed");
|
||
}
|
||
|
||
function ScormMarkAsIncomplete()
|
||
{
|
||
ScormProcessSetValue("cmi.core.lesson_status", "incomplete");
|
||
}
|
||
|
||
function ScormMarkAsPassed()
|
||
{
|
||
ScormProcessSetValue("cmi.core.lesson_status", "passed");
|
||
}
|
||
|
||
function ScormMarkAsFailed()
|
||
{
|
||
ScormProcessSetValue("cmi.core.lesson_status", "failed");
|
||
}
|
||
|
||
function ScormMarkAsBrowsed()
|
||
{
|
||
ScormProcessSetValue("cmi.core.lesson_status", "browsed");
|
||
}
|
||
|
||
function ScormSaveAnswer(id, type, student_response, pattern, result)
|
||
{
|
||
ScormProcessSetValue("cmi.interactions." + (id-1) + ".id", id);
|
||
ScormProcessSetValue("cmi.interactions." + (id-1) + ".type", type);
|
||
ScormProcessSetValue("cmi.interactions." + (id-1) + ".student_response", student_response);
|
||
ScormProcessSetValue("cmi.interactions." + (id-1) + ".correct_responses.0.pattern", pattern);
|
||
ScormProcessSetValue("cmi.interactions." + (id-1) + ".result", result);
|
||
}
|
||
|
||
function ScormSaveScore(score, total, sessionTime)
|
||
{
|
||
ScormProcessSetValue("cmi.core.score.raw", score);
|
||
ScormProcessSetValue("cmi.core.score.min", 0);
|
||
ScormProcessSetValue("cmi.core.score.max", total);
|
||
ScormProcessSetValue("cmi.core.lesson_status", "passed");
|
||
ScormProcessSetValue("cmi.core.session_time", sessionTime);
|
||
|
||
var comment = ScormProcessGetValue("cmi.comments");
|
||
|
||
ScormProcessSetValue("cmi.comments", comment + (new Date()).toString() + "; ");
|
||
}
|