Welcome to the LimeSurvey Community Forum

Ask the community, share ideas, and connect with other LimeSurvey users!

Record timing and limit time to answer set of questions

  • spalan
  • spalan's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 8 months ago #171515 by spalan
Hi all,

I am asking participants to answer as many of two sets of questions as they can manage in two minutes per set, and I need to record how long they take to answer each question.

Let me explain in some more detail. I set my survey to question-by-question mode and activated timing, so that LimeSurvey records the time taken to answer each question. This works fine.

The harder part is that I have created a series of questions (Q001, Q002, Q003,..., Q100) and participants should answer them one after the other, but the survey should automatically move on after they have spent 2 minutes answering these questions, irrespective of how many they have managed to answer. Then, they have to do the same thing again with another set of questions (Q101, Q102 ...). How do I get LimeSurvey to move them on to the next set of questions after a certain time?

I found a solution for setting a time limit for a question group ( www.limesurvey.org/forum/can-i-do-this-w...oups-or-whole-survey ), but if I follow this suggestion, put my questions into a group and set LimeSurvey to group-by-group mode, I can no longer record the exact time taken to answer each question.

I would be grateful for your help!

Best,
Stefan.

PS: We are running LimeSurvey Version 2.05+ Build 150508.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 8 months ago #171557 by tpartner
As I said in your other post, you will need to use a cookie to keep track of the allowed time.

1) Download js.cookie.js and place it in your template directory.
- github.com/js-cookie/js-cookie

2) Add this to the <head> element in startpage.pstpl after the {TEMPLATEJS} placeholder:
Code:
<script type="text/javascript" src="{TEMPLATEURL}js.cookie.js"></script>
3) Run the survey in group-by-group mode (you can place single questions in a group).

4) Enable the survey index in "Full" mode.

5) Place this in template.css to hide the index (this is for a copy of the default template):
Code:
.outerframe.withindex {
    margin: 0 !important;
}
 
#index {
  display: none !important;
}

6) Place this in template.js (this is for a copy of the default template):
Code:
//@name      | initiateTimer
//@author    | Tony Partner
//@editor    | Tony Partner
//@updated_at  | 21/07/2018 16:00:00
//@description  | A function to initiate a cookie-based timer
 
function initiateTimer(allowedTime) {
  // Set the cookie
  var sid = $('input#fieldnames').val().split('X')[0];
  Cookies.set('ls_g_time_'+sid, allowedTime-1, { expires: 365, path: '/' });
}
 
//@name      | runTimer
//@author    | Tony Partner
//@editor    | Tony Partner
//@updated_at  | 21/07/2018 16:00:00
//@description  | A function to run the timer
 
function runTimer(jumpToGroup) {
 
  // Define some vars
  var timerDisplayText = 'Time remaining in this question set:';  // Text in the active timer display
  var hourText = ' hours: ';    // Text appended to hours
  var minuteText = ' minute: ';  // Text appended to minutes
  var secondText = ' seconds';  // Text appended to seconds
 
  var sid = $('input#fieldnames').val().split('X')[0];
  var gid = $('input#fieldnames').val().split('X')[1];
  var lastGroupID = $('#index ol:eq(0) li:eq('+(jumpToGroup-1)+')').attr('data-gid');
  var currentTime = Cookies.get('ls_g_time_'+sid);
 
  // Insert the timer display element
  $('#progress-wrapper').after('<div class="g-timer-display-wrapper" style="border: 1px solid #BBC6CC; width: 200px; margin: 10px auto;">\
                      <div class="g-timer-display-text">'+timerDisplayText+'</div>\
                      <div class="g-timer-display-value"></div>\
                    </div>');
 
  // A function to update the timer display
  function updateTimerDisplay() {
    var displayTime = parseTime(Cookies.get('ls_g_time_'+sid), true, hourText, minuteText, secondText);
    $('.g-timer-display-value').text(displayTime);
  }
  updateTimerDisplay();
 
  // Interval timer
  var gInterval = setInterval(function(){gTimer()}, 1000);
  function gTimer() {
    if(currentTime != 0) { // Update timer cookie and display
      currentTime--
      Cookies.set('ls_g_time_'+sid, currentTime, { expires: 365, path: '/' });
      updateTimerDisplay();
    }
    if(currentTime == 0) { // Stop interval and advance survey
      gTimerStop();
      $('.g-timer-display-wrapper').removeClass('bg-primary').addClass('bg-warning');
 
      // Click on the index
      if(lastGroupID != gid) {
        $('#index li[data-gid="'+lastGroupID+'"]').trigger('click');
      }
    }
  }  
  function gTimerStop() {
    clearInterval(gInterval);
  } 
}
 
