Skip to main content
Inspiring
April 25, 2018
Answered

Override Captivate's SCORM output onUnload with JS?

  • April 25, 2018
  • 2 replies
  • 1415 views

Using Captivate 2017 and publishing as HTML5.

I'm trying to replace Captivate's built in SCORM bookmarking using custom JS calls to set and commit information: SCORM_CallLMSSetValue("cmi.core.lesson_location", window.cpAPIInterface.getVariableValue('highestTopic')) [highestTopic is an integer)

on certain slides, and this works wonderfully as long as the user closes the activity using the Exit button on the slide after the quiz results, which includes the following JS:

SCORM_SetBookmark("");

SCORM_objAPI.LMSSetValue("cmi.core.exit", "logout");

SCORM_CallLMSCommit();

SCORM_objAPI.LMSFinish('');

However, if the user closes the window using the parent window's controls, Captivate performs its own calls that overwrite my information (the custom cmi.core.lesson_location data) onUnload of the window. It overwrites my integer information with a string of the slide name that was showing at the time the window was closed.

Is there any way to override or disable this so that my information is preserved? I've tried digging through the JS created by Captivate on publishing the SCO, but I have had no success in finding the correct line of code where this is happening. If I add my own onUnload to the body of the index_scorm page, set and commit my data, then terminate the SCORM connection, will that override Captivate's onUnload, or will theirs beat mine to the punch?

    This topic has been closed for replies.
    Correct answer krob_delta

    Finally worked out a solution, for anyone else who comes along with a similar need. Note that this all involves SCORM 1.2, but I'd bet the same applies to 2004 - just the SCORM variable names would be different.

    Captivate will always pass the last slide's label (URI encoded) to the LMS via SCORM's cmi.core.lesson_location variable if the Captivate activity's window is closed. It doesn't seem to matter if you have Never Send Resume Data in the advanced Quiz preferences or not. You can override this through in-Captivate Javascript actions on Close/Exit buttons in your project, but lesson_location will always be reset every time your SCO is launched.

    TLCMediaDesign is absolutely correct that Captivate uses both cmi.core.lesson_location AND, more importantly, cmi.suspend_data to handle automated SCORM bookmarking. Unfortunately, cmi.suspend_data has a hard limit of 4096 characters and Captivate writes a HUGE amount of data to this variable if Never Send Resume Data is unchecked (i.e. you want Captivate's automatic SCORM bookmarking). It can easily overrun this limit and you can end up with strange results - even breaking the bookmarking altogether.

    If you check Never Send Resume Data, Captivate will still pass information via SCORM (such as lesson_location), but NOT to cmi.suspend_data. cmi.suspend_data will always hold a value of zero (the default SCORM value). So, if you want to store and use your own SCORM bookmarks, you can set a custom value for cmi.suspend_data (you'll need to commit it each time) and it will persist, whether users use your in-activity controls to close the unit or if they close the window. You can then read in this value on each session and either automatically return the user to their last location or even build a dialog on the first slide of your project to give the users a choice to resume or start over.

    This was a significantly easier approach for me than trying to work with Captivate's automatic bookmarking, modifying the scormdriver.js file for every project, and having to check and redirect the user's place if it tried to let them resume from an undesirable place.

    2 replies

    krob_deltaAuthorCorrect answer
    Inspiring
    April 26, 2018

    Finally worked out a solution, for anyone else who comes along with a similar need. Note that this all involves SCORM 1.2, but I'd bet the same applies to 2004 - just the SCORM variable names would be different.

    Captivate will always pass the last slide's label (URI encoded) to the LMS via SCORM's cmi.core.lesson_location variable if the Captivate activity's window is closed. It doesn't seem to matter if you have Never Send Resume Data in the advanced Quiz preferences or not. You can override this through in-Captivate Javascript actions on Close/Exit buttons in your project, but lesson_location will always be reset every time your SCO is launched.

    TLCMediaDesign is absolutely correct that Captivate uses both cmi.core.lesson_location AND, more importantly, cmi.suspend_data to handle automated SCORM bookmarking. Unfortunately, cmi.suspend_data has a hard limit of 4096 characters and Captivate writes a HUGE amount of data to this variable if Never Send Resume Data is unchecked (i.e. you want Captivate's automatic SCORM bookmarking). It can easily overrun this limit and you can end up with strange results - even breaking the bookmarking altogether.

    If you check Never Send Resume Data, Captivate will still pass information via SCORM (such as lesson_location), but NOT to cmi.suspend_data. cmi.suspend_data will always hold a value of zero (the default SCORM value). So, if you want to store and use your own SCORM bookmarks, you can set a custom value for cmi.suspend_data (you'll need to commit it each time) and it will persist, whether users use your in-activity controls to close the unit or if they close the window. You can then read in this value on each session and either automatically return the user to their last location or even build a dialog on the first slide of your project to give the users a choice to resume or start over.

    This was a significantly easier approach for me than trying to work with Captivate's automatic bookmarking, modifying the scormdriver.js file for every project, and having to check and redirect the user's place if it tried to let them resume from an undesirable place.

    TLCMediaDesign
    Inspiring
    April 25, 2018

    Not sure if yours would execute if the unload was already called.

    I think you best bet is to modify the set bookmark function in the scormdriver .js.

    I don't know how you are setting "'highestTopic', but you should be able to modify the function to:

    function SCORM_SetBookmark(strBookmark) {

        WriteToDebug("In SCORM_SetBookmark strBookmark=" + strBookmark);

        SCORM_ClearErrorInfo();

        

         if ( window.cpInfoCurrentSlide +1 < window.highestTopic )

         {

             return false;

         }

         else

         {

         return SCORM_CallLMSSetValue("cmi.core.lesson_location", strBookmark);

         }

    }

    cpInfoCurrentSlide is zero based and the bookmark is set on enter of a slide, so if you are on slide 10 and you set your variable to 10 on side enter it will set the bookmark, if you go to side 9 it will not.

    Inspiring
    April 25, 2018

    Yeah, I just tested it out of curiosity, and their unload gets called first. So that's not an option.

    Tweaking SCORM_SetBookmark might be a solution, or at least lead me in the right direction. It's complicated in that I have a subset of slides that I need to restrict SCORM bookmarking to. This subset also contains interstitial Knowledge Check slides that need to be ignored as far as bookmarking, so I can't rely on cpInfoCurrentSlide easily. This gives me something to think about though.

    Thanks!

    TLCMediaDesign
    Inspiring
    April 25, 2018

    If you use slide titles it would be easy to set it up as all of the titles are in an array. You could ignoer bookmarking if the title had an indexOf "knowledge check" else check to see the current bookmarks location in the array and if it's less than the current slide, don't bookmark.