Forum Discussion
SCORM/xAPI not passing grade to Brightspace (D2L) gradebook
Hello,
D2L's gradebook only pulls the cmi.core.score.raw value from SCORM objects, but Rise only passes that value via quiz objects. In Moodle 3, we can set pass completion status as a score to its gradebook, but that's not an option in D2L.
1. Is there a workaround we can implement using an embedded Storyline block?
2. Is there javascript code we can add to the SCORM1.2 object to write a score of 100 to cmi.core.score.raw if cmi.core.lesson_status is set to "complete"?
3. Failing these, is there another way to pass a score and not just completion to our LMS?
Hi
In my attached course, I’ve tried to set the score using the code from above inside a storyline object. This worked for my own scorm test harness, but not in scorm cloud. Not sure why.
I then tried changing tack. I modified the ./scormdriver/scormdriver.js file to emit an event when SetValue is called so that it’s easier to add custom logic. I then added a script block right before the closing </body> tag to the ./scormdriver/indexAPI.html file that detects the lesson_completed state and also sets a score.
<script>
/* custom event handler for SCORM_CallLMSSetValue */
window.addEventListener('lmssetvalue', function(e) {
const {api,key,value} = e.detail;
switch (key) {
case "cmi.core.lesson_status":
if (value == "completed" || value == "passed") {
console.info('heard lesson_status completed or passed, setting score');
// set the score to 100
api.LMSSetValue("cmi.core.score.raw", "100");
api.LMSSetValue("cmi.core.score.min", "0");
api.LMSSetValue("cmi.core.score.max", "100");
console.info(api.LMSCommit(""));
}
break;
}
});
</script>On scorm cloud, the score is set to 100% when the course completes.
Does this help?
- LukeWestfallCommunity Member
Oh interesting! And for others coming after, the CustomEvent you added looks something like:
const ev = new CustomEvent("lmssetvalue", {
bubbles: true,
detail: {
api: SCORM_objAPI,
key: strElement,
value: strValue
}
});
window.ldispatchEvent(ev); - LukeWestfallCommunity Member
After a day trying #1, we've failed to successfully pass a grade through a Rise SCORM object via Storyline (tested using https://app.cloud.scorm.com/).
Further suggestions would be appreciated.
- Tim_Community Member
Hi
In my attached course, I’ve tried to set the score using the code from above inside a storyline object. This worked for my own scorm test harness, but not in scorm cloud. Not sure why.
I then tried changing tack. I modified the ./scormdriver/scormdriver.js file to emit an event when SetValue is called so that it’s easier to add custom logic. I then added a script block right before the closing </body> tag to the ./scormdriver/indexAPI.html file that detects the lesson_completed state and also sets a score.
<script>
/* custom event handler for SCORM_CallLMSSetValue */
window.addEventListener('lmssetvalue', function(e) {
const {api,key,value} = e.detail;
switch (key) {
case "cmi.core.lesson_status":
if (value == "completed" || value == "passed") {
console.info('heard lesson_status completed or passed, setting score');
// set the score to 100
api.LMSSetValue("cmi.core.score.raw", "100");
api.LMSSetValue("cmi.core.score.min", "0");
api.LMSSetValue("cmi.core.score.max", "100");
console.info(api.LMSCommit(""));
}
break;
}
});
</script>On scorm cloud, the score is set to 100% when the course completes.
Does this help?
- Lars-vdPCommunity Member
Hi Tim_,
Thanks for your explanation and example SCORM-package. However the SCORM did not report a score to our Brightspace Gradebook. Can you confirm this works for your Bsp instance?
Our Bsp is using the 'new' Rustici SCORM-engine.
Thanks in advance, Lars
- LukeWestfallCommunity Member
Pulling apart the SCORM object (zip), I can't figure out where I'd put js code to accomplish this task. Do you have any experience with adding code to a Rise-exported SCORM object?
- Tim_Community Member
Hmm. I don’t think there’s an event driven way to determine when cmi.core.lesson_status is complete (or when any scorm value changes), so maybe there is something you could do with the first idea.
In storyline you’d craft a file that executes custom javascript on timeline load/end, then publish it and load the storyline file into rise where you want it to execute (like at the end perhaps).
It would find the scorm api and set the score fields directly (if you’re setting raw you have to also set min/max). This is off the top of my head, but something like this might work:
var findAPITries=0;function findAPI(win){while((win.API==null)&&(win.parent!=null)&&(win.parent!=win)){findAPITries+=1;if(findAPITries>7){alert("Error finding API -- too deeply nested.");return null}win=win.parent}return win.API}function getAPI(){var theAPI=findAPI(window);if((theAPI==null)&&(window.opener!=null)&&(typeof(window.opener)!="undefined")){theAPI=findAPI(window.opener)}if(theAPI==null){alert("Unable to find an API adapter")}return theAPI}const lmsAPI = getAPI(this);if (lmsAPI) {lmsAPI.LMSSetValue('cmi.core.score.min’,’0’);lmsAPI.LMSSetValue('cmi.core.score.max’,’100’);lmsAPI.LMSSetValue('cmi.core.score.raw’,’80’); // set your score here, maybe pull from a storyline variable etclmsAPI.LMSCommit(‘’);}