Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

User variables persisting between sessions

Explorer ,
Apr 01, 2016 Apr 01, 2016

I read in a long and informative thread from 4 and a half years ago that even if "resume data" or "suspend data" were being sent to the LMS between sessions (to persist my Captivate user variables), that if my user variables are being set to an initial value in my Captivate file, they will be reinitialized each time on entry to the initial value, and the persisted value will be lost.  My question:  is that still true in Captivate 9?

I ask because we have discovered a problem with the behavior of our modules if a student exits a lesson and reenters it later, a problem which would perhaps be explained by the above phenomenon.

TOPICS
Advanced
1.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

People's Champ , Apr 04, 2016 Apr 04, 2016

It's best if you use an included js file to do this. You can create the file and put the include in the index.html

The 'moduleReadyEvent' is only triggered once, create a function initVariables to get the vars form localStorage or initialize the localStaorage if it doesn't yet exist.

In the initializeEventListeners function you add a 'CPAPI_SLIDEENTER' listener, set the storage everytime you enter a slide.

Add a window.onunload function to set it again when the page unloads.

window.addEventListener(

...
Translate
Community Expert ,
Apr 01, 2016 Apr 01, 2016

User variables are reset when re-entering a course, still the same in CP9.

For HTML output only, the new CPExtra widget by InfoSemantics allows to transfer values of user variables between courses. It is also possible with JS.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 01, 2016 Apr 01, 2016

Thank you for the swift reply!

I have a follow-up question if you would be so kind:  I tried an experiment:  I created a new user variable and did NOT give it an initial value, published the lesson, ran it using Chrome, and at the pause on slide 1, I used cpAPIInterface.getVariableValue("varName") in the Console to inspect the value Captivate thought it had, wondering if it would be undefined or what.  The call returned the empty string "".  We were considering a solution involving NOT setting an initial value, in the hopes that the variable would NOT be reset to anything on re-entry to the course, but I wonder if Captivate still considers that such a variable is to be initialized to the empty string, as opposed to not trying to change its value at all, which is what we'd need to have happen for such a solution to work.  Do you think a user variable with "no initial value" is actually considered to have an initial value of "", and will be reset to "" on re-entry?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 01, 2016 Apr 01, 2016

The problem with the point-and-click programming in Captivate is that there is no real difference in variables between strings and numbers.  For CP an empty string, the number 0 and no value are the same. Could you perhaps try with 0 as an initial value?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 01, 2016 Apr 01, 2016

We have groups of 3 slides consisting of an A question, a remediation page if they get the A question wrong, and a B question seen after the remediation page is shown.  These triads are scattered throughout the lessons.  We have a single user variable for each triad, which is set to one of three values to indicate if they saw the question yet, if so, did they get it right or did they get it wrong.  During one session, it all works fine.  If the student exits and returns, obviously, it doesn't remember the values of the user variables.  It hasn't been a big problem because the students rarely view the lessons a second time, and even if they do, Captivate remembers what they did or didn't do question-wise, and shows them the remediation and B question even if they didn't see them the first time and lets them advance past it harmlessly (giving the canned message that an optional question was skipped, but not making them answer it).  But it looks stupid.  We need some way to save those values between sessions. 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 01, 2016 Apr 01, 2016

I told about the CPExtra widget and JS to keep those values.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 01, 2016 Apr 01, 2016

I know, thank you.  I don't think we'll be able to use CPExtra.  As for the JS solution, I'm not sure how to do that, but it probably involves session state in HTML5 or something. 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Apr 01, 2016 Apr 01, 2016

Are you publishing to HTML5? All of the user variables are in a string in the cp.ReportingVariables. You can also get them in a swf with a widget.

You can use the string converted to an array and get the values. Write that to a JSON object and use localStorage to persist it. Parse it back through when you re-enter.

I've found that not all variables get reset, TEB variables definitely do.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 01, 2016 Apr 01, 2016

Thank you very much!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 04, 2016 Apr 04, 2016

OK, I will try what you suggested.

The only thing I'm unsure about now is WHEN to do it.  Since the student can leave the lesson at any time and come back later to the same place, it would seem that I'd have to use the localStorage copy of the variables as the master copy of the values, reading them in to the user variables whenever the values of the user variables need to be examined, and writing them back out whenever the user variables change inside the lesson.  And I'd have to find some way to have code executed on their very first entry (and never again) to set up the initial values of the localStorage variables, and code which is invariably executed on exit which always saves the user variables to localStorage.  I read that there used to be a place for an advanced action on exit, or something like that.  Does that still exist?  Perhaps I could always save the user variables THEN.  On entry I could have a dummy first slide that does nothing but quickly initialize all the variables and advance to slide 2, and ensure they can never back up from slide 2 to slide 1.  I'd appreciate it if you would comment on this approach as to whether it seems sound or viable.  Thanks!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Apr 04, 2016 Apr 04, 2016

It's best if you use an included js file to do this. You can create the file and put the include in the index.html

The 'moduleReadyEvent' is only triggered once, create a function initVariables to get the vars form localStorage or initialize the localStaorage if it doesn't yet exist.

In the initializeEventListeners function you add a 'CPAPI_SLIDEENTER' listener, set the storage everytime you enter a slide.

Add a window.onunload function to set it again when the page unloads.

window.addEventListener( 'moduleReadyEvent', function ( e )

{

interfaceObj = e.Data;

eventEmitterObj = interfaceObj.getEventEmitter();

initVariables();

initializeEventListeners();

});

function initVariables()

{

  //set up the localStorage

}

function initializeEventListeners()
{
if ( interfaceObj )
{
     if ( eventEmitterObj )
  {
         eventEmitterObj.addEventListener( 'CPAPI_SLIDEENTER', function ( e )
   { 
    //call a function to set the storage here.
            });
  }
}
}

window.onunload = function()
{
   //call a function to set the storage here.
}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 04, 2016 Apr 04, 2016

Wow.  I can't thank you enough!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 15, 2016 Apr 15, 2016

I used this approach, and have finally been able to test it thoroughly, and it seems to be working!

I had to enhance it slightly, because our different lessons use many commonly named user variables, and since localStorage would not differentiate them, I needed some way to do so.  So I have added a new user variable to each lesson specifying a unique name for that one lesson and using a prescribed format, so that that single variable can be easily distinguished by name from the other user variables, and when I parse the value of cp.ReportingVariables, I look for the one variable named with that format and use that name as a namespace name prepended to each of the localStorage property names, like this:  FLT_888_NAME.uQ01a, so that different lessons taken by the same user will not step on each other's persisted user variable values!

Thanks again.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Apr 15, 2016 Apr 15, 2016
LATEST

What I do is to get the project name and prepend that to all of the variables. This gets the name from Preferences/Project/Information/Project Name

function initProgress()

{

var lessonStorage = cp.model.data.project.pN + '.progressData'; 

if ( typeof( Storage ) !== 'undefined' && netConnected != -1 )

{

  if ( localStorage.getItem( lessonStorage ) !== null )

  { 

   var getResults = localStorage.getItem( lessonStorage );          

    myProgress = JSON.parse( getResults );

  }

}

else

{

  for ( var i = 0; i < window.cpInfoSlideCount; i++ )

  {

   myProgress[ i ] = 0;

  }

}

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Help resources