Workarounds: Survey behaviour

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:
 * Workarounds: Manipulating a survey at runtime using Javascript
 * Workarounds: Question design, layout and templating

'''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:

=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=

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.


 * 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.
 * 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

with

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.
 * Add group relevance from the multi select question.

https://www.limesurvey.org/en/forum/can-i-do-this-with-limesurvey/102176-show-x-out-of-y-question-groups#126288
 * You can download lss from below link.

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.

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 ) 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:

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:

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

(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:

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.

\

';

$('div[id ="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 ="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'));

});

}

});

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.

There is a small demonstration here (page 2).

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, as in the demo, 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 ) 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.

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:

LINK.TXT: Only one link per line!

INDEX.PHP:

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.

=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:

http://www.example.../index.php?sid=1234&1234X43X123=Y

With 2.0, if your url is like this /survey/sid/1234, you have to use: http://www.example.../survey/sid/1234/1234X43X123/Y

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:

http://www.example.../index.php?sid=1234&1234X43X123=A2

With 2.0, if your url is like this /survey/sid/1234, you have to use: http://www.example.../survey/sid/1234/1234X43X123/A2

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

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

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

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:

http://www.yourdomain.org/limesurvey/date.php

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:

http://www.example.com/limesurvey180/newtoken.php?sid=98761&token;=12345

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:

=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 :

with lines :

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:

=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':
 * With a 'Multiple numerical input' question :
 * 'Question validation equation':
 * 'Sub-question validation equation':  to have only integer value set
 * With a 'Array (Numbers) ' question :
 * 'Question validation equation':

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