Actions

Workarounds: Survey behaviour

From LimeSurvey Manual

LimeSurvey users have been very creative in finding out how to change the behavior of a survey. All their workarounds are listed here. You can find some similar approaches at:


Please keep in mind that these workarounds are not official LimeSurvey extensions - they are solutions that users have created for themselves.
Therefore LimeSurvey can't offer guarantees or support for these solutions.
If you have questions, please contact the users that, thankfully, shared their solutions with the community.


Respond multiple times using the same computer

Tested with:

With this workaround it will be possible to respond multiple times to the same survey. Normally there will be a message saying that the computer already received the answers. To prevent this you have to add the following code to the URL that leads to the survey "&newtest;=Y".

Example of the "new" url:

http://www.yourdomain.org/limesurvey/index.php?sid=12345&newtest;=Y

Allow Multiple Survey Invitations to the same Email Address to be completed in the Same Browser Session

Tested with:

Problem: When Multiple Surveys Invitations are activated during the same browser session, the second and subsequent survey activation results in a system message stating that the survey has already been completed. A user would have to close the browser and reopen in order to complete the next survey inviation.

Workaround: Edit the Survey Invitation Email (also the reminder) Template. Append "&newtest;=Y" to the {SURVEYURL} line so it looks like this {SURVEYURL}&newtest;=Y

Save the edited templates.

Note: The save of this template edit does not seem to work when using HTML invitations, only text based invitations.

Add a data field to manually add data

Tested with:

If you want to add some additional data after a user has finished a survey you can use the dataentry screen of the admin panel. You have to set up the survey as follows:

  1. Create a question that can store the needed data at the end of the survey.
  2. Use conditions on the previous question so that whatever is answered at the previous question the following question doesn't appear.
  3. To enter several questions repeat steps 1-2. Don't forget to adapt the conditions.
  4. Go to the admin panel, chose the survey from the list and go to Dataentry screen for survey.
  5. Enter the additional data

Randomization

Important.png  All these workarounds can be replaced using therandomization group name attribute (located in the question settings) or |randomization group at group level.



Totally random survey order

Tested with:

If you want to use random order globally for all questions in your survey, you can do it like this, depending on what type of question routine you use.

  1. If you use Group by Group add "shuffle($_SESSION['grouplist']);" at the end of UpdateSessionGroupList($language) function in index.php
  2. If you use Question by Question or All-in-one put "shuffle($_SESSION['fieldarray'])" at the end of buildsurveysession() function in index.php

Important: This modifications affect all surveys in application, you may want to use an if statement with surveyid to make this work with specific surveys e.g.

if ($surveyid==12345)

{

  do_some_shuffling()

}
  • Saving survey is not possible because this workaround doesn't save random order for specyfic tokens.
  • Solution doesn't care about language changes so if you have on in your survey this will not work.
  • Using conditions is not possible because conditions rely on a fixed and pre-determined order of questions.

Randomize the order of sequences of groups in a survey

Tested with: 1.86

You can randomize the order of subsequences of groups in a survey. E.g., you may have a survey comprising the below group structure

  • demographics
  • itemgroup1
  • itemgroup2
  • itemgroup3
  • interlude
  • itemgroup4
  • itemgroup5
  • itemgroup6
  • closingcomments

and want to separately randomize the presentation order of itemgroup1...3 and itemgroup4...6 while maintaining the position of the other three groups. A working code modification is described in the PDF file randomize_groups which is downloadable from the Bugtracker at [1].

  • Note: The code will randomize the order of subsequent groups in isolation, not across different sequences. Hence in the above example, you might get itemgroup1, 3, 2 but never itemgroup1, 4, 2
  • Note: The survey presentation format must be Group by Group not Question by Question
  • Note: If you wish to select only a limited number of groups from a larger set, replace
$scratcharr = array_merge($scratcharr, $randarr);

with

$scratcharr = array_merge($scratcharr, array_slice($randarr,0,x));

