Forum Discussion

AmyGtt's avatar
AmyGtt
Community Member
20 days ago

Variable not changing button state

I've got a pretty complicated situation.

I am creating a compliance course that a user must be in each module for 30 minutes. There are 9 modules.

When the course begins, they can't leave the course, open another browser tab, click on a different monitor screen, etc.

Also, if they do any of these, their time stops and resumes when they return to the course and a popup layer tells them that they need to resume and that their time has stopped.

Everything works great except that I've got a variable, %correctedElapsedTime%, that shows the actual time that they've been in the course. Essentially, it subtracts the time away from the built in %Project.ElapsedTime% and shows a running timer in the corner of the slide the whole time.

I want a button to change states to normal when %correctedElapsedTime% has been met. Right now, I can only get the button to change when it is triggered by %Project.ElapsedTime%. 

%correctedElapsedTime% is a text variable with a value of MM:SS and %Project.ElapsedTime% is a number variable with a value of 0. I think this is where the problem may be. It also may be that my timer is somehow skipping over the 18000000 ms to meet the 30 min time constraint. Any thoughts?

Slide triggers

Master slide javascript and triggers

Javascript

var player = GetPlayer();
var elapsedTime = 0; 
var timer = null;
var isTabActive = true;
var isFocused = true;
var inactivityTime = 0; 
var inactivityLimit = 120; 
var inactivityTimer = null; 

// Load saved elapsed time
if (player.GetVar("correctedElapsedTime")) {
    var savedTime = player.GetVar("correctedElapsedTime").split(":");
    elapsedTime = parseInt(savedTime[0]) * 60 + parseInt(savedTime[1]); 
}

// Update elapsed time
function updateElapsedTime() {
    if (isTabActive && isFocused) { 
        elapsedTime++;
        var minutes = Math.floor(elapsedTime / 60);
        var seconds = elapsedTime % 60;
        var formattedTime = minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
        player.SetVar("correctedElapsedTime", formattedTime);
    }
}

// Start elapsed time counter
function startTimer() {
    if (timer === null) { 
        timer = setInterval(updateElapsedTime, 1000);
    }
}

// Stop elapsed time counter
function stopTimer() {
    if (timer !== null) {
        clearInterval(timer);
        timer = null;
    }
}

// **Inactivity Timer Functions**
function resetInactivityTimer() {
    inactivityTime = 0; // Reset inactivity timer
    player.SetVar("showPopUpLayer", false); // Hide pop-up if user is active
}

function trackInactivity() {
    inactivityTime++; 
    if (inactivityTime >= inactivityLimit) { 
        player.SetVar("showPopUpLayer", true); 
        stopTimer(); 
    }
}

// **Event Listeners to Reset Inactivity Timer**
document.addEventListener("mousemove", resetInactivityTimer);
document.addEventListener("keydown", resetInactivityTimer);
document.addEventListener("touchstart", resetInactivityTimer);

// **Start inactivity tracker**
function startInactivityTimer() {
    if (inactivityTimer === null) {
        inactivityTimer = setInterval(trackInactivity, 1000);
    }
}

// **Detect window focus loss**
window.addEventListener("blur", function() {
    isFocused = false;
    player.SetVar("isFocused", false);
    player.SetVar("showPopUpLayer", true); // Show pop-up when window is blurred
    stopTimer();
});

// **Detect window focus gain**
window.addEventListener("focus", function() {
    isFocused = true;
    player.SetVar("isFocused", true);
    player.SetVar("showPopUpLayer", false);
    startTimer();
});

// **Detect when tab visibility changes**
document.addEventListener("visibilitychange", function() {
    if (document.hidden) {
        isTabActive = false;
        player.SetVar("isTabActive", false);
        setTimeout(function() {
            player.SetVar("showPopUpLayer", true); // Ensure pop-up layer appears
        }, 500); // Delay helps trigger the layer reliably
        stopTimer();
    } else {
        isTabActive = true;
        player.SetVar("isTabActive", true);
        player.SetVar("showPopUpLayer", false);
        startTimer();
    }
});

// **Start timers**
startTimer();
startInactivityTimer();
  • Hi AmyGtt I think your best approach would be to not use the %correctedElapsedTime% variable as the trigger. As you said, it is a text variable, and so you cannot use the >= operator to determine if 30 minutes has been met.

    You could just have a Boolean variable, for example %timesUp% initialialised as FALSE. Then, on your main timeline you could trigger your Button - 2 "Next" to normal when it is updated to TRUE.

    You would then just need to add some more JS to to trigger that change.

    // Update elapsed time
    function updateElapsedTime() {
        if (isTabActive && isFocused) { 
            elapsedTime++;
            var minutes = Math.floor(elapsedTime / 60);
            var seconds = elapsedTime % 60;
            var formattedTime = minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
            player.SetVar("correctedElapsedTime", formattedTime);
           // ** NEW SCRIPT HERE ** //
           // Is time up?
           if(elapsedTime >= 1800000) player.SetVar("timesUp",true);
        }
    }
    • SamHill's avatar
      SamHill
      Super Hero

      Are you able to share your file? I can take a look for you if you would like?

      • AmyGtt's avatar
        AmyGtt
        Community Member

        No, unfortunately. It's full of sensitive information.

        I do think I figured it out though. Your code got me thinking.