January 12, 2019
Adding Timer(Time-Limit) to Captivate Quiz using JavaScript.
Comments
(19)
January 12, 2019
Adding Timer(Time-Limit) to Captivate Quiz using JavaScript.
in It industry as Instructor, Developer since 25+ years. Work on Java, .Net, Network protocols, Different Networking System like Linux, Windows Server . Prog. in Adv. Excel etc.
Newbie 62 posts
Followers: 26 people
(19)
Play

Although Captivate provides Widget to implement timer in Quiz(Test), following simple procedure, using JavaScript, could give you lot more freedom to program and control the Quiz. I regularly use this in the online Test of my Students.
Let me explain with example, steps required for the same.
In a Captivate project, Add following user variables:
Step 1:
User Variables:
cp_min, cp_sec, cp_time_out, time_left:
Create /add questions slides of your choice. I have added simple 5 slides in this Captivate project to explain this procedure.
Step 2:
As shown below, Insert similar Slide, just before 1st Quiz Slide.

Step 3:

“On Exit” Action of this Slide, add JavaScript as scripted below:

Explanation of the above Script: To explain it better, let me divide script in different parts :
Line 1 to 4: setting JavaScript variables and passing it’s value to Captivate. Here you can set time-limit of your choice. For Demo purpose, I have set just 2 minutes as Time-limit.
Line 7 to 23: it is the function which would be called every second by line number 24.
Inside the function: Line number 8 to 13: simple manipulation of seconds , minutes.
Line 15 to 18: checking if the time is Over. And if thime is over Resullt slide is called.

Timer(second_Passed() function) will continually check for Time elapsed. The moment time is up, JavaScript will force program execution to jump from the current question slide to the Result slide.
Note: The candidate who is giving that exam is not necessarily Failed, but marks would be counted for whatsoever correct answers he/she has given in the time-limit, and Result is displayed accordingly.

Step 4:

To inform Student, about this(sudden end of Exam due to time-out), Time-Out message need to be displayed.

In the Result Slide, following Advanced Actions is added to display “Timed-Out” Box, if time was over.

Result:

I hope this will be useful to many who want to add simple time-limit in the Quiz(online exam).

Note: Although everything is shown and working example in also hosted, I have purposely kept one ‘cache’ without explanation. And those who will do it, will come to know about that cache. Try solving that at least for some time… otherwise I will explain that Defiantly. But I strongly believe that first you must try practically.

Request to Expert: Defiantly, You may be knowing the ‘Cache’ and its solution, but please don’t explain and give solution in the immediate post. Let other do by them selves.

19 Comments
2021-01-13 21:11:54
2021-01-13 21:11:54

Tried following the instructions, but some parts aren’t clear. Could you expand and show all the steps to recreate your demo? Also does this work with questions pools?

 

Thank you

Like
(3)
>
ingrellis
's comment
2021-01-14 14:08:45
2021-01-14 14:08:45
>
ingrellis
's comment

Please read my previous comment.  Not sure you’ll ever get an answer from the author.

Personally I never use JS for this type of requirement, but the timing system variables and advanced actions, eventually combined with the Timer or Hourglass interaction. And there is the answer for pools: Yes but cumbersome. You have to design the shared or advanced action so that it can easily be added to all the questions in the pools.

 

Like
(1)
>
Lieve Weymeis
's comment
2021-01-16 20:40:12
2021-01-16 20:40:12
>
Lieve Weymeis
's comment

Hi Lieve,

Thanks for answering me. I used to use the Timer widget form Captivate, but this doesn’t seem to work anymore now that support for Flash/Flash player has stopped. This Is why I have been looking for another way to get such a timer working with advanced actions. Should be fairly easy if you could add if conditions within the while in Captivate 2019. Any help would be very welcome.

Like
>
ingrellis
's comment
2021-01-16 20:45:15
2021-01-16 20:45:15
>
ingrellis
's comment

I have used the Timer (and Hourglass) Learning interaction for HTML5 output. The older ‘widgets’ are not compatible with HTML5 output, but the Learning interactions are.

Often I use it in combination with the timing system variables. I have designed projects where the background of the timer interaction changes color when a certain percentage of the allowed time has elapsed. But more people tell me all the time that I shouldn’t give away so many free workflows.

Like
2020-06-15 07:49:49
2020-06-15 07:49:49

Cannot help, just want to tell that I have not seen Chandresh around since many months, maybe even a year. I doubt he keeps following his thread.

Personally I always use shared or advanced actions for a timer.

Like
(1)
2020-06-12 15:55:43
2020-06-12 15:55:43

Were you able to see my question?

Like
(1)
2020-06-12 15:45:04
2020-06-12 15:45:04

Please advise, I followed all the instructions. Even loaded the user variables I created on enter and assigned them as 0. I know Im missing something…. does it only work when published or should I be able to see the functionality in preview in HTML5?