where x is the number of elements/groups that you wish to include. In the example above $scratcharr = array_merge($scratcharr, array_slice($randarr,0,2)); would select two out of the possible three groups in each group set.

  • Warning: The code is compatible with conditions operating on items within a group but most possibly produces erroneous behavior with conditions between groups
  • Warning: In a multi-language survey, the groups get randomized each time the language is changed. A simple workaround is to remove the language changer from the question pages of the survey leaving it on the welcome page only. (Though not totally foolproof this does lower the risk of unnecessary language changes.)


Randomly show X out of Y question groups

This workaround allows you to randomly show X out of Y question groups

Tested with: Version 2.06+ Build 150612 Default template

Workaround created by user "OMdev"

  • Set up your survey to use JavaScript.
  • Create a multi question with y number of answer options. Randomize this question from question settings.
  • Select top X number of check boxes by add the following script to the source of this question.
<script>
$(function(){
$('body').hide() //Hiding multi select question using JavaScript . You can also hide it with CSS.
var showNumberOfGroups = 2; //enter number of check box to select from top ie number of groups to show randomly.
var $cboxs = $('input:checkbox');
	for(var i=0;i<showNumberOfGroups;i++){
		$cboxs.eq(i).prop('checked',true);
	}
document.getElementById('movenextbtn').click();//auto submitting page.
})
</script>
  • Add group relevance from the multi select question.
  • You can download lss from below link.

https://www.limesurvey.org/en/forum/can-i-do-this-with-limesurvey/102176-show-x-out-of-y-question-groups#126288

Selective Question Randomization

Tested with: 1.82

With this workaround you are able to select which groups within a survey should have their questions randomized and not kept in order. This workaround also adds a tab in the question ordering page. The extra tab allows you to enable / disable question randomization for the selected group.

A working code and database modification is described in the PDF file selective_random_questions which is downloadable from the Bugtracker at [2].

Note: This might not work when adding conditions or assessments to the survey.

Randomize the order of questions within individual groups - JavaScript solution

Tested with: 1.85+ (7557), IE 6/7, Firefox 3.0, Safari 3.2

This workaround allows you to randomize the order of questions in individual groups. It uses JavaScript/jQuery to apply this randomization to only those groups that you wish and requires no modification of the core files when updating the installation.

The script uses a cookie to "remember" the shuffled order of the questions for the duration of the session so if a respondent navigates away from the group and returns, they will see the same question order. However if the survey is submitted or the session expires the questions will be re-shuffled.

A couple of cautions about the script are:

  1. If the survey is saved, the questions will be re-shuffled when it is accessed again (as with the PHP solution).
  2. The question shuffling may play havoc with conditions within a group (as with the PHP solution).
  3. The script has been tested with all templates shipped with 1.85+ but if you have a custom template with "question" in the ID of division(s) (ie <div id="questionHolder">) it may fail - the script looks for all divs with IDs starting with "question" and adds them to an array to be shuffled.

There is a small demonstration here.

Put simply, the script:

  1. Checks cookies to see if the questions have already been shuffled for this group and session.
  2. If so - displays the questions in that order.
  3. If not - creates an array of all of the questions in the group, shuffles the array, sets a cookie with the shuffled array contents, displays the questions in the shuffled order.

Implementation is as follows:

  1. Turn off $filterxsshtml to allow insertion of JavaScript (see documentation here)..
  2. Create your group and questions.
  3. In the source of the group description add the following onload function (see How to use script).

Onload code:

