Simplify Scorm
Simplify Scorm is a Javascript API for SCORM 1.2 and SCORM 2004 Run-Time Implementations.
The purpose of this software is to provide a quick, easy way to implement both a SCORM 1.2 Run-Time API and a SCORM 2004 Run-Time API, and integrate them with your backend API.
SCORM has defined the data model required for this integration here: http://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/
To use, you must include the scormAPI.js file, or the minified version scormAPI.min.js, on the launching page of your SCORM 1.2 or SCORM 2004 application.
Hopefully this makes your life easier, and lets you get up and running much faster in your SCORM development!
Table of Contents
SCORM 1.2
Simplify Scorm will create a window.API object, required by SCORM 1.2, and will handle all the scorm interactions. Everything will be recorded on the object at window.API.cmi.
Listeners
For convenience, hooks are available for all the SCORM API Signature functions:
LMSInitialize,
LMSFinish,
LMSGetValue,
LMSSetValue,
LMSCommit,
LMSGetLastError,
LMSGetErrorString,
LMSGetDiagnostic
You can add your hook into these by adding a listener to the window.API object:
window.API.on("LMSInitialize", function() {
[...]
});
You can also listen for events on specific SCORM CMI elements:
window.API.on("LMSSetValue.cmi.core.student_id", function(CMIElement, value) {
[...]
});
Saving Your CMI
To save the CMI data, you can convert the CMI object to JSON and get a simplified data object to send to your backend API.
You should hook into the LMSFinish event to know when to save the finished session CMI data.
You can also hook into the LMSCommit event to save the progress along the way.
var simplifiedObject = window.API.cmi.toJSON();
Example output
{
"suspend_data":"viewed=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31|lastviewedslide=31|7#1##,3,3,3,7,3,3,7,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,11#0#b5e89fbb-7cfb-46f0-a7cb-758165d3fe7e=236~262~2542812732762722742772682802752822882852892872832862962931000~3579~32590001001010101010101010101001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001010010010010010010010010011010010010010010010010010010010010112101021000171000~236a71d398e-4023-4967-88fe-1af18721422d06passed6failed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105wrong110000000000000000000000000000000000~3185000000000000000000000000000000000000000000000000000000000000000000000000000000000~283~2191w11~21113101w41689~256~2100723031840~21007230314509062302670~2110723031061120000000000000000000~240~234531618~21601011000100000002814169400,#-1",
"launch_data":"",
"comments":"",
"comments_from_lms":"",
"core":{
"student_id":"",
"student_name":"",
"lesson_location":"",
"credit":"",
"lesson_status":"incomplete",
"total_time":"",
"lesson_mode":"normal",
"exit":"suspend",
"session_time":"0000:00:33.90",
"score":{
"raw":"",
"max":"100",
"min":""
}
},
"objectives":{
"childArray":[
]
},
"student_data":{
"mastery_score":"",
"max_time_allowed":"",
"time_limit_action":""
},
"student_preference":{
"audio":"",
"language":"",
"speed":"",
"text":""
},
"interactions":{
"childArray":[
{
"id":"Question14_1",
"time":"11:05:21",
"type":"choice",
"weighting":"1",
"student_response":"HTH",
"result":"wrong",
"latency":"0000:00:01.68",
"objectives":{
"childArray":[
{
"id":"Question14_1"
}
]
},
"correct_responses":{
"childArray":[
{
"pattern":"CPR"
}
]
}
}
]
}
}
Initial Values
If you want to initially load data from your backend API, you must do it before launching your SCORM 1.2 player. After the player has initialized, you will not be able to change any read-only values.
You can initialize your variables on the CMI object individually:
window.API.cmi.core.student_id = "123";
You can also initialize the CMI object in bulk by supplying a JSON object. Note that it can be a partial SCORM 1.2 CMI JSON object:
window.API.loadFromJSON(json);
Example JSON input
var json = {
"suspend_data": "viewed=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31|lastviewedslide=31|7#1##,3,3,3,7,3,3,7,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,11#0#b5e89fbb-7cfb-46f0-a7cb-758165d3fe7e=236~262~2542812732762722742772682802752822882852892872832862962931000~3579~32590001001010101010101010101001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001010010010010010010010010011010010010010010010010010010010010112101021000171000~236a71d398e-4023-4967-88fe-1af18721422d06passed6failed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105wrong110000000000000000000000000000000000~3185000000000000000000000000000000000000000000000000000000000000000000000000000000000~283~2191w11~21113101w41689~256~2100723031840~21007230314509062302670~2110723031061120000000000000000000~240~234531618~21601011000100000002814169400,#-1",
"core": {
"student_id": "123",
"student_name": "Bob The Builder"
},
"interactions": {
"childArray": [
{
"id": "Question14_1",
"time": "11:05:21",
"type": "choice",
"weighting": "1",
"student_response": "HTH",
"result": "wrong",
"latency": "0000:00:01.68",
"objectives": {
"childArray": [
{
"id": "Question14_1"
}
]
},
"correct_responses": {
"childArray": [
{
"pattern": "CPR"
}
]
}
}
]
}
};
Logging
By default, the API is set to only output errors in the Javascript console. You can change this by setting apiLogLevel to your desired level:
window.API.apiLogLevel = 1; // Log everything (Debug)
window.API.apiLogLevel = 2; // Log useful information, warning and errors
window.API.apiLogLevel = 3; // Log warnings and errors
window.API.apiLogLevel = 4; // Log errors only
window.API.apiLogLevel = 5; // No logging
Resetting
There may come a time when you need to reset the SCORM 1.2 API. Two methods are available.
You can create a new API and replace the one available on window.API:
window.API = new window.simplifyScorm.ScormAPI();
You can also create a new API and ask the existing one to use the new API instead.
This is useful when a SCORM object allows retrying after a failure, and you want to track each attempt in a separate CMI object.
SCORM objects often keep a reference to the original API, which is why this manipulation is needed:
var newAPI = new window.simplifyScorm.ScormAPI();
window.API.replaceWithAnotherScormAPI(newAPI);
window.API = newAPI;
SCORM 2004
Simplify Scorm will create a window.API_1484_11 object, required by SCORM 2004, and will handle all the scorm interactions. Everything will be recorded on the object at window.API_1484_11.cmi.
It is designed to work with the SCORM 2004 4th Edition specification. However, none of the ADL features have been implemented yet.
Listeners
For convenience, hooks are available for all the SCORM API Signature functions:
Initialize,
Terminate,
GetValue,
SetValue,
Commit,
GetLastError,
GetErrorString,
GetDiagnostic
You can add your hook into these by adding a listener to the window.API_1484_11 object:
window.API_1484_11.on("Initialize", function() {
[...]
});
You can also listen for events on specific SCORM CMI elements:
window.API_1484_11.on("SetValue.cmi.learner_id", function(CMIElement, value) {
[...]
});
Saving Your CMI
To save the CMI data, you can convert the CMI object to JSON and get a simplified data object to send to your backend API.
You should hook into the Terminate event to know when to save the finished session CMI data.
You can also hook into the Commit event to save the progress along the way.
var simplifiedObject = window.API_1484_11.cmi.toJSON();
Example output
{
"completion_status":"incomplete",
"completion_threshold":"",
"credit":"credit",
"entry":"",
"exit":"suspend",
"launch_data":"",
"learner_id":"",
"learner_name":"",
"location":"",
"max_time_allowed":"",
"mode":"normal",
"progress_measure":"",
"scaled_passing_score":"",
"session_time":"PT3M30S",
"success_status":"unknown",
"suspend_data":"viewed=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31|lastviewedslide=31|7#1##,3,3,3,7,3,3,7,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,11#0#b5e89fbb-7cfb-46f0-a7cb-758165d3fe7e=236~262~2542812732762722742772682802752822882852892872832862962931000~3579~32590001001010101010101010101001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001010010010010010010010010011010010010010010010010010010010010112101021000171000~236a71d398e-4023-4967-88fe-1af18721422d06passed6failed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105wrong110000000000000000000000000000000000~3185000000000000000000000000000000000000000000000000000000000000000000000000000000000~283~2191w11~21113101w41689~256~2100723031840~21007230314509062302670~2110723031061120000000000000000000~240~234531618~21601011000100000002814169400,#-1",
"time_limit_action":"continue,no message",
"total_time":"",
"comments_from_learner":{
"childArray":[
]
},
"comments_from_lms":{
"childArray":[
]
},
"interactions":{
"childArray":[
{
"id":"Question14_1",
"type":"choice",
"timestamp":"2018-08-26T11:05:21",
"weighting":"1",
"learner_response":"HTH",
"result":"wrong",
"latency":"PT2M30S",
"description":"",
"objectives":{
"childArray":[
{
"id":"Question14_1"
}
]
},
"correct_responses":{
"childArray":[
{
"pattern":"CPR"
}
]
}
}
]
},
"learner_preference":{
"audio_level":"1",
"language":"",
"delivery_speed":"1",
"audio_captioning":"0"
},
"objectives":{
"childArray":[
]
},
"score":{
"scaled":"",
"raw":"",
"min":"",
"max":""
}
}
Initial Values
If you want to initially load data from your backend API, you must do it before launching your SCORM 2004 player. After the player has initialized, you will not be able to change any read-only values.
You can initialize your variables on the CMI object individually:
window.API_1484_11.cmi.learner_id = "123";
You can also initialize the CMI object in bulk by supplying a JSON object. Note that it can be a partial SCORM 2004 CMI JSON object:
window.API_1484_11.loadFromJSON(json);
Example JSON input
var json = {
"learner_id": "123",
"learner_name": "Bob The Builder",
"suspend_data": "viewed=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31|lastviewedslide=31|7#1##,3,3,3,7,3,3,7,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,11#0#b5e89fbb-7cfb-46f0-a7cb-758165d3fe7e=236~262~2542812732762722742772682802752822882852892872832862962931000~3579~32590001001010101010101010101001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001010010010010010010010010011010010010010010010010010010010010112101021000171000~236a71d398e-4023-4967-88fe-1af18721422d06passed6failed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105wrong110000000000000000000000000000000000~3185000000000000000000000000000000000000000000000000000000000000000000000000000000000~283~2191w11~21113101w41689~256~2100723031840~21007230314509062302670~2110723031061120000000000000000000~240~234531618~21601011000100000002814169400,#-1",
"interactions": {
"childArray": [
{
"id": "Question14_1",
"type": "choice",
"timestamp": "2018-08-26T11:05:21",
"weighting": "1",
"learner_response": "HTH",
"result": "wrong",
"latency": "PT2M30S",
"objectives": {
"childArray": [
{
"id": "Question14_1"
}
]
},
"correct_responses": {
"childArray": [
{
"pattern": "CPR"
}
]
}
}
]
}
};
Logging
By default, the API is set to only output errors in the Javascript console. You can change this by setting apiLogLevel to your desired level:
window.API_1484_11.apiLogLevel = 1; // Log everything (Debug)
window.API_1484_11.apiLogLevel = 2; // Log useful information, warning and errors
window.API_1484_11.apiLogLevel = 3; // Log warnings and errors
window.API_1484_11.apiLogLevel = 4; // Log errors only
window.API_1484_11.apiLogLevel = 5; // No logging
Resetting
There may come a time when you need to reset the SCORM 2004 API. Two methods are available.
You can create a new API and replace the one available on window.API_1484_11:
window.API_1484_11 = new window.simplifyScorm.ScormAPI2004();
You can also create a new API and ask the existing one to use the new API instead.
This is useful when a SCORM object allows retrying after a failure, and you want to track each attempt in a separate CMI object.
SCORM objects often keep a reference to the original API, which is why this manipulation is needed:
var newAPI = new window.simplifyScorm.ScormAPI2004();
window.API_1484_11.replaceWithAnotherScormAPI(newAPI);
window.API_1484_11 = newAPI;