Like
(1)
2019-08-31 00:15:58
2019-08-31 00:15:58

Tried to post but it didn’t go through.

Like
(1)
(1)
>
michaelb31844492
's comment
2019-08-31 07:56:57
2019-08-31 07:56:57
>
michaelb31844492
's comment

What was the issue, Michael?

Like
(1)
2019-05-14 08:37:53
2019-05-14 08:37:53

Hi, about puts time to a question in a random group of questions, I was wondering if is it possible to create a randomized questionnaire with 30 questions but showing only one question and changing every 24 hours (86400000 miliseconds)?

I have been testing with normal (non-random) question slides by setting this javascript so that every 24 hours I move to the next slide, but the time doesn’t work for me, I move to the next slide when I re-enter the course:

 

window.setTimeout(“window.cpAPIInterface.

next()”,86400000);

 

Any idea if it´s possible something like that?

 

Grettings,

 

 

Like
(1)
2019-03-15 07:48:22
2019-03-15 07:48:22

I will give a try.

Like
(1)
2019-01-14 14:25:52
2019-01-14 14:25:52

I had issues with On Exit actions on many occasions, because it is executed after visiting the last frame of a slide.  If the developer replicating this example adds a Start button to the slide, with the action ‘Go to Next Slide’, will the On Exit script be executed?  Do I miss something like a warning?

I am not the only to recommend never to use the On Exit action, not only for this reason but it is also not always to be  trusted, at least not with advanced/shared actions.

Next question: can this script be entered into a Captivate JS window without  issues? Or are you using an external JS file.

Like
(1)
(5)
>
Lieve Weymeis
's comment
2019-01-14 14:37:58
2019-01-14 14:37:58
>
Lieve Weymeis
's comment

That is why if you see carefully my note, I have applied javascript JUST Before exam start. So when Exam has started, the script is in action in the background regardless of student goes for next slide or not…

Like
(1)
>
chandresh shah
's comment
2019-01-14 14:44:01
2019-01-14 14:44:01
>
chandresh shah
's comment

I did read carefully and I see that you use the On Exit action on the slide inserted just before the first quiz slide. I was talking about that slide (with Good Luck). If the developer adds a button Start to that slide, with the simple action ‘Go to Next Slide’ pausing that slide to give control to the learner, will your script be executed? Of course you need to start the timer at least on the first frame of the first question slide, which is not possible if those are random questions. I would prefer to use an On Enter action of a very short slide (0,1secs) before the quiz slide, not on a meaningful slide like the one with Good Luck.  Maybe I explained not well in my previous answer.

Like
(1)
>
Lieve Weymeis
's comment
2019-01-14 15:06:58
2019-01-14 15:06:58
>
Lieve Weymeis
's comment

See, the point of Random Question comes when Exam starts. That’s why, I have added script JUST before that. So, when Exam has started, means Script got executed and is in memory of computer… and is working continuously every second. Let me repeat, I use this in my all exams where I, my self, always use random questions from Q pool. It is 100% logical.

Your suggestion of using the script on very short slide was also used by me in my earlier exams. But the practical problem is, sometimes, we delete many duplicate or meaningless slides(that gets generated by simulation). and we may forget that this short slide is having a very important script. and we may delete by-mistake. So I purposely added this Script to ‘Good Luck’ Slide. Because regardless of the subject of any Exam, I will always use Good luck Slide. and thereby it assured that script has come.

Otherwise, your point is also good.

Like
(1)
>
chandresh shah
's comment
2019-01-14 15:24:40
2019-01-14 15:24:40
>
chandresh shah
's comment

At least add a warning that the developer should never use an interactive object on that slide with the On Exit action!  I am very well aware of the necessity of having the timer started with the first question, which is not possible using an On Enter action if it is a random question. I have created a lot of timers for clients with Shared actions, but they required more functionality than what you explain in this tutorial. I needed to use scripts on each pool question as well.

What about that script: is it in the Captivate JS window? No problems with some characters in that case? Whenever using functions in JS I prefer to use an external file for that reason.

Like
(1)
>
Lieve Weymeis
's comment
2019-08-31 00:14:19
2019-08-31 00:14:19
>
Lieve Weymeis
's comment

Hi, Had a stakeholder who required an over all countdown,  and wanted to retain the remaining time even after resuming the course , which gets really tricky.  I used the same variables in captivate, and you just have to set a few variables including, the total seconds,  the first slide number with quiz questions, and the slide quiz review slide number.  I chose to add this in a script tag in the index_scorm.html page.

I use localstorage, and even if the user switches browsers, which local storage is per browser, it will estimate the average time per slide if they resume mid quiz.

 