<script type="text/javascript" charset="utf-8">

   $(document).ready(function() {

       function shuffleQuestions() {

           // Create an array to hold question IDs

           var qArray = new Array();

           // Find the group ID of the page

           var fieldNames = $( 'input#fieldnames' ).attr('value');

           var tmp = fieldNames.split('X');

           var sID = tmp[0];

           var gID = tmp[1];

           // A function to get the value of a cookie by name

           function getCookie ( cookieName ) {

               var results = document.cookie.match ( '(<div class="simplebox">|;) ?' + cookieName + '=([</div>;]*)(;|$)' );

               if ( results ) {

                   return ( unescape ( results[2] ) );

               }

               else {

                   return null;

               }

           }

           // Get the session name

           var sessionName = getCookie ( 'PHPSESSID' );

           // Check to see if the question order has already been shuffled in this session

           var cookieArray = getCookie ( 'sArray' + gID + '_' + sessionName );

           // If already shuffled, use that question order

           if ( cookieArray ) {

               //qArray = $.trim(cookieArray);

               qArray = cookieArray.split(',');

           }

           // If not, go ahead and shuffle

           else {

               // Load the IDs of all questions on the page into the array

               $( 'div[id<div class="simplebox">="question"]' ).each(function(i) {

                   qArray.push($( this ).attr('id'));

               });

               // Shuffle the questions array

               function shuffle(o){

                   for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);

                   return o;

               }

               shuffle(qArray);

               // Set a cookie with the value of the shuffled array

               var today = new Date();

               today.setTime( today.getTime() );

               var expires = 2 * 1000 * 60 * 60 * 24; // Expire the cookie in 2 days

               var expiresDate = new Date( today.getTime() + (expires) );

               document.cookie = 'sArray' + gID + '_' + sessionName + '=' + qArray + ';expires=' + expiresDate.toGMTString();

           }

           // Wrap the questions in a div

           $( 'div[id</div>="question"]' ).wrapAll( document.createElement('div') );

           $( 'div[id<div class="simplebox">="question"]:eq(0)' ).parent().attr('id', 'qWrapper');

           $( 'div#qWrapper' ).css({

               'padding':0,

               'margin':0

           });

           // Insert the questions into the wrapper in the shuffled order

           $.each(qArray, function(i, val){

               $( 'div#' + val + '' ).appendTo( $( '#qWrapper' ) );

           });

       }

       shuffleQuestions();

   });

</script>

Randomise the order of questions within groups

Tested with:

You can randomize the order questions of within groups (i.e. without interleaving questions from different groups) like this:

1 Call a custom function from the last line of buildsurveysession() before the return statement in index.php:

$_SESSION['fieldarray'] = withinGroupsShuffle();

2. Add these custom functions at the end of the same file:

$currentGid;

function withinGroupsShuffle() {

   global $currentGid;

   $groupArray = array();

   $shuffledArray = array();

   foreach ($_SESSION['grouplist'] as $group)    {

       $currentGid = $group[0];

       $groupArray = array_filter($_SESSION['fieldarray'], "questionInGroup");

       shuffle($groupArray);

       $tmp = $shuffledArray;

       $shuffledArray = array_merge($tmp, $groupArray);

       $groupArray = array();

   }

   return $shuffledArray;

}

function questionInGroup($question) {

   global $currentGid;

   return ($question[5] == $currentGid) ? 1 : 0;

}

