Forum Discussion
Send module progress to LMS (Cornerstone)
Hello everyone,
I'm in a bit of a bind because I recently created a Storyline module (with STL 360) and my client would like to see the module's progress go up in his LMS. I've tried several techniques find on forums or more generally internet (using the score, using several Js codes to execute...) but none of them seem to work.
The latest one, which seems to me to be the most complete, after reading a Cornerstone article on the subject (here's the link), is as follows:
In the first module slide, I create number of objectives (corresponding to the units) using a Js code :
// Define the number of objectives to be created
var number_goals = 36;
// Loop to create and send each objective as incomplete
for (var i = 1; i <= goal_number; i++) {
var objective_id = "objective" + i;
// Send each objective as incomplete to the SCORM API
var success = lmsAPI.Set("cmi.objectives." + objectif_id + ".id", objectif_id);
success = success && lmsAPI.Set("cmi.objectives." + objectif_id + ".status", "incomplete");
Then, at different stages of the module and as I go along, I update the status of each objective (in order) using this code:
var lmsAPI = parent; // Connect to the LMS API
// Identify the objective to be updated
var objective_id = "objective1"; // Modify according to the specific objective to be updated
// Update objective status to "completed
var success = lmsAPI.Set("cmi.objectives." + objectif_id + ".status", "completed");
The latter doesn't seem to work either... Does anyone have any experience of this problem and a solution?
Thanks for the future help!
Claire
- SamHillSuper Hero
Hi Claire, has your client given you any indication as to how progress should be tracked on their LMS. For example, when they see progress on their LMS, which SCORM data model elements it the LMS using to show progress. Have you confirmed it is CMI.Objectives? I would first confirm this, as you might develop something that the LMS has no capability of displaying/reporting in a meaningful way. I know some LMS may support CMI.Objectives, but don't actually provide a means to display them. I would also check if the client has an example they can show you. It may be that the example they have is a course broken down into multiple SCOs, and then LMS shows progress (%) completion based on the number of SCOs completed in the course. Worth checking first I think.
- SamHillSuper Hero
Also, is their LMS Cornerstone?
- ClaireGarry-0e2Community Member
Hi Sam,
First of all, thanks for you reply!
The one and only information they were able to give me was the name of their LMS which is indeed Cornerstone (sorry this must not have been clear in my previous message) and the article shared above.
Unfortunately, they are unable to provide me with an example of project showing the percentage of progress in the LMS.Nonetheless, Cornerstone maintains that it is possible in their article.
So, I'm proceeding by trial and error. I thought that my codes would have been enough to declare a certain number of objectives and therefore to have a progression, but perhaps I was mistaken somewhere. Do you know how to divide a course into serveral SCOs ? Would this differ from the number of cmi.objectives and codes used so far?
My module is currently divided into several scenes. Would it be possible to transfer them into SCOs and thus obtain several units (as expected by Cornerstone for progress information)?
Have a nice day!
- SamHillSuper Hero
Hi Claire,
I would push on with cmi.objectives as it looks to be well supported in cornerstone.
cmi.objectives aren't widely used, and so you could expect some problems implementing, but I think it is worth a go before going down the multi sco route.
You will be able to use Storylines reference to the SCORM 1.2 API if the module is published as SCORM 1.2.
There are a couple of issues with the script you have as an example. For example, cmi.objectives are kind of an array, and so start at zero. When you see a reference to a cmi.objective like this, "cmi.objective.n.status", n = the index of the objectives. This value cannot be anything other than a number, and must be sequential. For example, you can't skip numbers. The object ID is use to try and give your objective some kind of meaningful ID for ID in the LMS. It can only be alphanumerical though (hyphen, dash or underscore are legal).
So, when you initialize your objectives, you would want to do something like this:
initObjectives = function()
{
var goals = 36;
for (var i = 0; i < goals; i++) {
// using the Storyline function SCORM_CallLMSSetValue
// which takes care of error handling and getting the API
var objid = "objective_"+i;
var success = SCORM_CallLMSSetValue("cmi.objectives." + i + ".id", objid);
if(success)
{
success = SCORM_CallLMSSetValue("cmi.objectives." + i + ".status", "not attempted");
if(!success) alert('Unable to set the status for the objective cmi.objectives.' + i + '.id');
}else{
alert('Unable to set the ID for the objective cmi.objectives.' + i + '.id');
}
}
}
// if the total amount of objectives set is 0 (zero), then initialize them
// this check ensures that the objectives are only initialized once!
if(SCORM_CallLMSSetValue("cmi.objectives._count") === 0) initObjectives();Then, when you are updating the objective status, you are updating by the index number, and not the id defined. For example, the first objective would be updated like this:
// user starts the objective
SCORM_CallLMSSetValue("cmi.objectives.0.status", "incompleted");
// user completes the objective ("passed", "completed", "failed");
SCORM_CallLMSSetValue("cmi.objectives.0.status", "completed");The LMS should then be able to show the progress through the objectives, and if the LMS allows, the admin will be able to drill down further and see that "objective_0" is "completed"This should set you on the right path Claire.Cheers,Sam - ClaireGarry-0e2Community Member
Hi Sam,
Thanks for your responsiveness and help.
As I'm not familiar with JS, I thank you and appreciate the fact that you went into so much detail in your response.
- If I understood correctly, my objectives weren't recognizable by the LMS because they weren't well defined. Given your code examples, I would "just" have to implement the code below in my first module slide to "create" the 36 objectives.
initObjectives = function()
{
var goals = 36;
for (var i = 0; i < goals; i++) {
// using the Storyline function SCORM_CallLMSSetValue
// which takes care of error handling and getting the API
var objid = "objective_"+i;
var success = SCORM_CallLMSSetValue("cmi.objectives." + i + ".id", objid);
if(success)
{
success = SCORM_CallLMSSetValue("cmi.objectives." + i + ".status", "not attempted");
if(!success) alert('Unable to set the status for the objective cmi.objectives.' + i + '.id');
}else{
alert('Unable to set the ID for the objective cmi.objectives.' + i + '.id');
}
}
}
// if the total amount of objectives set is 0 (zero), then initialize them
// this check ensures that the objectives are only initialized once!
if(SCORM_CallLMSSetValue("cmi.objectives._count") === 0) initObjectives();- To enable the LMS to record progress throughout my module, I need to integrate the following javascript on one slide
// user starts the objective
SCORM_CallLMSSetValue("cmi.objectives.0.status", "incompleted");
- Then, on the next slide for example (or the slide corresponding to the achievement of the objective), I need to integrate the javascript// user completes the objective ("passed", "completed", "failed");
SCORM_CallLMSSetValue("cmi.objectives.0.status", "completed");Is this correct?
- ClaireGarry-0e2Community Member
Finally, at no time should I include the following lines:
var lmsAPI = parent or var success = lmsAPI.Set- SamHillSuper Hero
That's right Claire. You don't need to get the lmsAPI as Storyline does
that for you in their Get/Set functions.You just need to increment the CMI.objectives index for each objective.
If you have a go at implementing on the first couple of objectives, I'm
happy to look over your Storyline file to see if it is all ok.Thanks, Sam.
- ClaireGarry-0e2Community Member
Great!
Thanks a lot for your help!
I'll do a little test on a blank file to share it with you in that case!One last little question: in my module, I have 6 scenes: of the 6, the learner must do one to reach the end, but the remaining 5 are optional. What would you advise me to do so that the last objective (associated with the final scene) is still indicated as completed, and the module updated to 100% if the previous ones haven't been?
Should I put the same objective ID on the slides for each of these 6 scenes, or should I keep the progression constant? - SamHillSuper Hero
Hi Claire,
Sounds good re: blank file.
The other question regarding mandatory and non-mandatory scenes, I would check with your client what they would like, as I think the progress bar that shows the % of objectives complete acts independently of the module completion, which simply sets a lesson status. So, you could mark the module complete, but have zero objectives complete (0% progress bar) I believe.
There are options, but it is really up to your client what they would like to see. They may say, "we want to see the progress bar 100% complete when the module is marked as complete, regardless of which objectives have been completed". You can do this just by running through a similar loop that initialized the objectives, but this time, just marking each one has "completed". It would then show 100% progress, but would not be a true reflection of which objectives have been completed.
It might take some trial an error. As an end user, I would be confused if my module was "completed" but the progress bar showed only "10%" progress.
There are a few questions that need to be answered before I can suggest a solution, but it's all possible with the script. It just depends what the client wants and what is going to be best for the end user.
When setting the status of an objective, the following values are available:
- passed
- completed
- failed
- incomplete
- browsed
- not attempted
I think (not 100% sure) that the values "passed", "completed" and "failed" are all considered finished and will therefore increment the progress. The one I'm iffy about is "failed", but I'm wondering if you could possibly use "passed" and "completed" to differentiate between objectives that have been completed by the user "passed" or not completed by the user, but the course is completed and so mark them as "completed". This would be experimental and would depend on how Conernstone interpreted these values.
I think the mix of mandatory and non-mandatory content makes showing an overall progress quite complex, and explaining the issue to the client can help them make the decision as to how it should be presented.
Cheers,
Sam - ClaireGarry-0e2Community Member
Hello Sam,I've made two blank files that follow the same flow as my module (a linear beginning and then different parts, only one of which is compulsory).
The one called "Test_Progression_Vierge" would allow the progression to be recorded as if the 3 parts of part 3 (scenes 5,6,7) were to be viewed.I'll share it in a future post
The one called "Test_Progression_Vierge_V2" would record the viewing of one of the 3 parts as equal to the same percentage of progress (see what I've developed below).
As far as the latter file is concerned, I was wondering whether setting the same objective as incomplete and complete several times might cause problems.My client only wants to see the "current module progress". In other words, as soon as the learner has completed one of part 3, and therefore has access to the "conclusion" scene, the module is considered complete. In this case, I thought I'd put the same objectives in each part 3, a bit like in my "Test_Progression_Vierge_V2" file.
What do you think?
I do think that differentiating the objectives as you suggest in your last paragraphs is indeed something to look into! I know that for this module, it's not expected, but it's worth looking into. Too bad Cornerstone doesn't offer a free trial of its LMS...
Have a nice day, - ClaireGarry-0e2Community Member