Storyline - Set LMS Status with JavaScript

As known with previous Articulate products and versions, there are traditionally only two ways to set the LMS status to "complete".

  1. Number of slides viewed
  2. Score on quiz/test


A third "custom" way to set completion in the LMS:

  • Slide location


This third way would be more appropriate with multi-branching courses where the test is really landing on a particular screen or one of multiple screens.

Publishing

When publishing, choose the slide count method set to all slides. In a multi-branching course the learner would not see all slides but the course will be set to complete before the learner views all slides.

Flash method

In the past, this was accomplished with an imported flash file that would call a JavaScript function. That is still possible using the AS2 "setStatus.swf" file found attached to this post.

However, in Storyline, you can call JavaScript functions from any trigger, including a slide trigger.

JavaScript method

So here is the least bit of JS you need on a trigger to mark a course complete:


Run that little bit of code in a JavaScript trigger on any slide, object, button, etc. and Storyline will tell the LMS that the course is done.

Other options… "completed", "incomplete", "failed" and "passed"

Some LMSes want a bit more info. And you may want more yourself; like a score. That only takes a few more lines of code be added before we call SetStatus:


Now you can set the course status whenever/wherever you want.

72 Replies
Mateusz Szuter

Ok, since I have some free time, I'll try to gather all the knowledge I have ;) If you want simple solution go to the end of the post.

First of all I highly recommend to use built-in Storyline tracking options if you can. The things below may not work on every LMS platform out of there (I had some problems in the past). Also, remember, that certain platforms can be set up to only use Completion status (incomplete/complete) or Success status (failed/passed). Therefore, you must set that option accordingly inside storyline tracking options.

Second thing, the scormdriver.js in 360 has been fully rewritten, so some things posted before may not work. 

Third, all the commends of SCORM 1.2 and 2004 can be found on scorm.com site and all the things below are based on the official SCORM specification. 

Fourth, Storyline added some own js commends to easen things up. So the most versatile way would be to use the official SCORM specifation, but we will go the easier way using Storyline built-in commends :)

Fifth, you always must publish using LMS tab. In order to following codes work and prevent Storyline from overriding that codes, you must trick it :) Set tracking to view all slides. Then, put additional scene with blank slide. This way, user must view eg. 50 slides to trigger storyline completion. But you will show him only 49, hence the Storyline will never trigger it's completion.

Any of the code below must be fired using Execute javascript trigger. You can merge the code chunks. 

So, to start communication with LMS platform, add on the beginning following lines:

var player = GetPlayer();
function findLMSAPI(win) {
if (win.hasOwnProperty("GetStudentID")) return win;
else if (win.parent == win) return null;
else return findLMSAPI(win.parent);
}
var lmsAPI = findLMSAPI(this);

Thing you need to know is that fetching the variables defined in Storyline is possible, so you can send them to lms. The code are:

player.SetVar("storyline_variable_name","value");
player.GetVar("storyline_variable_name");

The first SetVar assign some value to the defined in Storyline variable. 
The second GetVar reads the value defined in Storyline. 

First one isn't used much - you can manipulate variable values inside storyline pretty well :) Second is used more widely, as you can use it to pass some thins to LMS.

So, let's go with the example. You want to set course score to LMS. The command for this is:

lmsAPI.SetScore(100, 100, 0);

So for you to fully understand, SetScore sends cmi.core.score.raw (1.2) or cmi.score.raw (2004) to the platform, which reflects the performance of the user in the course and is mostly common viewed on LMS as "Score". The first argument (arguments are inside ()) tells LMS the number you want to see on your LMS. If you set it to 100, the SCORE on LMS would be 100. If you jest 12, it will be 12. The second and third set the maximum score and minimum score. Keep it always 100 and 0, as the LMS will most probably send you an error that score range isn't 0-100. 

But... what's the point on sending fixed number? You would do 100 layers to reflect all score scenario? Of course not! Let's use our Storyline variable.

lmsAPI.SetScore(player.GetVar("points"), 100, 0);

You see? We used player.GetVar to catch points variable value. If user gathered 89 points, that exact value would be send to the platform. If he makes 10 points, the Score on LMS would say 10. If something went wrong, and the points would be below 0 or above 100, the score will remain unassigned on LMS, but the completion statuses can work.

That was the part common in both 1.2 and 2004. Now let's go to completion statuses.

You need to know the biggest difference between versions. The 1.2 uses only one lesson status, while 2004 handles two (completion and success).

In 1.2 specification you can find:

cmi.core.lesson_status (“passed”, “completed”, “failed”, “incomplete”, “browsed”, “not attempted”, RW)
and that means, in the command below, you can pass one of four completion (browsed and not attempted aren't much interest to us) - passed, completed, failed, incomplete. 

SCORM_CallLMSSetValue("cmi.core.lesson_status", "status");

SCORM_CallLMSSetValue is another Storyline shortcut. In the "status" place you need to put one of the four statues, eg. passed.

In 2004 specification you can find:

cmi.completion_status (“completed”, “incomplete”, “not attempted”, “unknown”, RW) Indicates whether the learner has completed the SCO

AND

cmi.success_status (“passed”, “failed”, “unknown”, RW) Indicates whether the learner has mastered the SCO

So, you can actually distinguish wheter learner COMPLETED course and PASSED it. Some may go through the all course, but not pass the final test. Or even go through the course and leave the test for another occasion. Ok, here's the code:

SCORM2004_CallSetValue("cmi.completion_status", "completed");
SCORM2004_CallSetValue("cmi.completion_status", "incomplete");
SCORM2004_CallSetValue("cmi.success_status", "passed");
SCORM2004_CallSetValue("cmi.success_status", "failed");


Of course you need to pick one from each pair :) SCORM2004_CallSetValue is shortcut for use from Articulate. Please note, that the shortcuts are different! I've spent once about two hours trying to figure out why my statues aren't reported to the LMS, and I've put cmi.completion_status inside SCORM_CallLMSSetValue :)

Ready to go code snippets (of course you can delete part you doesn't need, like SetScore):

Scorm 1.2

var player = GetPlayer();
function findLMSAPI(win) {
if (win.hasOwnProperty("GetStudentID")) return win;
else if (win.parent == win) return null;
else return findLMSAPI(win.parent);
}

var lmsAPI = findLMSAPI(this);
lmsAPI.SetScore(player.GetVar("points"), 100, 0);
SCORM_CallLMSSetValue("cmi.core.lesson_status", "passed");

SCORM 2004 (any edition)

var player = GetPlayer();
function findLMSAPI(win) {
if (win.hasOwnProperty("GetStudentID")) return win;
else if (win.parent == win) return null;
else return findLMSAPI(win.parent);
}
var lmsAPI = findLMSAPI(this);
lmsAPI.SetScore(player.GetVar("points"), 100, 0);
SCORM2004_CallSetValue("cmi.completion_status", "completed");
SCORM2004_CallSetValue("cmi.success_status", "passed");