(I'm new to PHP, so please make changes if you can make the code shorter or more elegant)

This could be combined with the method mentioned above for shuffling the order of groups:

shuffle($_SESSION['grouplist']);

I don't know how this code affects or is affected by conditions or tokens! This code has the same limitations as the global randomisation above: it applies to all groups in all surveys. It would be nice to add a group-level parameter like randomise_questions = [0|1], but I can't find a mechanism for doing that.

Randomize all questions in "All In One" mode - even if they are place in groups.

Tested with: 1.91, IE 7/8, Firefox 3.6, Safari 3.2

This workaround will randomize all questions when using "All In One" mode, even if they are place in groups. This may be useful if you want to use group assessments and display all questions on a single page in a random order.

Notes:

  • The workaround is tested in the default template and may need slight tweaks for others.
  • It is NOT tested with conditions.

Implementation is as follows:

  1. Set up your survey to use JavaScript.
  2. Add the following script to the source of one of the questions.
<script type="text/javascript" charset="utf-8">

   $(document).ready(function() {

       shuffleQuestions();

       function shuffleQuestions() {

           // Hide the group wrappers

           $('div[id</div>="group-"]').hide();

           // Create and insert a new question wrapper

           var qWrapper = '<div id="qWrapper">\

                       <table class="group"> \

                           <tbody> \

                               <tr> \

                                   <td> \

                                   </td> \

                               </tr> \

                           </tbody> \

                       </table>\

                   </div>';

           $('div[id<div class="simplebox">="group-"]:last').after(qWrapper);

           $( 'div#qWrapper td' ).css({'padding-top':'10px'});

           // Create an array to hold question IDs

           var qArray = new Array();

           // Load the IDs of all questions on the page into the array

           $('div[id</div>="question"]').each(function(i) {

               qArray.push($(this).attr('id'));

           });

           // Shuffle the questions array

           function shuffle(o){

               for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);

               return o;

           }

           shuffle(qArray);

           // Insert the questions into the new question wrapper in the shuffled order

           $.each(qArray, function(i, val){

               $('div#' + val + '').appendTo($('#qWrapper td:first'));

           });

       }

   });

</script>

Random question sets

Pre 2.0

Tested with: 1.85+ (7557), IE 6/7, Firefox 3.0, Safari 3.2

This workaround, in conjunction with the randomizing questions script, allows you to display a random set of questions in a group.

JavaScript is used to first shuffle the question order and then hide the number of questions that you stipulate, effectively giving respondents a random question set. So if you have 5 questions in your group and choose to hide 2, the respondents will be presented with a random 3 questions.

A brief explanation of the script is:

  • The questions are shuffled (see randomizing questions) and their IDs placed in an array.
  • The number of questions to be shown is calculated and their IDs are moved to a new array.
  • All questions in the first array are hidden - this effectively hides the first n questions on the page so you'll get a random set of questions displayed.
  • An asterisk is prepended to the remaining questions (remove this if your questions are not mandatory).
  • When the next/submit button is clicked, all remaining questions are checked for an answer. If any are unanswered, their text is turned red, an alert is popped up and the next/submit is aborted (remove this if your questions are not mandatory).

A cookie is used to "remember" the shuffled order of the questions for the duration of the session so if a respondent navigates away from the group and returns, they will see the same question set. However if the survey is submitted or the session expires, the questions will be re-shuffled and a new set will be displayed. Therefor this workaround should not be used with surveys that can be saved.

A couple of cautions about the script are:

  1. If the survey is saved, the questions will be re-shuffled when it is accessed again and a new question set will be displayed.
  2. The question shuffling may play havoc with conditions within a group.
  3. The script has been tested with all templates shipped with 1.85+ but if you have a custom template with "question" in the ID of division(s) (ie <div id="questionHolder">) it may fail - the script looks for all divs with IDs starting with "question" and adds them to an array to be shuffled.
  4. The script may need to be modified to display the "Mandatory" asterisk in templates other than the default - see below.