//Values Needed////////
var defaultSeconds = 14400;//4 hours
var default_net= “Loading Time..”;
var startSlide = 3;//first slide with quiz questions
var targetSlide = 153;//slide with quiz review
/////////////////////////
var timerActive = false;
var startTimer = false;
var firstSlideIndex = -1;
var seconds;
var minutes = Math.round((seconds)/60);
var net_time = default_net;
var countdownTimer;
//In case user switches browser with different local storage
var estimatedTimePerQuestion = Math.round(defaultSeconds/((targetSlide)-startSlide));
console.log(“Est time per question ” + estimatedTimePerQuestion);
window.addEventListener(“moduleReadyEvent”, function(evt)
{
window.cpAPIEventEmitter.addEventListener(“CPAPI_SLIDEENTER”,
function(evt)
{
console.log(“Entering slide: ” + evt.Data.slideNumber);

if (firstSlideIndex ==-1 && evt.Data.slideNumber == 1 )//First Attempt
{
console.log(“First Attempt”);
firstSlideIndex=evt.Data.slideNumber;
seconds = defaultSeconds;
window.cpAPIInterface.setVariableValue(“time_left”,default_net);
}

if(!timerActive && evt.Data.slideNumber == startSlide)
{
startTimer = true;
}

if(firstSlideIndex == -1 && evt.Data.slideNumber > (startSlide -1) && evt.Data.slideNumber < (targetSlide+1))
{
//NOT first Attempt, resuming
var storageAvailable = false;
if(typeof(Storage)!==’undefined’)
{
if(localStorage && !timerActive)
{
console.log(“Local Storage Available”);
storageAvailable = true;

seconds = parseInt(localStorage.timeremaining );
if(isNaN(seconds)||seconds == “”) seconds = defaultSeconds;
console.log(“seconds resulting from local storage: ” + seconds);
net_time = Math.round((seconds)/60) + “:” + (seconds % 60);
}
else if( !timerActive)
{
console.log(“Re-entering after close and or complete,”);
firstSlideIndex=evt.Data.slideNumber;
firstAttempt = true;
seconds = defaultSeconds;
window.cpAPIInterface.setVariableValue(“time_left”,default_net);
}
}
if(!storageAvailable && !timerActive)
{
console.log(“User switched browsers or cleared storage, get current slide resumed to calculate time remaining // if resume slide is after quiz questions, cancel”);
seconds = estimatedTimePerQuestion*((targetSlide-1) – evt.Data.slideNumber);
if(seconds==-1)return;
net_time = default_net;
}
startTimer = true;
}
//If reached the quiz summary page, need to reset values;
if(evt.Data.slideNumber == (targetSlide+1))
{
seconds = defaultSeconds;
timerActive = false;
startTimer= false;
try{clearInterval(countdownTimer);}catch(e){}
}
//if first attempt and entering first slide, or resuming and within target range and first resuming
if(!timerActive&& startTimer )
{
timerActive = true;
console.log(“starting timer”);
window.cpAPIInterface.setVariableValue(“cp_min”,0);
window.cpAPIInterface.setVariableValue(“cp_sec”, 00);
countdownTimer = setInterval(“second_Passed()”, 1000);
}
});
});

function second_Passed()
{
seconds–;
console.log(seconds);
remainingSeconds = seconds % 60;
minutes = Math.floor((seconds)/60);
if(typeof(Storage)!==’undefined’)
{
if(localStorage)
{
localStorage.timeremaining = seconds;
}
}
if(remainingSeconds < 10)
{
remainingSeconds = “0” + remainingSeconds;
}
if(minutes<=0 && remainingSeconds<1)
{
clearInterval(countdownTimer);
var getSlides = cp.model.data.project_main.slides.split(“,”);
alert(“You’re out of time!”);
window.cpCmndGotoSlideByUIDAndResume = getSlides[targetSlide].substring(5, getSlides[targetSlide].length);
timerActive = 0;
}
var _hours = (minutes/ 60);
var _rhours = Math.floor(_hours);
var _minutes = (_hours – _rhours) * 60;
var _rminutes = Math.round(_minutes);

net_time = _rhours + “:” + _rminutes + “:” + remainingSeconds;
window.cpAPIInterface.setVariableValue(“cp_min”, minutes);
window.cpAPIInterface.setVariableValue(“cp_sec”, remainingSeconds);
window.cpAPIInterface.setVariableValue(“time_left”, net_time);
}

Like
(1)
2019-01-14 08:53:29
2019-01-14 08:53:29

Thanks for posting this workflow. It would be interesting to compare with my usual workflow without any JS, only with shared actions.   In most cases I need to do this with random slides generated from question pools. Did you try that?

 

Like
(1)
(1)
>
Lieve Weymeis
's comment
2019-01-14 14:12:48
2019-01-14 14:12:48
>
Lieve Weymeis
's comment

Yes. I always create my tests(quiz) with random Q. slides and use this for time-limit. Just to make it simple, I kept static questions in this uploaded Demo.

Like
(1)
Add Comment