Forum Discussion

LukeWestfall's avatar
LukeWestfall
Community Member
10 months ago

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?

  • Tim_'s avatar
    Tim_
    10 months ago

    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?

  • Tim_'s avatar
    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 etc
    lmsAPI.LMSCommit(‘’);
    }
     
  • 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_'s avatar
      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-vdP's avatar
        Lars-vdP
        Community 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

  • 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);