Implementation is as follows:

  1. Turn off $filterxsshtml to allow insertion of JavaScript (see documentation here).
  2. Create your group with all questions non-mandatory (we'll make them mandatory later with JavaScript).
  3. In the source of the group description add the following script (see How to use script here).
  4. Modify the function call at the end of the script for the number of questions to be hidden and the mandatory error text.
<script type="text/javascript" charset="utf-8">

	$(document).ready(function() {

		function shuffleQuestions() {
			// Create an array to hold question IDs
			var qArray = new Array();

			// Find the group ID of the page
			var fieldNames = $( 'input#fieldnames' ).attr('value');
			var tmp = fieldNames.split('X');
			var sID = tmp[0];
			var gID = tmp[1];

			// A function to get the value of a cookie by name
			function getCookie ( cookieName ) {
				var results = document.cookie.match ( '(<div class="simplebox">|;) ?' + cookieName + '=([</div>;]*)(;|$)' );
				if ( results ) {
					return ( unescape ( results[2] ) );
				}
				else {
					return null;
				}
			}

			// Get the session name
			var sessionName = getCookie ( 'PHPSESSID' );
			// Check to see if the question order has already been shuffled in this session
			var cookieArray = getCookie ( 'sArray' + gID + '_' + sessionName );
			// If already shuffled, use that question order
			if ( cookieArray ) {
				//qArray = $.trim(cookieArray);
				qArray = cookieArray.split(',');
			}
			// If not, go ahead and shuffle
			else {
				// Load the IDs of all questions on the page into the array
				$( 'div[id<div class="simplebox">="question"]' ).each(function(i) {
					qArray.push($( this ).attr('id'));
				});
				// Shuffle the questions array
				function shuffle(o){
					for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
					return o;
				}

				shuffle(qArray);

				// Set a cookie with the value of the shuffled array
				var today = new Date();
				today.setTime( today.getTime() );
				var expires = 2 * 1000 * 60 * 60 * 24; // Expire the cookie in 2 days
				var expiresDate = new Date( today.getTime() + (expires) );
				document.cookie = 'sArray' + gID + '_' + sessionName + '=' + qArray + ';expires=' + expiresDate.toGMTString();
			}

			// Wrap the questions in a div
			$( 'div[id</div>="question"]' ).wrapAll( document.createElement('div') );
			$( 'div[id<div class="simplebox">="question"]:eq(0)' ).parent().attr('id', 'qWrapper');
			$( 'div#qWrapper' ).css({
				'padding':0,
				'margin':0
			});

			// Insert the questions into the wrapper in the shuffled order
			$.each(qArray, function(i, val){
				$( 'div#' + val + '' ).appendTo( $( '#qWrapper' ) );
			});
		}

		shuffleQuestions();

		function hideQuestions(numberToHide, mandatoryMsg) {
			// Create an array of the IDs of all questions on the page
			var questions = new Array();
			$( 'div[id</div>="question"]' ).each(function(i) {
				questions.push($( this ).attr('id'));
			});

			// Remove the "shown" questions and place them in a new array
			var questionsLength = questions.length;
			var shownQuestions = questions.splice(numberToHide,questionsLength-numberToHide);

			// Hide the remaining questions
			$.each(questions, function(i, val){
				$( 'div#' + val + '' ).hide();
			});

			// Add an asterisk to the "shown" questions
			// NOTE: Comment this section out if questions are not mandatory
			$( 'td.questiontext' ).prepend( '<span class="asterisk">*</span>');

			// Interrupt the submit function and validate mandatory questions
			// NOTE: Comment this section out if questions are not mandatory
			$('form#limesurvey').submit(function(){
				// Override the built-in "disable navigation buttons" feature
				$('#moveprevbtn, #movenextbtn, #movesubmitbtn').attr('disabled', '');

				// Loop through all "shown" questions and check for answer
				var answered = 0;
				$.each(shownQuestions, function(i, val){
					if ( $( 'div#' + val + ' input.radio:checked' ).length == 0 ) {
						$( 'div#' + val + '' ).css('color', 'red');
						answered = 1;
					}
					else {
						$( 'div#' + val + '' ).css('color', '');
					}
				});

				if ( answered == 1 ) {
					alert ( mandatoryMsg );
					return false;
				}
				else {
					return true;
				}
			});
		}

		// Call the hide function
		// Edit here for number of question to hide and mandatory message
		hideQuestions(2, 'Please complete all questions');
	});
</script>

To add the asterisk to non default templates, replace $( 'td.questiontext' ).prepend( '*');'' with:

- basic - $( 'td.be' ).prepend( '*');

- bluengrey - Not possible to insert asterisk in correct location

- business_grey - $( 'div.questiontext' ).prepend( '*');

- clear_logo - $( 'td.be' ).prepend( '*');

- default - $( 'td.questiontext' ).prepend( '*');

- eirenicon - Not possible to insert asterisk in correct location

- limespired - $( 'div.survey-question-text' ).prepend( '*');

- mint_idea - $( 'div.survey-question-text' ).prepend( '*');

- sherpa - $( 'div.survey-question-text' ).prepend( '*');

- vallendar - Not possible to insert asterisk in correct location

Version 2.0 And Newer

Here is a link to a sample survey showing how to do this with Relevance - Randomly Ask A Specific Number Of Questions In A Group (a subset of the questions)

Randomization - Assign People Randomly To Surveys

Tested with:

This is a very easy way to assign people randomly to surveys, I think experts do it in other ways, but it works for me.

LINK.PHP:

<?php 
  $db = @file("link.txt"); // path to .txt file 
  $anz = @count($db); 
  srand((double)microtime()*1000000); // random numbers 
  $random = rand(1,$anz); 
  print $db[$random-1]; 
  ?>

LINK.TXT:

<meta http-equiv="refresh" content="1;url=http://www.survey1.com"> 
<meta http-equiv="refresh" content="1;url=http://www.survey2.com">

Only one link per line!

INDEX.PHP:

<html>
  <head><title>title</title> 
  
  <?php 
  include("link.php"); 
  ?> 
  
  </head> 
  <body> 
  <!-- shows the loading statement --> 
  <table width=100% height=100%>  
  <tr>
  <td valign=middle>
  <center><font size=5>loading ... </font></center>
  </td>
  </tr>
  </table> 
  <!-- shows the loading statement --> 
  </body> 
  </html>

Random Redirect responders to surveys

Tested with:

As the workaround above, this one assign randomly (uniform distribution) people to multiple surveys in easier way, but with the same outcome: every survey has the same probability to be accessed by a responder.

1. Copy and paste the code below in a text editor. 2. Replace the URLs with those of your surveys, and save it as index.php 3. Create a new directory in your server. 4. Upload the file in that directory and give the link (http://www.yourdomain.com/newdirectory) to the responders.

<?php 
$urls = array("www.site1.com", 
              "www.site2.com", 
              "www.site3.com"); 
$url = $urls[array_rand($urls)]; 
header("Location: http://$url"); 
?>

Prefilling survey elements

There are some ways to pre-fill elements in a survey. The data to prefill an answer can be passed by URL if it matches a certain format.

Prefilling survey answers using the survey URL

Tested with: 1.80 and later

You can prefill answers to questions in your survey by passing the SGQA identifier, and the answer, as a parameter of your survey URL. This feature will only work where the survey is commenced immediately upon entering the URL (so it won't work if you use CAPTCHA's to restrict access, or the registration page).

You'll need to ensure that the answer you pass is the correct format for the question you are attempting to prefill - for example - multiple option questions should contain a "Y" to check a box. List type questions need the correct answer code. To be certain which codes to pass, complete a survey manually with the prefilled answer(s) you want, and then export the results as question codes and answer codes(not full text). This will give you both the correct SGQA identifier (the name of the column), and the correct format for the answer.

Starting with version 1.92+, you can use qcode naming for the variables in addition to, or instead of, using SGQA naming.
In version 2.x the link for a prefill have to look like that: http://www.example.com/index.php/survey/index/sid/712544/newtest/Y?712544X99X2151=gelb&712544X99X2152=12345
And if your question code is QCODE and CODE2, you can use it like that : http://www.example.com/index.php/survey/index/sid/712544/newtest/Y?QCODE=gelb&CODE2=12345 It's important to add "newtest/Y" to the link.


Example:

With 2.0, if your url is like this /survey/sid/1234, you have to use:

When the user gets to that question, the "Y" will be prefilled as the answer to question 123 in group 43 in survey 1234.

Example Single-Choice:

With 2.0, if your url is like this /survey/sid/1234, you have to use:

If you like to prefill a single choice question (answer-code A1 - X ), you have to write this. If you export the results of this question, you will see, that this kind of question save the answer code as result in table. Use in any case the capital "X" in the link!

Prefilling survey answers using the survey URL and hiding the Answer

Starting with version 1.87 every question has a property 'Always hide this question' which can be used for this purpose.

Prefilling a date question with the current date

Tested with: 1.80RC3

Workaround created by user "Mazi"

Using the workaround mentioned above you can prefill the current date for a date question. Instead of using the common link to a survey which looks like this

you create an additional script, let's call it date.php. This script contains the following code:

<?php

   $date = date("Y-m-d");

   header("Location: http://www.yourdomain.org/limesurvey/index.php?sid=53298&newtest;=Y&lang;=de&53298X15X102=$date");

?>

The script determines the current date and calls the survey with a certain URL. The current date is attached as the answer for a certain date question using SGQA identifier. Don't forget to adjust the SID and SGQA identifier according to your survey/group/question ID!

Upload the new date.php file into your limesurvey directory. You can then call the survey using this link:

Things to watch out for:

  • Date questions always use the internal date data format of the database which has to be YYYY-MM-DD!
  • You have to adjust the SID at the URl.
  • Also adjust the SGQA identifier (SIDXGIDXQID) according to your survey.
  • This solution doesn't work if you use tokens at your survey.

Offer option to change answers later

Tested with:

When having a closed access survey using a token table it is possible to offer the opportunity to change answers later. Normally after having submitted the answers a token is marked as "used". To prevent this do as follows:

  • set your survey to question-by-question mode (or group-by-group mode)
  • set the survey to Non anonymous + Allow persistence for token answers
  • activate survey and create your token table
  • add at least one question of type boilerplate (which contains just some text). This is necessaray to give some instructions to the user like "Your answers have been recorded to the DB, if you're sure you won't modify them, you can submit your response. If unsure, please quit your browser now and get back later with the private URL you've received.

By not submitting the survey the user is still able to change the answers later.

Use general password for accessing a survey

If you don't want to use tokens but a general password to access a survey you can set your survey to "allow public access". Don't create a token table but use the following workaround:

  1. Create a short text question first
  2. Create the other questions
  3. Use conditions on all the other questions. You can use regular expressions to validate the string entered at the short text question. Just validate a certain password. If the password is correct the following questions are shown.
  4. Create a boilerplate question which just says "invalid password" which is shown if the user entered a wrong password.

Create token on the fly and Edit completed survey

Warning: The link for the code link is wrong (June 2013)

When having a close token survey you can create a token on the fly by giving as parameters sid and token.

In addition if someone has already completed a survey he can review his answers and correct them.

Just put this script attached at the bugtracker ticket into limesurveys root directory

Prerequisites:

  1. Anonymous answers? No (This survey is NOT anonymous.)
  2. Enable Token-based answers persistence? Yes
  3. Switch to closed-acces mode

Example:

where Survey id = 98761 your survey's id and token=12345 a token (any token actually)

  1. The first time the token will be created and you you will redirect to anwser the surrvey
  2. If you wont complete the survey and call the script with the same parameters you will be redirect to the same case in order to finish the survey
  3. If you finish the survey and call the script with the same parameters you will see restart the survey with your previews answers prefiled so you can change them
  4. Back to 3

this is valid for all survey in the installation but you can make a filter so it wont be valid for every survey.

Reference

  • You can find the code provided by user "janokary" and a short explanation at the LimeSurvey Bug & Feature Tracker: [3]

multiple 'completed' with only one token

Tested with: 1.71

Whit a closed survey, each token work only one time. Sometime we need the possibility to complete a particular survey several time with the same token. This works only if you survey is set to non-anonymous answers and to use datestamps.

Here is an example for the survey id '71314'. Don't forget to adapt your own sid.

Edit index.php to in the function submittokens() replace lines ~ 1312 :

if (bIsTokenCompletedDatestamped($thissurvey))

   {

   $utquery .= "SET completed='$today'\n";

   }

   }

   else

   {

   $utquery .= "SET completed='Y'\n";

with lines :

if (bIsTokenCompletedDatestamped($thissurvey))

   {

   //multiple token only for survey 71314

   if ($surveyid == '71314') {

   $utquery .= "SET completed='N'\n";

   }else {

   $utquery .= "SET completed='$today'\n";

   }

   }

   else

   {

   //$utquery .= "SET completed='Y'\n";

We never update the database with the completed date and time for this survey.

Warning : a limitation of this code is that you never recieve a confirmation mail for the completed.

Loop question(s)

Tested with: 1.85

There is no real loop option within LimeSurvey 1.x. To loop a question an initial question to determine the number of loops is needed. Looping is then done using a condition workaround:

1. Create a single choice question asking "How many X do you want to rate", possible answers 1, 2, 3, 4, 5.

2. Create up to 5 following questions asking "Please rate item 1/2/3/...".

3. Check manual -> conditions and read it carefully.

4. Set conditions like

a) "Only show Q3 (Rate item 2) IF Q1 (How many...) was answered 2

OR Q1 (How many...) was answered 3

OR Q1 (How many...) was answered 4

OR Q1 (How many...) was answered 5"

b) "Only show Q4 (Rate item 3) IF Q1 (How many...) was answered 3

OR Q1 (How many...) was answered 4

OR Q1 (How many...) was answered 5"

c) Q5... see above

d) Q6...

Of course Q2 is always shown, the following question will be added by conditions depending on what the user answered at Q1.


Prevent accidentially closing the survey

Sometimes you want to ask the user to confirm that they want to close an incomplete survey and/or use the back/reload buttons (which might break LimeSurvey).

A solution can be done in javascript, as discussed in the forum: https://www.limesurvey.org/en/community-services/forums/can-i-do-this-with-limesurvey/96384-prevent-accidentially-closing-the-survey

You can add this functionality in the template.js file:

//FEATURES: (2015-03-27) Now with fix for iframes (e.g. file uploader) and the template editor 
function goodbye(e) {
    if(!$('body', top.document).hasClass('submitted') && !$('#completed').length && !$('.templateeditor', top.document).length) { //check if a button was used to navigate OR the survey is completed OR the template is displayed in the template editor

		if(!e) e = window.event;
		//e.cancelBubble is supported by IE - this will kill the bubbling process.
		e.cancelBubble = true;
		e.returnValue = 'Are you sure you want to quit this survey?'; //This is displayed on the dialog for IE
 
		//e.stopPropagation works in Firefox.
		if (e.stopPropagation) {
			e.stopPropagation();
			e.preventDefault();
		}

		return 'Are you sure you want to quit this survey?'; // For chrome
	}
}

window.onbeforeunload = goodbye;

$(document).on('click', '.button, .changelang, [name="move"]', function(event){ //added .changelang here, please add other classes if you know which should be allowed to navigate
	$('body', top.document).addClass('submitted');
});

Alternate system for Ranking

Sometimes default ranking are not usable for your survey. But Expression manager unique function can easily be used for other question type.

  • With an 'Array' question where answer are number from 1 to X (X is the max number of choice to rank).
    • 'Question validation equation': unique(self)
  • With a 'Multiple numerical input' question :
    • 'Question validation equation': unique(self) and count(self)==max(self)
    • 'Sub-question validation equation': (is_empty(NUMBER_SQ001) or is_int(NUMBER_SQ001)) and (is_empty(NUMBER_SQ002) or is_int(NUMBER_SQ002)) ... to have only integer value set
  • With a 'Array (Numbers) ' question :
    • 'Question validation equation': unique(self) and count(self)==max(self)

Demonstration can be found here : Demonstration of alternate ranking solution , lss file : media:Limesurvey_survey_lotofranking.lss