Getting Started With SCORM: The basics of initializing/closing a SCO and sending/receiving data

Getting Started With SCORM: The basics of initializing/closing a SCO and sending/receiving data
Summary: Continuing on in our discussion of the SCORM standard and how communication happens between a SCO and as LMS, today we will be talking about the first and last communication calls made by a SCO, LMSInitialize and LMSFinish.  After that we will get into the basics of how course data is passed back and forth using LMSGetValue and LMSSetValue.

Lets get started with SCORM!

After the SCO has found the LMS API (please see the first article in this series for more information on the API, Getting Started with SCORM: How does SCORM really work?), the SCO calls LMSInitialize.  LMSInitialize simply notifies the LMS that the SCO is loaded and ready to begin sending/receiving data. The LMS then has the opportunity to initialize any data, variables, or other functions needed before the SCO proceeds.  It also has the opportunity to notify the SCO of potential problems by returning the value “false”.

In JavaScript the call from the SCO simply looks like this:  api.LMSInitialize(“”) (where API is a variable that points to the API object of the LMS).

LMSFinish is somewhat of the opposite of LMSIntiialize. LMSFinish is the last call a SCO makes and notifies the LMS to save the data the SCO has sent so far and to close the current session. In most SCOs the LMSFinish command is setup to fire when the training window is closed, so when a user exits their training it automatically fires.

In JavaScript the call from the SCO simply looks like this:  api.LMSFinish(“”) (where API is a variable that points to the API object of the LMS).

After the LMS has been initialized the SCO can begin sending data back and forth. This is done by two commands: LMSGetValue and LMSSetValue.

In SCORM the data model stores data as name/value pairs. We generally refer to this data as CMI data.  LMSGetValue and LMSSetValue facilitate setting and retrieving these values.

LMSGetValue retrieves the value of any element the LMS stores.  It takes a single parameter which is the name of the element’s value that should be returned. So for example api.LMSGetValue(“cmi.core.lesson_status”)  would return the status of the current course.

LMSSetValue takes two parameters, the first is the name of the element to set and the second is the value. So for example  api.LMSSetvalue(“cmi.core.lesson_status”,”completed”) would set the cmi.core.lesson_status element to completed.

The SCORM spec defines the entire data model and you can download a complete breakdown from the ADL website at: www.adlnet.gov/scorm/scorm-version-1-2 .  The ADL’s documentation details all supported elements, what values are allowed for an element, and whether an element should be read or write only.

So let’s put it all together – Below is a small piece of JavaScript based on what we have discussed so far.  By far the most complicated portion of this code is the snippet we grabbed from the ADL website that finds a reference to the LMS API (again see the previous article for more details on that). After we have a reference to the API the code is very straight forward.  It calls LMSInitialize to initialize the LMS, then it retrieves the user name (which according to the spec should be provided by the LMS in an element named cmi.core.student_name), and then it sets the  cmi.core.lesson_status variable to completed, which marks our SCO as complete.  Finally we call LMSFinish to notify the LMS that the SCO has finished sending data..

<script>

//ADL Sample Code to Retrieve API Reference

var apiHandle = null;

function getAPIHandle() {

if (apiHandle == null)    {

apiHandle = getAPI();

}

return apiHandle;

}

function getAPI() {

var theAPI = findAPI(window);

if ((theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined"))    {

theAPI = findAPI(window.opener);

}

if (theAPI == null)  {

message("Unable to find an API adapter");

}

return theAPI

}

function findAPI(win) {

var findAPITries = 0;

while ((win.API == null) && (win.parent != null) && (win.parent != win))    {

findAPITries++;

// Note: 7 is an arbitrary number, but should be more than sufficient

if (findAPITries > 7)

{

message("Error finding API -- too deeply nested.");

return null;

}

win = win.parent;

}

return win.API;

}

//Function to set a value in the LMS

function SetValue(name, value) {

var api = getAPIHandle();

return api.LMSSetValue(name, value);

}

//Function to retrieve a value from the lms

function Getvalue(name) {

var api = getAPIHandle();

return api.LMSGetValue(name);

}

//The following 4 lines handle our actions for this example

// get the API, Initialize the LMS, retrieve a value, set a value

var api = getAPIHandle();

api.LMSInitialize("");

alert(api.LMSGetValue("cmi.core.student_name"));

api.LMSSetValue("cmi.core.lesson_status","completed");

api.LMSFinish(“”);

</script>