Forum Discussion

BenMcKenna-ba88's avatar
BenMcKenna-ba88
Community Member
6 years ago

Saving checkboxes in Rise

Hey guys,

I saw Mike Amelang’s inventive solution to create a Learning Journal in Rise, and it inspired me to post something similar!

Recently our team built an observational checklist in Rise, only to discover that Rise doesn’t save the value of checkbox lists between sessions! ☹️ I’ve seen other people on these forums disappointed by this as well, so I thought I would share our hotfix solution. This will make it so that your Rise course will keep checkboxes ticked/unticked between sessions.

What you’ll need:

How to use it:

  1. Unzip your Rise SCORM .zip file and
  2. Navigate to the '[RISE COURSE]\scormcontent\' subfolder
  3. Copy 'checkboxes.js' into this folder
  4. Open 'index.html' in a text editor (e.g. Notepad++)
  5. Search for the following line of code:
    <script type="text/javascript" src="lib/lzwcompress.js"></script>
    And paste this line below it:
    <script type="text/javascript" src="checkboxes.js"></script>
  6. Search for the following line of code:
    const data = JSON.parse(stringData);
    And REPLACE it with these lines:
    stringData = stringData.split("checkbox");
    convertSuspendedData(stringData[1]);
    const data = JSON.parse(stringData[0]);
  7. Search for the following lines of code:
    function concatLMSData(data) {
    assign(cache, data);

    LMSProxy.SetDataChunk(compress(cache));
    }
    And REPLACE it with these lines:
    function concatLMSData(data) {
    assign(cache, data);
    saveCheckboxes();
    checkboxData = JSON.stringify(checkboxMap);
    LMSProxy.SetDataChunk(compress(cache) + "checkbox" + checkboxData);
    }
  8. Re-zip your course and upload to your LMS

NOTE: This script only tracks “Checkbox list” block types.

 

How it works (for those interested):

Identifying and tracking checkboxes

Blocks in Rise are loaded procedurally as the user scrolls, and each lesson is effectively a separate webpage which animates in and out as the user navigates.

This immediately throws up obstacles for identifying when and where certain blocks are used in a course because they will rarely be displayed ‘all at once’. As a result, using JavaScript to find and keep track of all the checkboxes in a course isn’t as simple as just accessing the DOM to count each checkbox element on the page. Instead, the script keeps track of each checkbox as it loads in and out of existence (as well as their respective states, and respective lesson associations).

When a user accesses a lesson in Rise, the lesson ID will be appended at the end of the page URL:

By using JavaScript, each checkbox on the page is associated with its respective lesson ID by appending it as an additional attribute:

When the user jumps to another lesson, the lesson ID in the URL changes with it. This is when the script counts the checkboxes again, but this time excludes the checkboxes with the old lesson ID. It then assigns the new lesson ID to the new checkboxes loading onto the page.

At the same time, these lessons IDs and checkboxes get saved into a variable (called checkboxMap), where the lesson ID is used as a property, and the corresponding checkboxes are saved into its value as an array.

checkboxMap variable:

Every time the user navigates, the script cross-checks this variable with the lesson ID from the URL to determine whether or not the lesson had already been visited. If the lesson ID is not found in the variable, it will be added as a parameter and will continue to track the checkbox states as normal. However, if the lesson ID is found, it will reference the values in the array next to it and mark each of the boxes and checked/unchecked.

Appending this information to the suspend data

The checkbox data needs to be converted into a simpler format so that it could be transmitted and stored by the LMS. The JSON.stringify() method does this automatically by converting object variables into text strings. After converting the checkboxMap variable into a string, it gets appended onto the end of Rise’s suspend data:

Modified suspend data output:

White = Rise’s auto-generated suspend data
Blue = Separator keyword
Yellow = Custom checkbox suspend data

These two chunks of data also get separated immediately upon resuming a course. Otherwise, Rise would attempt to parse the checkbox information (which it doesn’t understand) and corrupt the session. This is done using the split() method with the separator keyword:

After separating the checkbox data, it gets converted back into the checkboxMap variable using the JSON.parse() method. The script then continues to operate as normal – counting checkboxes in each lesson and applying the checked/unchecked states to them.

Further reading:

Forum discussions:

https://community.articulate.com/discussions/rise-360/new-to-rise-is-there-a-way-for-a-checklist-to-stay-ticked

https://community.articulate.com/discussions/rise-360/what-s-the-purpose-of-the-rise-checkbox-lists#reply-509079

https://community.articulate.com/discussions/rise-360/forcing-completion-of-a-checkbox-list

https://community.articulate.com/articles/learning-more-about-your-lms-suspend-data-and-resume-behavior

Suspend data:

https://articulate.com/support/article/Rise-Exceeding-SCORM-Suspend-Data-Limits

https://elearningindustry.com/getting-started-with-scorm-tracking-course-specific-data

https://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/

LinkedIn post:

https://www.linkedin.com/posts/ben-mckenna-a00ba5155_elearning-articulate360-storyline-activity-6595486759080071168-cl_3

Let me know if you have any questions or suggestions to improve the script! 😊 I know this method is not ideal for most people, so it would be great if Articulate implements this as an official feature at some point.

  • IsabellTnebn's avatar
    IsabellTnebn
    Community Member

    Hi Ben, thanks for sharing. In my e-learning, I have the issue that I would like learners to complete a checkbox before continuing the lesson. I have added the checkbox and the continue button with the completion type "complete block directly above". However, after ticking all boxes the continue button arises and learners can remove their selection. Is this  issue also restricted by your workaround? Thanks 

  • SteveG's avatar
    SteveG
    Community Member

    Hi all, 

    I haven't been an Articulate user for a good few years now but recently found this thread while looking for information about RISE and using checkboxes for a project in work. It's a shame that this still seems to be an issue. 

    I have been playing with the original code posted by Ben and think I have this working so thought I'd share it in case it helps anyone else. Massive thanks to Ben for the original code as without it I wouldn't have known where to even start. Worth pointing out that the vast majority of the code in the attached file is Ben's work!!

    The main changes I have made are commented in the attached JavaScript file if anyone is interested but in short they are: 

    1. Created a click event listener on the <li></li> elements of the checkBox component. This updates the 'checkboxMap' value on each checkbox click to ensure that checkbox state is captured regardless of how a user exist the lesson - close button, browser close button or navigating to a new block or lesson.  
    2. Identifies the checkboxes using updated classes and attributes as the checkbox list component seems to have changed since Ben's original solution. 
    3. Implemented the changed from Meagan earlier in this thread. 

    Works exactly as per Bens instructions except point 7 which I changed to:

    function concatLMSData(data) {
    //Wrap in a 500ms delay to allow the 'checkboxMap' value to update before sending data to the LMS
    setTimeout(function () {
      assign(cache, data);
      saveCheckboxes();
      checkboxData = JSON.stringify(checkboxMap);
      LMSProxy.SetDataChunk(compress(cache) + "checkbox" + checkboxData);
    }, 500);
    }

    Can't promise it's fool proof as I haven't done a huge amount of testing but wanted to share it in case anyone found it useful. Happy for any comments.
     
    Steve