//@name      | parseTime
//@author    | Tony Partner
//@editor    | Tony Partner
//@updated_at  | 21/07/2018 16:00:00
//@description  | A function to parse the remaining time
 
var parseTime = function(totalSeconds, showHours, hourText, minuteText, secondText) {
  var hours   = Math.floor(totalSeconds / 3600);
  var minutes = Math.floor((totalSeconds - (hours * 3600)) / 60);
  var seconds = totalSeconds - (hours * 3600) - (minutes * 60);
 
  // Round seconds
  seconds = Math.round(seconds * 100) / 100
 
  var result = '';
  if(showHours) {
     result += (hours < 10 ? "0" + hours : hours)+hourText;
  }
  result += (minutes < 10 ? "0" + minutes : minutes)+minuteText;
  result += (seconds  < 10 ? "0" + seconds : seconds)+secondText;
  return result;
}

7) Place this script in the source of a question where you want to initiate and run the timer. In this example, the timer will run for 30 seconds and then jump the survey to group 4.
Code:
<script type="text/javascript" charset="utf-8">
  $(document).ready(function() {
    // Initiate the timer with allowed time in seconds
    initiateTimer(30);
 
    // Run the timer with the group number to jump to on time expiration
    runTimer(4);
  });
</script>

8) Place this script in the source of every other question where simply want to run the timer. In this example, the survey will jump to group 4 when the allowed time expires.
Code:
<script type="text/javascript" charset="utf-8">
  $(document).ready(function() {
    // Run the timer with the group number to jump to on time expiration
    runTimer(4);
  });
</script>

Sample survey and template attached (install the template before importing the question:

File Attachment:

File Name: limesurvey...7-21.lss
File Size:27 KB

File Attachment:

File Name: test_cookie_timer.zip
File Size:94 KB

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The following user(s) said Thank You: spalan
The topic has been locked.
  • spalan
  • spalan's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 8 months ago #171599 by spalan
Dear TPartner,

This looks extremely helpful, thank you! I have tried to start implementing this in my organization's Limesurvey installation, but I have since found out that they block Javascript for security reasons. So I have decided to use a limesurvey.org-hosted survey.

However, I am stuck when it comes to trying to implement your solution. I have googled around, but I cannot find how to access the template directory in the limesurvey.org-hosted instance. I have also tried to import your .zip-file as a theme, but I get the error message "Can't find a manifest for test_cookie_timer in '/limeservice/instances/10/limesurvey/themes/survey/test_cookie_timer/' ". Is this because the limesurvey.org-hosted instance is version 3.13.2 or simply because uploading it as a theme is not actually what you were talking about?

Sorry if these questions are basic - I have so far used Limesurvey for a few surveys, but I have not yet had occasion to modify some of the more coding-related aspect of it.

Best,
Stefan.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 8 months ago #171606 by tpartner
The solution is for LimeSurvey 2.05 as this is the version you said you are using. Solutions such as this are version-specific.

This took quite a bit of time to develop so I don't know when I'll be able to provide a 3.x version.

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • spalan
  • spalan's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 8 months ago #171758 by spalan
Dear TPartner,

Did you receive my private message?

Cheers,
Stefan.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 8 months ago #171759 by tpartner
Hi Stefan,

Sorry, I rarely check that inbox. I have sent a reply.

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose