<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.limesurvey.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jcleeland</id>
	<title>LimeSurvey Manual - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.limesurvey.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jcleeland"/>
	<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/Special:Contributions/Jcleeland"/>
	<updated>2026-08-12T11:21:19Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Workarounds:_Manipulating_a_survey_at_runtime_using_Javascript&amp;diff=59826</id>
		<title>Workarounds: Manipulating a survey at runtime using Javascript</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Workarounds:_Manipulating_a_survey_at_runtime_using_Javascript&amp;diff=59826"/>
		<updated>2014-01-16T03:58:39Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: /* Drag and Drop Ranking - Version 1.90 to 1.92 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Often you want to manipulate certain elements of a survey at runtime. The only solution without touching the source code is to use JavaScript or jQuery which is shipped with LimeSurvey. Here are some examples to hide and style elements, validate user input or do calculations at runtime.&lt;br /&gt;
&lt;br /&gt;
Other workarounds can be found at&lt;br /&gt;
* [[Workarounds: Survey behaviour]]&lt;br /&gt;
* [[Workarounds: Question design, layout and templating]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;lt;center&amp;gt;&amp;lt;br /&amp;gt;&#039;&#039;&#039;Please keep in mind that these workarounds are not official LimeSurvey extensions - they are solutions that users have created for themselves.&amp;lt;br /&amp;gt;&amp;lt;span style=&#039;color:#EE0000,#FFFFFF&#039;&amp;gt;Therefore LimeSurvey can&#039;t offer guarantees or support for these solutions.&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;If you have questions, please contact the users that, thankfully, shared their solutions with the community.&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/center&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note:  Version 1.92 implements many new features that make some existing workarounds obsolete.  You can continue to use existing workarounds, but may want to consider switching over to using the new features (since those new features are officially supported, and the workarounds are not).  Please review below for details of which are no longer needed.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Also Note:  Version 1.92&#039;s Expression Manager (EM) may cause some of these work-arounds to fail.  Any custom javascript included as a .js file will be fine.  However, if you in-line your JavaScript code, you must make sure that you have a space after every opening (left) curly brace, and a space before every closing (right) curly brace.  Otherwise, EM will think that the content between the curly braces is something it should parse and understand.  I have fixed all of the work-arounds below that can be fixed (many did not follow those rules).  However, some will continue to break.  If a work-around contains a regular expression which contains curly braces (to indicate a range of repeats of a sub-expression), EM will try to process those curly braces, and thus break your regular expression.  Strategies to continue to support that work-around functionality are discussed below.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;add&#039;&#039; a javascript workaround solution to this Wiki page?=&lt;br /&gt;
&lt;br /&gt;
Well, this is pretty easy. Click the edit icon and create your own headline within the javascript section starting with &amp;quot;&#039;&#039;&#039;!&#039;&#039;&#039;&amp;quot;. Then add a short note about the version you have used when creating your workaround, you can copy/paste this code snippet &amp;lt;nowiki&amp;gt;&#039;&#039;Tested with: (enter LimeSurvey version and maybe browser)&#039;&#039;&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Finally it&#039;s imported to mark all your code with code tags, other wise you might break this page.&lt;br /&gt;
*Start tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
*End tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;use&#039;&#039; Script (eg. JavaScript etc.) in LimeSurvey?=&lt;br /&gt;
&lt;br /&gt;
To use JavaScript within LimeSurvey, the XSS filter must be turned off and the code inserted in the source of a question or a group description.&lt;br /&gt;
*Go to Global settings --&amp;gt; Security and set &amp;quot;Filter HTML for XSS&amp;quot; to &amp;quot;Off&amp;quot;.&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=Adding+A+Question Add a new question]&lt;br /&gt;
* Edit the question and click the &amp;quot;Source&amp;quot; button in the editor toolbar:&lt;br /&gt;
&lt;br /&gt;
   [[File:editor_1.gif]]&lt;br /&gt;
* Enter your script after the question text:&lt;br /&gt;
&lt;br /&gt;
   [[File:editor_2.gif]]&lt;br /&gt;
* Save the question&lt;br /&gt;
&lt;br /&gt;
A simple test to see if JavaScript is enabled is to echo an alert. Use this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good practice to use the jQuery $(document).ready function to prevent the code from executing until the page is fully loaded:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is also good practice to use jslint.com to get a good layout and design (e.q. no cluttering of name space)&lt;br /&gt;
&lt;br /&gt;
=Sum up input values using Javascript=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the sum() function in [[Expression Manager|Expression Manager]].  See this [[Expression Manager HowTos#Calculate assessment values at runtime and store the results in the survey data|HowTo example]].&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Starting in  Version 1.92, you also do no longer need to use SGQA (e.g. 45251X1X5) identifiers. Instead the code &amp;lt;code&amp;gt;{SGQ}&amp;lt;/code&amp;gt; will automatically replaced by the current questions SGQA-codes.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is from a survey that is a invitation to a longer party, when the user clicks to the next page, the calculated results will be shown.&lt;br /&gt;
&lt;br /&gt;
If you wonder what the {INSERTANS:1X6X12} stuff is, look at [http://docs.limesurvey.org/tiki-index.php?page=SGQA+Identifier SGQA identifier] and [[Adding a question#Information from previous answers|Using information from previous answers]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: left&amp;quot;&amp;gt;These are your answers:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;script LANGUAGE=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
partyprice = 3;&lt;br /&gt;
&lt;br /&gt;
beadclothprice = 3;&lt;br /&gt;
&lt;br /&gt;
breakfastprice = 7;&lt;br /&gt;
&lt;br /&gt;
lunchprice = 8;&lt;br /&gt;
&lt;br /&gt;
dinnerprice = 10;&lt;br /&gt;
&lt;br /&gt;
foodtotal = 0;&lt;br /&gt;
&lt;br /&gt;
var isreallytrue = &amp;quot;Yes&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var noanswer = &amp;quot;No answer&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
document.write( &amp;quot;Can you come? = {INSERTANS:45251X1X1}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:45251X1X1}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X3}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X3}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
   partypeople = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   partytotal = partyprice * partypeople;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;It&#039;s {INSERTANS:45251X1X3} persons who will come = &amp;quot; + partytotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X4}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X4}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   beadcloths = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   beadclothtotal = beadclothprice * beadcloths;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;You want to borrow {INSERTANS:45251X1X4} beadcloths = &amp;quot; + beadclothtotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there thursday? = {INSERTANS:45251X1X5}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;On friday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X71}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X71}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   breakfastfriday = parseInt(answer) * breakfastprice;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X72}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X72}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   lunchfriday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X73}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X73}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   dinnerfriday = parseInt(answer)* dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnerfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   foodtotal = breakfastfriday + lunchfriday + dinnerfriday;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there saturday? = {INSERTANS:45251X1X8}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X8}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On saturday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X91}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X91}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       breakfastsaturday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write(&amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X92}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X92}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       lunchsaturday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X93}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X93}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       dinnersaturday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsaturday + lunchsaturday + dinnersaturday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there sunday? = {INSERTANS:45251X1X10}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X10}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On sunday you will have these meals: &amp;lt;br&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X111}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X111}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       breakfastsunday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot;  );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X112}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X112}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       lunchsunday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X113}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X113}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       dinnersunday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersunday + &amp;quot;&amp;amp;euro;&amp;lt;p&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsunday + lunchsunday + dinnersunday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   total = partytotal + beadclothtotal + foodtotal;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&amp;lt;h3&amp;gt;In total it will cost you &amp;quot; + total + &amp;quot;&amp;amp;euro;&amp;lt;/h3&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   Put that sum in this bank account 1234 5678 9012&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/SCRIPT&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Question Validation=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the min/max/equals_num_value attributes (to validate sums), or the em_validation_q function, which lets you refer to other variables when you validate the current question [[Expression Manager|Expression Manager]].  Such validations also work on the current page, and properly handle array_filter and cascading relevance.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround is in case you need to do some validation involving more than one question, it implies a very little JavaScript programming and the use of SGQA Identifiers; this should work on almost any version of LimeSurvey.&lt;br /&gt;
&lt;br /&gt;
Is easy to explain with an example, we need to do a survey of the percentage of males and females and we want to be sure that the sum is 100, to do this follow this steps (the necessary data that is not indicated in these instructions are not important i.e. question codes, etc.):&lt;br /&gt;
#Create a new survey of type &amp;quot;group by group&amp;quot;, set the &amp;quot;Show |&amp;lt;&amp;lt; Prev| button&amp;quot; to yes and note the SID.&lt;br /&gt;
#Add a new group called &amp;quot;Group 1&amp;quot; and note the GID.&lt;br /&gt;
#Add a new question &amp;quot;Percent of males&amp;quot; of type &amp;quot;numeric&amp;quot;, make it mandatory and note the QID (we will refer to this as QID1).&lt;br /&gt;
#Add a new question &amp;quot;Percent of females&amp;quot; of type &amp;quot;numeric&amp;quot;, make it mandatory and note the QID (we will refer to this as QID2).&lt;br /&gt;
#Add a new group called &amp;quot;Group 2&amp;quot;&lt;br /&gt;
#Add a new non mandatory question, here is the trick the question text has to be (be sure to replace the SID, GID, QID1 and QID2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function validation()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   if [[{INSERTANS:SIDXGIDXQID1}+{INSERTANS:SIDXGIDXQID2}) != 100)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     alert(&amp;quot;Your responses don&#039;t sum 100! Check them&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;movelast&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But this will show shortly the question and will jump to the end page, a little weird for the survey taker but works.&lt;br /&gt;
&lt;br /&gt;
This is a proof of concept, and may have some problems, please if you notice something or improve it send me an e-mail to leochaton-limesurvey at yahoo dot com.&lt;br /&gt;
&lt;br /&gt;
This will work for 2 questions that you want to be the same.  Works well for email and confirm email questions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function validation() {&lt;br /&gt;
&lt;br /&gt;
 if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; != &amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
    alert(&amp;quot;Your responses don&#039;t match Check them&amp;quot;); document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
    document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Alternate exit=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using the same idea of the previous post, you can implement an alternate exit of your survey.&lt;br /&gt;
&lt;br /&gt;
This script should be in the first question to be displayed in a next page after the question that should trigger the alternate exit. In this example the question that trigger the alternate exit is a Yes/No question, if the user chooses no, he is redirected to another page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; == &amp;quot;No&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  window.location=&amp;quot;http://www.limesurvey.org&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Custom onload function=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;All browsers&#039;, LimeSurvey 1.70 and up&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
&lt;br /&gt;
This simple workaround describes how to &#039;&#039;&#039;add a custom Javascript code&#039;&#039;&#039; that is triggered right after the page is loaded. It may have numerous applications, especially when you deal with a custom JS/HTML code. It may be used to hide form elements (&amp;lt;input&amp;gt;  tags), make them read-only, display alert messages, etc.&lt;br /&gt;
&lt;br /&gt;
To run any Javascript code right after page load use the Query ready() function. It will be executed when the page is being loaded. For example when you add the following code to one of your question definitions...:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
       alert(&#039;onload alert!&#039;);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...it will display a pop-up message immediately after the page has been loaded.&lt;br /&gt;
&lt;br /&gt;
Some of the applications of this trick I&#039;ve explored are:&lt;br /&gt;
&lt;br /&gt;
a) Hiding the form elements by calling in your Custom_On_Load:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: As of svn build 9755, you can now dynamically reference the questions input fields by using the {SGQ} keyword. You can rewrite the previous example like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer{SGQ}&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
this makes it a little easier when exporting surveys, so you don&#039;t have to worry about manually entering each questions SurveyGroupQuestion ID.&lt;br /&gt;
&lt;br /&gt;
b) Making the elements read only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).readOnly=true;&amp;lt;/syntaxhighlight&amp;gt; where the &amp;quot;answer73166X16X54&amp;quot; structure has been described in one of other workarounds above.&lt;br /&gt;
&lt;br /&gt;
c) For Hiding by a lot of elements by calling in your Customer_On_Load&lt;br /&gt;
&lt;br /&gt;
jQuery searchs in html document for input-fields with radio type, if his answer text empty then do the display css set to none.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
           function() {&lt;br /&gt;
&lt;br /&gt;
             jQuery(&#039;input:radio&#039;).each(&lt;br /&gt;
&lt;br /&gt;
               function() {&lt;br /&gt;
&lt;br /&gt;
                 var s = jQuery(this);&lt;br /&gt;
&lt;br /&gt;
                 var c = s.parent().children(&#039;.answertext&#039;);&lt;br /&gt;
&lt;br /&gt;
                 for(var i=0; i &amp;lt; c.length; i++) {&lt;br /&gt;
&lt;br /&gt;
                   var a = jQuery(c[i]]);&lt;br /&gt;
&lt;br /&gt;
                   if(this.id &amp;lt;/u&amp;gt; a.attr(&#039;for&#039;) &amp;amp;&amp;amp; a.text() == &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
                     s.css({ &#039;display&#039; : &#039;none&#039; });&lt;br /&gt;
&lt;br /&gt;
                     a.css({ &#039;display&#039; : &#039;none&#039; });&lt;br /&gt;
&lt;br /&gt;
                     break;&lt;br /&gt;
&lt;br /&gt;
                   }&lt;br /&gt;
&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
             )&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
         );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advanced usage==&lt;br /&gt;
&lt;br /&gt;
If you want to place global Javascript code using the above jQuery(document).ready function then the best place to do this is the template javascript file template.js. You can edit this file using the template editor. Please be aware that placing it in the template javascript file will make the function available to all surveys using that template. If needed just create a new template copy for your survey.&lt;br /&gt;
&lt;br /&gt;
Alternatively you can place the jQuery(document).ready function in the group description to make a Javascript function only available to a certain question group.&lt;br /&gt;
&lt;br /&gt;
==Language-specific Javascript code==&lt;br /&gt;
&lt;br /&gt;
There is an easy way to find out the current language and execute according Javascript using jQuery: The &amp;lt;html&amp;gt; tag of any survey pages contains an &#039;lang&#039; attribute which holds the current language code. You can read that language code by using the followin code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
       languagecode=$(&#039;html&#039;).attr(&#039;lang&#039;);&lt;br /&gt;
&lt;br /&gt;
       alert(&#039;This is the current language code: &#039;+languagecode);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an English survey the above code would show a messagebox with &amp;quot;This is the current language code: en&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Custom onload function in multi-language survey=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use custom onload functions, as above, in multi-language surveys you must define the functions in the question source for &#039;&#039;&#039;all&#039;&#039;&#039; languages.&lt;br /&gt;
&lt;br /&gt;
While this initially seems to be a bit tedious, it actually can be useful - you can alter your onload functions depending on the language in use. For example, you can dynamically display alerts or element contents in the current language.&lt;br /&gt;
&lt;br /&gt;
=Skipping the welcome page=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85 (second code snippet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: As of version 1.91, there is a survey option letting you skip the welcome page, so this workaround is not needed.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 1:&#039;&#039;&#039; Include this Javascript in your welcome template, in the file welcome.pstpl for all welcome page, or in the source of the welcome text for one survey:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function($) {&lt;br /&gt;
&lt;br /&gt;
document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
document.limesurvey.submit(); });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will reproduce the onclick event of the submit button and submit the form.&lt;br /&gt;
&lt;br /&gt;
Drawback of course is that users will see the page flashing up.&lt;br /&gt;
&lt;br /&gt;
Therefore, you may want to announce &amp;quot;... loading survey ...&amp;quot; as a description of your welcome page (in the admin interface when creating the survey), to pretend loading something big.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 2:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function custom_on_load(){&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
window.setTimeout( &#039;custom_on_load()&#039;,1);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Filter answers of a question with the answer of another=&lt;br /&gt;
&lt;br /&gt;
===Method 1===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.70 - 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the the array_filter attribute, or relevance equations in general.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to filter the answer of a question with another answer, you can use this workaround.&lt;br /&gt;
&lt;br /&gt;
First, use answer code like that: XX for the first question, and XXYYY for the second one.&lt;br /&gt;
&lt;br /&gt;
Answer of the second question filter if the 2 first letters are the answer of the first question.&lt;br /&gt;
&lt;br /&gt;
We use 1000X1X1 and 1000X1X2 for the example, question had to be on separate page (question by question for example).The second question had to be a dropdown list (we can do similar workaround, but droplis is the best). You can do this using JQuery.  It leaves the answer in the select box, but disables it.  You could also replace &amp;quot;disable&amp;quot; with &amp;quot;remove&amp;quot; to get rid of it altogether.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var previousQuestionAnswer = &amp;quot;{INSERTANS:1000X1X1}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var currentQuestionID = &amp;quot;#answer1000X1X1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // See if the answer for the previous question matches an answer in the current question&lt;br /&gt;
&lt;br /&gt;
   // (other than &#039;No Answer&#039;)&lt;br /&gt;
&lt;br /&gt;
   // If so, disable it.&lt;br /&gt;
&lt;br /&gt;
   if (previousQuestionAnswer!=&#039;No Answer&#039;) {&lt;br /&gt;
&lt;br /&gt;
       $(currentQuestionID).children().each(function(index, Element)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           if ($(this).attr(&#039;text&#039;) == previousQuestionAnswer)&lt;br /&gt;
&lt;br /&gt;
               { $(this).attr(&#039;disabled&#039;, true); }&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       );}&lt;br /&gt;
&lt;br /&gt;
}); // End of JQuery ready function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Method 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with 1.92 + Firefox 9.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you have a country, state, and city set of questions (or similar), you could code answer options as:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1 Country&#039;&#039;&#039; &#039;&#039;Single choice list (ratio, dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
X country#&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2 State&#039;&#039;&#039; &#039;&#039;Single choice list (dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
XY state#&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3 City&#039;&#039;&#039; &#039;&#039;Single choice list (dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
XYZZ city#&lt;br /&gt;
&lt;br /&gt;
Now you must put the following Javascript code in the source of question 2 (State):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Get the countryCode (first character of the country)&lt;br /&gt;
&lt;br /&gt;
       var countryCode = &#039;{INSERTANS:1000X1X1}&#039;.substr(0, 1).toUpperCase();&lt;br /&gt;
&lt;br /&gt;
       // Loop through all dropdown options and remove those with codes not starting with the countryCode&lt;br /&gt;
&lt;br /&gt;
       $(&#039;select[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;answer&amp;quot;] option&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
           if($(this).attr(&#039;value&#039;)  &amp;amp;&amp;amp; $(this).attr(&#039;value&#039;).substr(0, 1).toUpperCase() != countryCode) {&lt;br /&gt;
&lt;br /&gt;
               $(this).remove();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the following code in the source of question 3 (City):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Get the stateCode (two first characters of the state)&lt;br /&gt;
&lt;br /&gt;
       var stateCode = &#039;{INSERTANS:1000X1X2}&#039;.substr(0, 2).toUpperCase();&lt;br /&gt;
&lt;br /&gt;
       // Loop through all dropdown options and remove those with codes not starting with the stateCode&lt;br /&gt;
&lt;br /&gt;
       $(&#039;select[id&amp;lt;/div&amp;gt;=&amp;quot;answer&amp;quot;] option&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
           if($(this).attr(&#039;value&#039;)  &amp;amp;&amp;amp; $(this).attr(&#039;value&#039;).substr(0, 2).toUpperCase() != stateCode) {&lt;br /&gt;
&lt;br /&gt;
               $(this).remove();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each question must be in different pages of survey to work, i.e. in a question by question survey, or in diferent groups in a group by group survey.&lt;br /&gt;
&lt;br /&gt;
Note that if you choose a two characters answer option code in the State question, i.e. a XYY answer option code, you must change the &#039;&#039;substr(0, 2)&#039;&#039; part of code in question 3 to &#039;&#039;substr(0, 3)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Filter answers of a multiple numeric type question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the the array_filter attribute, or relevance equations in general.  In 1.92, array_filter works with all questions that have sub-questions (e.g. also works for multiple numeric and multiple short text).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to filter a question of type &amp;quot;multiple numeric&amp;quot;, you have to modify the workaround.&lt;br /&gt;
&lt;br /&gt;
Note that this workaround assumes that the code for each of the subquestions are a numeric sequence 1,2,3...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
   // Match elements with labels using htmlFor and a loop&lt;br /&gt;
&lt;br /&gt;
   var labels = document.getElementsByTagName(&#039;LABEL&#039;);&lt;br /&gt;
&lt;br /&gt;
   for (var i = 0; i &amp;lt; labels.length; i++) {&lt;br /&gt;
&lt;br /&gt;
       if (labels[i].htmlFor != &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
            var elem = document.getElementById(labels[i].htmlFor);&lt;br /&gt;
&lt;br /&gt;
            if (elem)&lt;br /&gt;
&lt;br /&gt;
               elem.label = labels[i];&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   var answerFilter=&amp;quot;{INSERTANS:96553X63X759}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   for (i=0; i&amp;lt;30; i++){&lt;br /&gt;
&lt;br /&gt;
     var iLabel = document.getElementById(&#039;answer96553X63X760&#039;+(i+1]].label.innerHTML;&lt;br /&gt;
&lt;br /&gt;
     if (answerFilter.search(iLabel) == -1){&lt;br /&gt;
&lt;br /&gt;
       // Hide element&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question760&#039;).find(&#039;li&#039;).eq(i).hide();&lt;br /&gt;
&lt;br /&gt;
       // Set value of hidden elements to zero&lt;br /&gt;
&lt;br /&gt;
       document.getElementById(&#039;answer96553X63X760&#039;+(i+1)).value = 0;&lt;br /&gt;
&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 });&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use an answer to prefill another question (default value)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;And tested with: 1.91+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the enhanced defaults feature, which lets you pre-fill most question types with default values.  In 1.91, you could set defaults for list and multiple choice questions.  In 1.92, you can set defaults for any text-entry question too.  Moreover, the defaults can be [[Expression Manager|Expression Manager]] compatible equations or tailored text.  Finally, with 1.92, defaults are properly managed even when set on the same page.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround gives you the ablility to use an answer to fill the default value for another question. It&#039;s explained for free text question type but can be adapted for another question type.&lt;br /&gt;
&lt;br /&gt;
We use SGQA identifier. For example, we use SGQA 1000X10X20 and 1000X10X21 to prefill 1000X11X30 and 1000X11X31. For the script to work, the question has to be on a different page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X11X30&#039;).val(&#039;{INSERTANS:1000X10X20}&#039;);&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X11X31&#039;).val(&#039;{INSERTANS:1000X10X21}&#039;);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want use two times the value of an integer input, you can also use this to prefill a question that you hide via CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X2X2&#039;).val(parseInt(&#039;{INSERTANS:1000X1X1}&#039;)*2);&lt;br /&gt;
&lt;br /&gt;
 $(&amp;quot;#question2&amp;quot;).hide();&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use {INSERTANS:1000X2X2} for giving you twice the value of the user input from question 1.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Sum=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do with [[Expression Manager|Expression Manager]] using the sum() function.  Not only will sums be dynamic, but they wille exclude irrelevant values, so you can array_filter a multiple numeric question and get the sum of just the answers that are visible.  This [[Expression Manager HowTos#Calculate assessment values at runtime and store the results in the survey data|HowTo example]] demonstrates the dynamic sum feature.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Also note, as of version 1.92, the following workaround will fail, since it includes a a regular expression containing curly braces.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script is used with a &amp;quot;Multiple Options&amp;quot; type question calculate a total price based on how which checkboxes are selected. The prices are listed as part of the answer. The answers are set up like this: &amp;quot;USB Mouse ($20)&amp;quot;. The script uses the number between the &amp;quot;($&amp;quot; and the &amp;quot;)&amp;quot; as the price for that item. You can adapt the script to if you need to change the currency or need to sum something other than money.&lt;br /&gt;
&lt;br /&gt;
This script works when used in a question-by-question format.  It does not work when there are more than one question on a page. I think it can be adapted to work, but I haven&#039;t done the coding yet.&lt;br /&gt;
&lt;br /&gt;
Put the following code into body of your question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script language=Javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// General definitions&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match the labels containing information about an answer&lt;br /&gt;
&lt;br /&gt;
// In LimeSurvey, these labels start with &amp;quot;answer...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
var answerRegex = /^answer/;&lt;br /&gt;
&lt;br /&gt;
// Find all answer checkboxes in the document and set their&lt;br /&gt;
&lt;br /&gt;
// onchange events to updatePrice&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   // Find all input elements&lt;br /&gt;
&lt;br /&gt;
   var inputList=document.getElementsByTagName(&amp;quot;input&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   // Loop through each, looking for checkboxes&lt;br /&gt;
&lt;br /&gt;
   var i;&lt;br /&gt;
&lt;br /&gt;
   for( i=0; i&amp;lt; inputList.length;i++ )&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // If input item does not have an ID, skip&lt;br /&gt;
&lt;br /&gt;
       if (! (inputList[i].id)) { continue; }&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if ID doesn&#039;t start with &amp;quot;answer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
       if (!answerRegex.test(inputList[i].id)) { continue; }&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if not a checkbox&lt;br /&gt;
&lt;br /&gt;
       if (inputList[i].type.toUpperCase()!=&#039;CHECKBOX&#039;)  { continue; }&lt;br /&gt;
&lt;br /&gt;
       // This is an answer checkbox!&lt;br /&gt;
&lt;br /&gt;
       // Setup onchange event&lt;br /&gt;
&lt;br /&gt;
       inputList[i].onclick = updatePrice;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Load initial sum&lt;br /&gt;
&lt;br /&gt;
   updatePrice();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function updatePrice()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
var labels=document.getElementsByTagName(&amp;quot;LABEL&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match a price inside parenthesis&lt;br /&gt;
&lt;br /&gt;
// For example: ($29) or ($29.54).&lt;br /&gt;
&lt;br /&gt;
// Set up&lt;br /&gt;
&lt;br /&gt;
priceRegex = /\(\$(\d*\.{0,1}\d+)\)/;&lt;br /&gt;
&lt;br /&gt;
// Loop through all the labels, looking for labels corresponding to&lt;br /&gt;
&lt;br /&gt;
// answers that have a price in them.&lt;br /&gt;
&lt;br /&gt;
var i;&lt;br /&gt;
&lt;br /&gt;
var total = 0;&lt;br /&gt;
&lt;br /&gt;
for( i=0; i&amp;lt;labels.length;i++ )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   var myArray;    // Define array used for regex matching&lt;br /&gt;
&lt;br /&gt;
   var inputID;    // Define field element&lt;br /&gt;
&lt;br /&gt;
   // Get the ID of the field corresponding to the label using the&lt;br /&gt;
&lt;br /&gt;
   // &amp;quot;htmlFor&amp;quot; attribute&lt;br /&gt;
&lt;br /&gt;
   // (FYI, there are some labels that will have to be screened out&lt;br /&gt;
&lt;br /&gt;
   // because they don&#039;t correspond to an answer)&lt;br /&gt;
&lt;br /&gt;
   // Does the label start with &amp;quot;answer&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
   // If not: exit.&lt;br /&gt;
&lt;br /&gt;
   if (!answerRegex.test(labels[i].htmlFor)) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // First make sure this element exists&lt;br /&gt;
&lt;br /&gt;
   // If it doesn&#039;t, go to the next element&lt;br /&gt;
&lt;br /&gt;
   // If it does, it will be defined in inputID&lt;br /&gt;
&lt;br /&gt;
   if (! (inputID = document.getElementById(labels[i].htmlFor)) ) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // See if the corresponding answer is a checkbox that is checked.&lt;br /&gt;
&lt;br /&gt;
   // If not, go to next label&lt;br /&gt;
&lt;br /&gt;
   if (inputID.type.toUpperCase()!=&#039;CHECKBOX&#039;)  { continue; }&lt;br /&gt;
&lt;br /&gt;
   if (!inputID.checked) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // This is label for an answer.&lt;br /&gt;
&lt;br /&gt;
   // The innerHTML will give us the text of the label&lt;br /&gt;
&lt;br /&gt;
   // The price information will be in the form ($XX.XX)&lt;br /&gt;
&lt;br /&gt;
   // which in contained in the label text.&lt;br /&gt;
&lt;br /&gt;
   // Find a match for a decimal number inside the pattern &amp;quot;($&amp;quot; and &amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   if [[myArray = priceRegex.exec(labels[i].innerHTML]] != null)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // Keep a running tally&lt;br /&gt;
&lt;br /&gt;
       total += parseFloat(myArray[1]);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // Update total price on form&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&amp;quot;totalPrice&amp;quot;).value = &amp;quot;$&amp;quot; + formatCurrency(total);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function formatCurrency(num) {&lt;br /&gt;
&lt;br /&gt;
  num = isNaN(num) || num &amp;lt;u&amp;gt; &#039;&#039; || num &amp;lt;/u&amp;gt; null ? 0.00 : num;&lt;br /&gt;
&lt;br /&gt;
  return parseFloat(num).toFixed(2);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put the following code in the help section (or wherever you want the sum to appear):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Total Cost for selected accessories: &amp;lt;input type=&amp;quot;readonly&amp;quot; value=&amp;quot;&amp;quot; id=&amp;quot;totalPrice&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Focus on the first Input field=&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: LimeSurvey 1.80 / IE6/7, Firefox 3, Safari, Opera, chrome&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.91, there is a built-in JavaScript function called  focusFirst() to focus on the first visible element.  It uses jQuery, so is more robust than this example.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again an onload Function is needed for this tasks. I have done it the DOM way with compatibility to IE6/7.&lt;br /&gt;
&lt;br /&gt;
Put the following code into the startpage.pstpl of your template, right before the &amp;lt;/head&amp;gt; closing tag:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   function focusFirst(Event)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       var i=0;&lt;br /&gt;
&lt;br /&gt;
       while(document.forms[0].elements[i].type == &amp;quot;hidden&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           i++;&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       document.forms[0].elements[i].focus();&lt;br /&gt;
&lt;br /&gt;
       return;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(ie)&lt;br /&gt;
&lt;br /&gt;
   { window.attachEvent(&amp;quot;onload&amp;quot;, focusFirst); }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   { document.addEventListener(&amp;quot;load&amp;quot;, focusFirst, true); }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; I am using this with version 1.80. As changes happened to the templates in the last release, you might need to add the following before the code, if your template is older than 1.80 stable and does not include this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   var ie = false;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will need this for the var ie to be set. Without this var, the function will not work with ie.&lt;br /&gt;
&lt;br /&gt;
=Answer questions by keypress=&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: IE7, Firefox 3&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
This workaround allow to answer the question on key 0-9 (0 is for the 10 answer).&lt;br /&gt;
&lt;br /&gt;
Follow issues are supported at the moment:&lt;br /&gt;
*Yes-No Questions&lt;br /&gt;
*List Questions (radio)&lt;br /&gt;
*other radio questions&lt;br /&gt;
&lt;br /&gt;
In lists the answer limit is ten.&lt;br /&gt;
&lt;br /&gt;
You supply the template &amp;quot;endpage&amp;quot; of your template with the following script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   jQuery(document).bind(&#039;keypress&#039;, function(e){&lt;br /&gt;
&lt;br /&gt;
       if (48 &amp;lt;= e.which &amp;amp;&amp;amp; e.which &amp;lt;= 57) {&lt;br /&gt;
&lt;br /&gt;
           jQuery(&#039;input:radio&#039;).each(function() {&lt;br /&gt;
&lt;br /&gt;
               var v = jQuery(this).val();&lt;br /&gt;
&lt;br /&gt;
               var c = (e.which &amp;lt;u&amp;gt; 48) ? 10 : e.which - 48;&lt;br /&gt;
&lt;br /&gt;
               if(v &amp;lt;/u&amp;gt; &#039;Y&#039; || v &amp;lt;u&amp;gt; &#039;N&#039;) {&lt;br /&gt;
&lt;br /&gt;
                   v = (v &amp;lt;/u&amp;gt; &#039;Y&#039;) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               if(v == c) {&lt;br /&gt;
&lt;br /&gt;
                   jQuery(this).click();&lt;br /&gt;
&lt;br /&gt;
                   jQuery(&#039;#limesurvey input:submit&#039;).click();&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   })&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Math notation in LimeSurvey=&lt;br /&gt;
#download the js file from [http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html AsciiMath script]&lt;br /&gt;
#copy it in the /scripts/ folder in your installation&lt;br /&gt;
#modify the startpage.psptl of the template you want to use adding the reference to the script (if you use an older version make sure that you copy the template folder first!) for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;ASCIIMathML.js&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the notation where you need it!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you use internet explorer or safari you will need to download the plugin as well, but firefox does the lot for you.&lt;br /&gt;
&lt;br /&gt;
Finally, if you are confident with the limesurvey structure you could add the editor which support math notation and change the reference to the editor you want to use in the configuration file. here is the [http://www.imathas.com/editordemo/demo.html link for a TinyMCE with math support].&lt;br /&gt;
&lt;br /&gt;
=Reverse array_filter (for pre-1.90)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Version 1.91 natively supports this functionality via the array_filter_exclude advanced quation option.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used to filter the answers of an array question to be displayed based on the answers of a multi option question that were &#039;&#039;&#039;NOT&#039;&#039;&#039; selected. A possible application would be to have a multi-option question asking which products were purchased, followed by 2 array questions - one asking to rate the purchased products and another asking why the remaining products were not purchased. Another would be to ask about sessions attended at a conference as in [http://www.limesurvey.org/en/forum/5-can-i-do-this-with-limesurvey/27970-reverse-of-arrayfilter.html this forum thread] and pictured below. There is a live [http://www.partnersinc.biz/surveys//index.php?sid=43358&amp;amp;newtest=Y&amp;amp;lang=en demo here]&lt;br /&gt;
&lt;br /&gt;
[[File:sessions_645x344.gif]]&lt;br /&gt;
&lt;br /&gt;
We&#039;ll use the above example to explain the process as follows:&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsAttended&#039;&#039; multi-options question&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsNotAttended&#039;&#039; multi-options question with identical answers as &#039;&#039;SessionsAttended&#039;&#039; and hide it with styles or conditions&lt;br /&gt;
#In group 2 - Create a &#039;&#039;RateSessionsAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsAttended&#039;&#039;&lt;br /&gt;
#In group 2 - Create a &#039;&#039;ReasonNotAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsNotAttended&#039;&#039;&lt;br /&gt;
#In group 1 - Place JavaScript/jQeury listeners on each of the checkboxes in &#039;&#039;SessionsAttended&#039;&#039; that would toggle the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
&lt;br /&gt;
The JavaScript/jQuery code used would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       // The toggle function&lt;br /&gt;
&lt;br /&gt;
   function toggle(q1, q2) {&lt;br /&gt;
&lt;br /&gt;
       if ($(q1).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       else {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Initialize the SessionNotAttended checkboxes to &amp;quot;checked&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   // The jQuery listeners on the SessionAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   // that toggle the SessionNotAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X331&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X332&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X333&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X334&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some notes about the code:&lt;br /&gt;
*The code is in an onload function defined in the first question of group 1 - see [[Workarounds#Custom_onload_function|here]]&lt;br /&gt;
*Both &#039;&#039;SessionsAttended&#039;&#039; and &#039;&#039;SessionsNotAttended&#039;&#039; must be in the same group for the toggling to work&lt;br /&gt;
*This case only uses 4 checkboxes but could be expanded as required&lt;br /&gt;
*In this case the survey ID is 11111, the group ID is 22, &#039;&#039;SessionsAttended&#039;&#039; ID is 33 and SessionsNotAttended ID is 44 - these would need to be modified for your survey&lt;br /&gt;
*The toggle function looks for the state of a checkbox in &#039;&#039;SessionsAttended&#039;&#039; and sets the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
*The &amp;quot;Initialize&amp;quot; section sets the state of &#039;&#039;SessionsNotAttended&#039;&#039; checkboxes whenever we navigate to the group&lt;br /&gt;
*The &amp;quot;Listener&amp;quot; section uses jQuery listeners to detect any change in the &#039;&#039;SessionsAttended&#039;&#039; checkboxes and then toggle the corresponding &#039;&#039;SessionsNotAttended&#039;&#039; checkbox&lt;br /&gt;
&lt;br /&gt;
Some general notes about the questions:&lt;br /&gt;
*CSS can be used to hide &#039;&#039;SessionsNotAttended&#039;&#039; (div#question44 { display: none; }) if you don&#039;t want to use conditions (because maybe you&#039;ve got [[Optional settings#Survey Behavior|$deletenonvalues set to 1]])&lt;br /&gt;
*&#039;&#039;RateSessionsAttended&#039;&#039; and &#039;&#039;ReasonNotAttended&#039;&#039; are another group to avoid things popping in and out of existence as &#039;&#039;SessionsAttended&#039;&#039; is answered&lt;br /&gt;
*[[Setting conditions|Conditions]] are used to ensure that &#039;&#039;RateSessionsAttended&#039;&#039; only appears if some sessions are selected and &#039;&#039;ReasonNotAttended&#039;&#039; only appears if no sessions are selected&lt;br /&gt;
&lt;br /&gt;
=Filter Ranking Question With Multiple-Options (pre 1.92)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90, IE 7/8, FireFox 3/4, Safari 5.0, Chrome 10.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, most of this is easier to do using the the array_filter attribute, or relevance equations in general.  They all work on the same page, and fully support cascading relevance.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround applies a filter to a ranking question based on the checked boxes of a previous multiple-options question. There are two methods - one for filter and ranking questions being on the same page and a slightly different one for the filter question being on a page before the ranking question.&lt;br /&gt;
&lt;br /&gt;
There is a [http://www.partnersinc.biz/surveys//index.php?sid=96314&amp;amp;newtest=Y&amp;amp;lang=en demo of both methods here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH METHODS:&#039;&#039;&#039;&lt;br /&gt;
*[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
*Place the following script in your template.js file. This function will be accessed by either method.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// A function to filter choices in a ranking question&lt;br /&gt;
function rankFilter(q1ID, q2ID, prevPage) {&lt;br /&gt;
&lt;br /&gt;
	// If filter question is on a previous page, hide Q1 and check all &amp;quot;visible&amp;quot; boxes&lt;br /&gt;
	if(prevPage == 1) {&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; li[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;javatbd&amp;quot;]:visible input.checkbox&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039;&#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	handleChecked(q1ID, q2ID);&lt;br /&gt;
	$(&#039;#question&#039;+q1ID+&#039; input.checkbox&#039;).click(function() {&lt;br /&gt;
		handleChecked(q1ID, q2ID);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	function handleChecked(q1ID, q2ID) {&lt;br /&gt;
	&lt;br /&gt;
		// Find the survey and group IDs&lt;br /&gt;
		if($( &#039;input#fieldnames&#039; ).length != 0) {&lt;br /&gt;
			var fieldNames = $( &#039;input#fieldnames&#039; ).attr(&#039;value&#039;);&lt;br /&gt;
			var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
			var sID = tmp[0];&lt;br /&gt;
			var gID = tmp[1];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Loop through all Q1 options&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.checkbox&#039;).each(function(i) {&lt;br /&gt;
		&lt;br /&gt;
			// Find the answer code and value&lt;br /&gt;
			var tmp2 = $(this).attr(&#039;id&#039;).split(&#039;X&#039;+gID+&#039;X&#039;+q1ID+&#039;&#039;);&lt;br /&gt;
			var ansCode = tmp2[1];&lt;br /&gt;
			var ansTxt = $(this).next(&#039;label&#039;).text();&lt;br /&gt;
			&lt;br /&gt;
			// If option is checked and not in rank choices or output, add it to the rank choices&lt;br /&gt;
			if($(this).attr(&#039;checked&#039;) == true&lt;br /&gt;
						  &amp;amp;&amp;amp; $(&#039;#question&#039;+q2ID+&#039; select.select option[value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).length == 0&lt;br /&gt;
						  &amp;amp;&amp;amp; $(&#039;#question&#039;+q2ID+&#039; .output input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;][value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).length == 0) {&lt;br /&gt;
				$(&#039;&amp;lt;option value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;&amp;gt;&#039;+ansTxt+&#039;&amp;lt;/option&amp;gt;&#039;).appendTo(&#039;#question&#039;+q2ID+&#039; select.select&#039;);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// If option is unchecked...&lt;br /&gt;
			else if($(this).attr(&#039;checked&#039;) == false) {&lt;br /&gt;
				// Remove it from the rank choices&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select option[value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).remove();&lt;br /&gt;
				// Remove it from the rank output and reset hidden values&lt;br /&gt;
$(&#039;#question&#039;+q2ID+&#039; .output input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;][value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).attr(&#039;value&#039;, &#039;&#039;).siblings(&#039;input.text&#039;).val(&#039;&#039;).siblings(&#039;img&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Clean up empty inputs in the rank output table&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr&#039;).each(function(i) {&lt;br /&gt;
			var nextRow = $(this).next(&#039;tr&#039;);&lt;br /&gt;
			if($(&#039;input.text&#039;, this).val() == &#039;&#039; &amp;amp;&amp;amp; $(&#039;input.text&#039;, nextRow).val() != &#039;&#039;) {&lt;br /&gt;
				$(&#039;input.text&#039;, this).val($(&#039;input.text&#039;, nextRow).val());&lt;br /&gt;
				$(&#039;input.text&#039;, nextRow).val(&#039;&#039;);&lt;br /&gt;
				$(&#039;input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, this).attr(&#039;value&#039;, $(&#039;input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, nextRow).attr(&#039;value&#039;));&lt;br /&gt;
				$(&#039;input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, nextRow).attr(&#039;value&#039;, &#039;&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Show the scissors for the last populated rank output row&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table img[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;cut_&amp;quot;]&#039;).hide();&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table input.text[value!=&amp;quot;&amp;quot;]:last&#039;).siblings(&#039;img[id&amp;lt;/div&amp;gt;=&amp;quot;cut_&amp;quot;]&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Hide extra rank output rows&lt;br /&gt;
		var optNum = $(&#039;#question&#039;+q1ID+&#039; input.checkbox:checked&#039;).length;&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr&#039;).hide();&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr:lt(&#039;+(optNum+1)+&#039;)&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Hide and clear the ranking question if there are less than 2 checked options in Q1&lt;br /&gt;
		if(optNum &amp;lt; 2) {&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039;&#039;).hide();&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039; input.text&#039;).val(&#039;&#039;);&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039; input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;).attr(&#039;value&#039;, &#039;&#039;);&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039;&#039;).show();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// A workaround for the built in max-answers function&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; td.output tr:visible&#039;).each(function(i) {&lt;br /&gt;
			if($(&#039;input.text&#039;, this).val() == &#039;&#039;) {&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// A listener to work around the built in max-answers function&lt;br /&gt;
	$(&#039;#question&#039;+q2ID+&#039; td.rank&#039;).click(function (event) {&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; td.item input.text&#039;).each(function(i) {&lt;br /&gt;
			if ($(this).val() == &#039;&#039;) {&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH FILTER AND RANKING QUESTIONS ON SAME PAGE:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question and a ranking question on the same page (in the same group).&lt;br /&gt;
*Both questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Place the following script in the source of one of the questions.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;RR&amp;quot; with the ID of the ranking question.&lt;br /&gt;
*The function will hide the ranking question unless at least two options are selected in the multiple options question, in which case, it will only show the options selected.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		rankFilter(MM, RR);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR FILTER AND RANKING QUESTIONS ON SEPARATE PAGES:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question on page 1.&lt;br /&gt;
*Create a multiple options question and a ranking question on page 2.&lt;br /&gt;
*All three questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Set the multiple options on page 2 to be filtered by the multiple options on page 1.&lt;br /&gt;
*Place the following script in the source of one of the questions on page 2.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;RR&amp;quot; with the ID of the ranking question. Do not modify the &amp;quot;1&amp;quot;.&lt;br /&gt;
*The function will hide the multiple options question. If at least 2 options were selected in the multiple options on page 1, the corresponding options will be checked in the hidden multiple options question which will then be used to control the display of the ranking question.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		rankFilter(MM, RR, 1);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Filter &amp;quot;Array by Column&amp;quot; Question With &amp;quot;Multiple-Options&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, FireFox 3/4, Safari 5.0, Chrome 10.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround applies a filter to an &amp;quot;Array by Column&amp;quot; question based on the checked boxes of a previous multiple-options question. There are two methods - one for filter and array questions being on the same page and a slightly different one for the filter question being on a page before the array question.&lt;br /&gt;
&lt;br /&gt;
There is a [http://www.partnersinc.biz/surveys//index.php?sid=74213&amp;amp;newtest=Y&amp;amp;lang=en demo of both methods here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH METHODS:&#039;&#039;&#039;&lt;br /&gt;
*[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
*Place the following scripts in your template.js file. These functions will be accessed by either method.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
	function filterArrByCol(qMultiOpt, qArray, prevPage) {&lt;br /&gt;
	&lt;br /&gt;
		// If filter question is on a previous page, hide Q1 and check all &amp;quot;visible&amp;quot; boxes&lt;br /&gt;
		if(prevPage == 1) {&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039; li[id&amp;lt;/div&amp;gt;=&amp;quot;javatbd&amp;quot;]:visible input.checkbox&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039;&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Assign classes to the answer cells&lt;br /&gt;
		$(&#039;#question&#039;+qArray+&#039; table.question tbody td&#039;).each(function(i){&lt;br /&gt;
			var classArr = $(this).attr(&#039;class&#039;).split(&#039;answer_cell_00&#039;);&lt;br /&gt;
			var ansCode = classArr[1];&lt;br /&gt;
			$(this).addClass(&#039;ans-&#039;+ansCode+&#039; filtered&#039;);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Assign classes to the answer label cells&lt;br /&gt;
		$(&#039;#question&#039;+qArray+&#039; table.question tbody tr:eq(0) td&#039;).each(function(i){&lt;br /&gt;
			var classArr2 = $(this).attr(&#039;class&#039;).split(&#039; ans-&#039;);&lt;br /&gt;
			var ansCode2 = classArr2[1];&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; table.question thead tr:eq(0) th:eq(&#039;+i+&#039;)&#039;).addClass(&#039;ans-&#039;+ansCode2+&#039;&#039;);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Fire the filter function on page load&lt;br /&gt;
		filterArr(qMultiOpt, qArray);&lt;br /&gt;
&lt;br /&gt;
		// Listener on multi-opt checkboxes to fire the filter function&lt;br /&gt;
		$(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox&#039;).click(function(){&lt;br /&gt;
			filterArr(qMultiOpt, qArray);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// On submit, clear all hidden radios of array&lt;br /&gt;
		$(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; td.filtered:hidden&#039;).each(function(i){&lt;br /&gt;
				$(&#039;input.radio&#039;, this).attr(&#039;checked&#039;, false);&lt;br /&gt;
			});&lt;br /&gt;
			return true;&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function filterArr(qMultiOpt, qArray) {&lt;br /&gt;
	&lt;br /&gt;
		if($(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox:checked&#039;).length &amp;lt; 1) {&lt;br /&gt;
			// Hide the array if no multi-opt options are checked&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039;&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039;&#039;).show();&lt;br /&gt;
			&lt;br /&gt;
			// Hide all columns of array&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; table.question tbody td, #question&#039;+qArray+&#039; table.question thead th&#039;).hide();&lt;br /&gt;
			&lt;br /&gt;
			// Loop through multi-opt checkboxes and, if checked, show corresponding column of array&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox&#039;).each(function(i){&lt;br /&gt;
				if($(this).attr(&#039;checked&#039;) == true) {&lt;br /&gt;
					var classArr3 = $(this).attr(&#039;id&#039;).split(&#039;X&#039;+qMultiOpt);&lt;br /&gt;
					var ansCode3 = classArr3[1];&lt;br /&gt;
					$(&#039;#question&#039;+qArray+&#039; .ans-&#039;+ansCode3+&#039;&#039;).show();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH FILTER AND ARRAY QUESTIONS ON SAME PAGE:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question and an array-by-column question on the same page (in the same group).&lt;br /&gt;
*Both questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Place the following script in the source of one of the questions.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;AA&amp;quot; with the ID of the ranking question.&lt;br /&gt;
*The function will hide the array question unless at least one option is selected in the multiple-options question, in which case, it will only show the corresponding array column(s).&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		filterArrByCol(MM, AA);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR FILTER AND ARRAY QUESTIONS ON SEPARATE PAGES:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question on page 1.&lt;br /&gt;
*Create a multiple options question and an array-by-column question on page 2.&lt;br /&gt;
*All three questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Set the multiple options on page 2 to be filtered by the multiple options on page 1.&lt;br /&gt;
*Place the following script in the source of one of the questions on page 2.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;AA&amp;quot; with the ID of the array question. Do not modify the &amp;quot;1&amp;quot;.&lt;br /&gt;
*The function will hide the multiple options question. If options were selected in the multiple options on page 1, the corresponding options will be checked in the hidden multiple options question which will then be used to control the display of the array columns.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		filterArrByCol(MM, AA, 1);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Auto-tabbing between text input fields=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a workaround to facilitate auto-tabbing between text input questions in a single group using a [http://plugins.jquery.com/project/autotab jQuery plugin by Mathachew] and the Maximum characters attribute of questions.&lt;br /&gt;
&lt;br /&gt;
The behaviour will be: When the maximum number of characters has been entered into an input field, the focus (cursor) will be automatically moved to the next input field. When the backspace key is used to remove all characters from a field, the focus will be moved to the previous field. It&#039;s very useful in surveys having many text input questions to avoid having to manually tab or click between fields.&lt;br /&gt;
&lt;br /&gt;
You can view a small demo survey [http://www.partnersinc.biz/surveys//index.php?sid=11327&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Visit [http://plugins.jquery.com/autotabs http://plugins.jquery.com/autotabs], download the plugin script and save it as &#039;&#039;jquery.autotab-1.1b.js&#039;&#039; in the template folder.&lt;br /&gt;
#Link to the script by placing &#039;&#039;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autotab-1.1b.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&#039;&#039; within the &#039;&#039;&amp;lt;head&amp;gt;&#039;&#039; tag of startpage.pstpl.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Create the text based questions that auto-tabbing is to be applied to. (All must be in the same group if you&#039;re using group by group presentation)&lt;br /&gt;
#Define a Maximum characters attribute for all questions that the autotab is applied to.&lt;br /&gt;
{{QS:maximum_chars}}  &lt;br /&gt;
#In the source of the first question of the group that contains the auto-tabbed questions, add the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXAA&#039;).focus(); //initially focus on the first input&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXAA&#039;).autotab({ target: &#039;answerSSSSSXGGXBB&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXBB&#039;).autotab({ previous: &#039;answerSSSSSXGGXAA&#039;, target: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXCC&#039;).autotab({ previous: &#039;answerSSSSSXGGXBB&#039;, target: &#039;answerSSSSSXGGXDD&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXDD&#039;).autotab({ previous: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example has 4 fields to be auto-tabbed between - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
*SSSSS -&amp;gt; Survey ID&lt;br /&gt;
*GG -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Last question&lt;br /&gt;
&lt;br /&gt;
[[File:ids_343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;target&#039;&#039; parameter defines where the next input is and the &#039;&#039;previous&#039;&#039; parameter defines (you guessed it) the previous input.&lt;br /&gt;
&lt;br /&gt;
This plugin also has limited capability of formatting the input text - see comments in the plugin script.&lt;br /&gt;
&lt;br /&gt;
=Custom response listeners=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Listeners can be used to perform functions when a change in an input is detected. There are many uses such as the [[Workarounds#Reverse_array_filter|Reverse array_filter]] but a simple one would be to warn a respondent if they enter a value that may be too high.&lt;br /&gt;
&lt;br /&gt;
We can use the [http://docs.jquery.com/Events/change jQuery change( ) event] to fire a function whenever there is a change to the input. The function will look for an input value higher than 10 and, if found, will warn the respondent.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the script below in the source of one of the questions on the page where:&lt;br /&gt;
**11111 is the survey ID&lt;br /&gt;
**22 is the group ID&lt;br /&gt;
**33 is the question ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer11111X22X33&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
			if ( $(&#039;#answer11111X22X33&#039;).val() &amp;gt; 10 ) {&lt;br /&gt;
				alert (&amp;quot;That&#039;s an awful lot. Are you sure?&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Text input masks=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number ((###) ###-####) or a Canadian postal code (A1A 1A1) The [http://plugins.jquery.com/project/meioMask jQuery meioMask plugin by fabiomcosta] can be used to do this.&lt;br /&gt;
&lt;br /&gt;
The plugin has several pre-defined masks and supports custom masks. It also allows for pasting of input, allows default values and can auto-focus the next form element when the current input is completely filled. See [http://www.meiocodigo.com/projects/meiomask/ http://www.meiocodigo.com/projects/meiomask/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
There is a small demo [http://www.partnersinc.biz/surveys//index.php?sid=36146&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo was as follows:&lt;br /&gt;
#Visit [http://www.meiocodigo.com/projects/meiomask/ http://www.meiocodigo.com/projects/meiomask/], download the latest plugin script and save it as jquery.meiomask.js in the template folder.&lt;br /&gt;
#Link to the script by placing &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.meiomask.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; within the &amp;lt;head&amp;gt; tag of startpage.pstpl.&lt;br /&gt;
#Turn off $filterxsshtml to allow insertion of JavaScript in the questions. ([http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects See documentation here])&lt;br /&gt;
#Create the text input questions that the masks are to be applied to&lt;br /&gt;
#In the source of the help section of the first question of the group that contains the masked inputs, add the following code. ([http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ See How to use script here]) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {	&lt;br /&gt;
						   &lt;br /&gt;
	// Define custom masks&lt;br /&gt;
	$.mask.masks = $.extend($.mask.masks,{&lt;br /&gt;
		customMask1:{ mask: &#039;a9a 9a9&#039; }, // Canadian postal code&lt;br /&gt;
		// Maximum input of 9,999.99, reverse input, default value of 0.00		&lt;br /&gt;
		customMask2:{ mask: &#039;99.999,9&#039;, type : &#039;reverse&#039;, defaultValue : &#039;000&#039; } &lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Set the &#039;alt&#039; attributes of the inputs&lt;br /&gt;
	$(&#039;#answer111111X22XAA&#039;).attr(&#039;alt&#039;, &#039;phone-us&#039;); // a pre-defined mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XBB&#039;).attr(&#039;alt&#039;, &#039;customMask1&#039;); // a custom mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XCC&#039;).attr(&#039;alt&#039;, &#039;customMask2&#039;); // a custom mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XDD&#039;).attr(&#039;alt&#039;, &#039;cc&#039;); // a pre-defined mask for credit card&lt;br /&gt;
	&lt;br /&gt;
	// Tell the plugin to apply masks to these inputs&lt;br /&gt;
	$(&#039;input:#answer111111X22XAA&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XBB&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XCC&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XDD&#039;).setMask();	&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first section defines two custom masks to be used - one for Canadian postal code with a format of A#A #A# and a second for a maximum amount of 9999.99 with reverse input (useful for cost inputs) and a default value of 0.00.&lt;br /&gt;
&lt;br /&gt;
The next section sets the &amp;quot;alt&amp;quot; attributes for the text inputs. This will tell meioMask which mask we will be applying to each input. By default meioMask looks at the alt attribute to find which mask to apply however this can be changed using the [http://www.meiocodigo.com/projects/meiomask/#mm_options mask options].&lt;br /&gt;
&lt;br /&gt;
In the final section we apply the masks to the inputs.&lt;br /&gt;
&lt;br /&gt;
This example has 4 inputs with masks on them - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
&lt;br /&gt;
*11111 -&amp;gt; Survey ID&lt;br /&gt;
*22 -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Fourth question&lt;br /&gt;
&lt;br /&gt;
[[File:Ids 343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
=Text input masks - second method=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91RC6+, FireFox 4.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number ((###) ###-####) or a US social security number (###-##-####). The jQuery meioMask plugin by fabiomcosta is no longer supported but an alternative exists. The DigitalBush Masked Input Plugin is updated and simple to implement in LimeSurvey. See [http://digitalbush.com/projects/masked-input-plugin/ http://digitalbush.com/projects/masked-input-plugin/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
Implementation as follows:&lt;br /&gt;
&lt;br /&gt;
#Visit [http://digitalbush.com/projects/masked-input-plugin/ http://digitalbush.com/projects/masked-input-plugin/], download the latest plugin script and save it as jquery.maskedinput.js in the template folder.&lt;br /&gt;
#Link to the script by placing &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.maskedinput.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; within the &amp;lt;head&amp;gt; tag of startpage.pstpl.&lt;br /&gt;
#Turn off $filterxsshtml to allow insertion of JavaScript in the questions. ([http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects See documentation here])&lt;br /&gt;
#Create the text input questions that the masks are to be applied to&lt;br /&gt;
#In the source of the help section of the first question of the group that contains the masked inputs, add the following code. ([http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ See How to use script here])  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function($) {	 &lt;br /&gt;
		$(&amp;quot;#answer55431X1X5&amp;quot;).mask(&amp;quot;999-99-9999&amp;quot;,{ placeholder:&amp;quot;#&amp;quot; });&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace the &amp;quot;#answer55431X1X5&amp;quot; with your survey ID, group ID, and question ID. You can change the mask format and change or eliminate the placeholder if you wish. If you have multiple questions in the same group, simply copy and paste the line that begins with &amp;quot;$&amp;quot; and change the code to what is needed for your application.&lt;br /&gt;
&lt;br /&gt;
=Select a random response to a &amp;quot;Multiple options&amp;quot; question for later use=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to randomly select one of the checked boxes in a &amp;quot;Multiple options&amp;quot; question and store it&#039;s label for later use in the survey. A possible use would be to have a question asking what products were purchased and then randomly selecting one of the products to ask further questions about.&lt;br /&gt;
&lt;br /&gt;
There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=81252&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Basically what we&#039;ve done here is to put listeners on all of the checkboxes. If a change of state is detected in any of them the &amp;quot;randomResponse&amp;quot; function is called which loops through all of the checkboxes and if it finds a checked state, that box&#039;s label is added to an array. Then a random item is pulled from the array and used to populate the hidden question. This hidden question can then be drawn upon later in the survey using [http://docs.limesurvey.org/tiki-index.php?page=Adding+a+Question#Information_from_previous_answers INSERTANS] or [http://docs.limesurvey.org/tiki-index.php?page=Setting+conditions&amp;amp;structure=English+Instructions+for+LimeSurvey Conditions].&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
#[http://docs.limesurvey.org/tiki-index.php?page=Workarounds%3A+Manipulating+a+survey+at+runtime+using+Javascript&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._in_LimeSurvey_ Set up your survey to use JavaScript].&lt;br /&gt;
#Create a &amp;quot;Multiple options&amp;quot; question that we&#039;re going to randomly pick a checked box from&lt;br /&gt;
#Create a text input question to store the label of the checked box in (we&#039;re going to hide this with JavaScript)&lt;br /&gt;
#Place the script below in the source of one of the questions on the page. &lt;br /&gt;
&lt;br /&gt;
The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
*EDIT HERE (1) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 44 -&amp;gt; hidden question ID.&lt;br /&gt;
*EDIT HERE (2) - 44 -&amp;gt; hidden question ID.&lt;br /&gt;
*EDIT HERE (3) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 33 -&amp;gt; multiple option question ID, A/B/C/D/E/F -&amp;gt; multiple option answer codes. Also add or remove CBs for more or less checkboxes.&lt;br /&gt;
*EDIT HERE (4) - add or remove CBs for more or less checkboxes.&lt;br /&gt;
*EDIT HERE (5) - add or remove CBs for more or less checkboxes. &lt;br /&gt;
&lt;br /&gt;
For more info on these IDs see [http://docs.limesurvey.org/tiki-index.php?page=SGQA+identifier&amp;amp;structure=English+Instructions+for+LimeSurvey SGQA identifier].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
				&lt;br /&gt;
		//// Identify the hidden question input&lt;br /&gt;
		//// EDIT HERE (1) - replace with your hidden question input ID&lt;br /&gt;
		var hiddenInput = &#039;#answer11111X22X44&#039;;&lt;br /&gt;
		&lt;br /&gt;
		//// Make the &amp;quot;hidden&amp;quot; question disappear&lt;br /&gt;
		//// EDIT HERE (2) - replace with your hidden question ID&lt;br /&gt;
		$(&#039;#question44&#039;).hide();&lt;br /&gt;
		&lt;br /&gt;
		//// Identify the checkboxes to be randomized&lt;br /&gt;
		//// EDIT HERE (3) - add or remove as required, &lt;br /&gt;
		//// replace with your checkbox IDs&lt;br /&gt;
		var CB1 = &#039;#answer11111X22X33A&#039;;&lt;br /&gt;
		var CB2 = &#039;#answer11111X22X33B&#039;;&lt;br /&gt;
		var CB3 = &#039;#answer11111X22X33C&#039;;&lt;br /&gt;
		var CB4 = &#039;#answer11111X22X33D&#039;;&lt;br /&gt;
		var CB5 = &#039;#answer11111X22X33E&#039;;&lt;br /&gt;
		var CB6 = &#039;#answer11111X22X33F&#039;;&lt;br /&gt;
		&lt;br /&gt;
		//// Create an array of all checkboxes to be randomized&lt;br /&gt;
		//// EDIT HERE (4) - add or remove CBs as required&lt;br /&gt;
		checkBoxes = new Array( CB1, CB2, CB3, CB4, CB5, CB6 );&lt;br /&gt;
		var checkBoxesLength = checkBoxes.length;&lt;br /&gt;
		&lt;br /&gt;
		//// The randomizing function - no editing required&lt;br /&gt;
		function randomResponse () {&lt;br /&gt;
			var boxLabels = new Array();&lt;br /&gt;
			&lt;br /&gt;
			// loop through all of the checkboxes and if they are checked, &lt;br /&gt;
			// add their label to the boxLabels array&lt;br /&gt;
			for( var i=0; i&amp;lt;checkBoxesLength; i++ ) {&lt;br /&gt;
				if ( $(checkBoxes[i]).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
					var cbid = checkBoxes[i].replace(&#039;#&#039;,&#039;&#039;);&lt;br /&gt;
					boxLabels.push( $( &#039;label[for=&#039; + cbid + &#039;]&#039; ).html() );&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// find a random index of the responses array&lt;br /&gt;
			var randomNum = Math.floor(Math.random() * boxLabels.length); &lt;br /&gt;
			&lt;br /&gt;
			// populate the hidden question input with the &lt;br /&gt;
			// random input value&lt;br /&gt;
			$(hiddenInput).val( boxLabels[randomNum] ); &lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		//// The listeners that will fire the randomize function if a &lt;br /&gt;
		//// change occurs in the checkboxes&lt;br /&gt;
		//// EDIT HERE (5) - add or remove CBs as required&lt;br /&gt;
		$(CB1).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB2).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB3).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB4).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB5).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB6).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});	&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Display secondary options in a &amp;quot;Multiple options&amp;quot; question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to display secondary options in a &amp;quot;Multiple options&amp;quot; question if a primary option is checked as in the images below.&lt;br /&gt;
&lt;br /&gt;
Primary option not selected:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Secondary_options_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Primary option selected:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Secondary_options_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=11491&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
We&#039;ve put a listener on the primary answer (&amp;quot;Option 1&amp;quot; in the demo) that shows or hides the secondary answers depending on the state of the primary.&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
#[http://docs.limesurvey.org/tiki-index.php?page=Workarounds%3A+Manipulating+a+survey+at+runtime+using+Javascript&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._in_LimeSurvey_ Set up your survey to use JavaScript].&lt;br /&gt;
#Create a &amp;quot;Multiple options&amp;quot; question including both the primary and secondary answers (in the order that you would like them displayed if all shown)&lt;br /&gt;
#Add the following script to the source of the question.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		&lt;br /&gt;
		/**** &lt;br /&gt;
		The following code puts a listener on an answer in a multiple options&lt;br /&gt;
		question (the primary answer) and if that answer is checked, a secondary &lt;br /&gt;
		level of answers is displayed.&lt;br /&gt;
		****/&lt;br /&gt;
		&lt;br /&gt;
		// --- 1 --- Indent the secondary answers a bit&lt;br /&gt;
		$( &#039;#questionQQ li:eq(1)&#039; ).css({ &#039;margin-left&#039;:&#039;2.5em&#039; });&lt;br /&gt;
		$( &#039;#questionQQ li:eq(2)&#039; ).css({ &#039;margin-left&#039;:&#039;2.5em&#039; });&lt;br /&gt;
		&lt;br /&gt;
		// --- 2 --- When the page loads, see if the primary answer is checked and if not, &lt;br /&gt;
                //hide and un-check all secondary answers&lt;br /&gt;
		if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
			&lt;br /&gt;
			$( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
			$( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
			&lt;br /&gt;
			$( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
			$( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// --- 3 --- Now put a listener on the primary answer to show or hide secondary answers &lt;br /&gt;
		// We need to use .click instead of .change cause IE won&#039;t cooperate&lt;br /&gt;
		$(&#039;#answerSSSSSXGGXQQAA&#039;).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Have a look at the primary answer and hide/show the secondary answers accordingly&lt;br /&gt;
			if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
			&lt;br /&gt;
				$( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
				$( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
				&lt;br /&gt;
				$( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
				$( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				&lt;br /&gt;
				$( &#039;#questionQQ li:eq(1)&#039; ).show();&lt;br /&gt;
				$( &#039;#questionQQ li:eq(2)&#039; ).show();&lt;br /&gt;
			} &lt;br /&gt;
			&lt;br /&gt;
			// The original functions of the click event&lt;br /&gt;
			cancelBubbleThis(event);&lt;br /&gt;
			checkconditions(this.value, this.name, this.type);&lt;br /&gt;
		  }&lt;br /&gt;
		);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 1:&#039;&#039;&#039;&lt;br /&gt;
*This section indents the secondary answers to give the look of a list in a list when they&#039;re shown&lt;br /&gt;
*&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID&lt;br /&gt;
*&#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; are the index positions of your secondary options. Modify or add as necessary for the number and placement of secondary options in your question. Note that the index starts at 0 so &#039;&#039;&#039;eq(1)&#039;&#039;&#039; actually affects the second option in the full list and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; affects the third. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 2:&#039;&#039;&#039;&lt;br /&gt;
*This section checks the state of the primary question when the page is loaded and if necessary hides the secondary questions. We need this in case users navigate away from and then back to the page.&lt;br /&gt;
*Modify &#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; as above.&lt;br /&gt;
*&#039;&#039;&#039;SSSSS&#039;&#039;&#039; is your survey ID.&lt;br /&gt;
*&#039;&#039;&#039;GG&#039;&#039;&#039; is your group ID.&lt;br /&gt;
*&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID.&lt;br /&gt;
*&#039;&#039;&#039;AA&#039;&#039;&#039; is your primary answer code.&lt;br /&gt;
*&#039;&#039;&#039;BB&#039;&#039;&#039; and &#039;&#039;&#039;CC&#039;&#039;&#039; are your secondary answer codes (add as necessary). &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 3:&#039;&#039;&#039;&lt;br /&gt;
*This is the section that &amp;quot;listens&amp;quot; to the primary answer and reacts accordingly.&lt;br /&gt;
*Edit as in section 2.&lt;br /&gt;
&lt;br /&gt;
For more info on these IDs see SGQA identifier(external link).&lt;br /&gt;
&lt;br /&gt;
This code could be tidied up and shortened a bit but I left it this way to make it easier to follow.&lt;br /&gt;
&lt;br /&gt;
=Minimum number of required answers in an array (pre 1.92)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92 all array style questions have the min_answers and max_answers options, so this script is obsolete.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to specify a &#039;&#039;&#039;minimum number&#039;&#039;&#039; of answers required in an array question. It is an alternative to the &amp;quot;Mandatory&amp;quot; parameter which specifies that &#039;&#039;&#039;all&#039;&#039;&#039; answers are required. It could also be easily modified to specify a maximum number of answers.&lt;br /&gt;
&lt;br /&gt;
We accomplish this by placing an onload function in the source of the array question. This function hides the Next/Submit button and displays a warning element until it detects a minimum number of responses. It then hides the warning and shows the Next/Submit button.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=97166&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Set up the template to use custom onload functions. (See the [[Workarounds#Custom onload function|workaround here]])&lt;br /&gt;
#In the source of the array question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Modify the &#039;&#039;SETTINGS&#039;&#039; section of the code as required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	// Wait until the document is fully loaded&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
	&lt;br /&gt;
		/********************** SETTINGS **********************/&lt;br /&gt;
		// The text to appear in the warning element&lt;br /&gt;
		var warningText = &#039;Please answer at least 4 to continue&#039;;&lt;br /&gt;
		// The question ID&lt;br /&gt;
		var questionId = 137;&lt;br /&gt;
		// The minimum number of answers required&lt;br /&gt;
		var minNumber = 4;&lt;br /&gt;
		/******************************************************/&lt;br /&gt;
		&lt;br /&gt;
		// Create the warning element and place it after the submit button&lt;br /&gt;
		var el = document.createElement(&#039;div&#039;);&lt;br /&gt;
		el.setAttribute(&#039;id&#039;,&#039;warning&#039;);&lt;br /&gt;
		document.body.appendChild(el);&lt;br /&gt;
		$( &#039;#warning&#039; ).css({&lt;br /&gt;
			&#039;border&#039;:&#039;1px solid #333333&#039;,&lt;br /&gt;
			&#039;width&#039;:&#039;200px&#039;,&lt;br /&gt;
			&#039;padding&#039;:&#039;3px&#039;,&lt;br /&gt;
			&#039;color&#039;:&#039;red&#039;&lt;br /&gt;
		});&lt;br /&gt;
		$(&#039;#warning&#039;).html(warningText);&lt;br /&gt;
		$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).after($(&#039;#warning&#039;));&lt;br /&gt;
		&lt;br /&gt;
		// Detect the initial number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
		var inputInitCount = 0;&lt;br /&gt;
		$(&#039;#question&#039; + questionId + &#039; input&#039;).each(function(i) {&lt;br /&gt;
			if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
				inputInitCount++;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		if (inputInitCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
			$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
			$(&#039;#warning&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#warning&#039;).show();&lt;br /&gt;
			$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Listener to detect number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
		$(&#039;#question&#039; + questionId + &#039; input.radio, #question&#039;+questionId+&#039; tbody[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;javatbd&amp;quot;] td&#039;).click(function() {&lt;br /&gt;
			var inputCount = 0;&lt;br /&gt;
			$(&#039;#question&#039; + questionId + &#039; input.radio&#039;).each(function(i) {&lt;br /&gt;
				if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
					inputCount++;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
			if (inputCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
				$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
				$(&#039;#warning&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;#warning&#039;).show();&lt;br /&gt;
				$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// The original functions of the click event&lt;br /&gt;
			checkconditions(this.value, this.name, this.type);&lt;br /&gt;
		});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Minimum elapsed time before moving forward in survey=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, Firefox 7.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround interrupts the Next/Submit function and checks the amount of time elapsed since the page loaded. If the time is less than the minimum dictated, the respondent is alerted and not allowed to proceed. It is useful if you want to enforce a minimum amount of time spent viewing a page.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the script below in the source of one of the questions on the page, replacing &amp;quot;TT&amp;quot; with the minimum number of seconds required before advancing is allowed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		minTime(TT);&lt;br /&gt;
&lt;br /&gt;
		function minTime(minTime) {&lt;br /&gt;
&lt;br /&gt;
			var startTime = new Date();&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
				var endTime = new Date();&lt;br /&gt;
&lt;br /&gt;
				if((endTime - startTime)/1000 &amp;lt;= minTime) {&lt;br /&gt;
					alert (&#039;You must spend at least &#039;+minTime+&#039; seconds on the question.&#039;);&lt;br /&gt;
					return false;&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					return true;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Minimum number of characters in Long free text or Huge free text questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, Firefox 7.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.91, you can use regular expression masks (validation) to specify the minimum number of required characters.  However, even if the question is mandatory, it can still be blank.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version  1.92, if you make the question mandatory and use a validation mask to specify the minimum number of characters, then the user will be forced to answer the question.  Note that unlike 1.91, they can submit their current answers, even if partially invalid (so they are stored in the database), but they will not ber able to proceed to the next page until they have passed all mandatory and validity checks.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround interrupts the Next/Submit function and checks the number of characters entered in a Long free text or Huge free text question. If the number is less than the minimum dictated, the respondent is alerted and not allowed to proceed.&lt;br /&gt;
&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
&lt;br /&gt;
#Place the script below in the source of one of the questions on the page, replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;CC&amp;quot; with the minimum number of characters required before advancing is allowed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       minChar(QQ, CC);&lt;br /&gt;
&lt;br /&gt;
       function minChar(qID, minChars) {&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               if($(&#039;#question&#039;+qID+&#039; textarea&#039;).val().replace(/ /g,&#039;&#039;).length &amp;lt; minChars) {&lt;br /&gt;
&lt;br /&gt;
                   alert (&#039;You must enter at least &#039;+minChars+&#039; characters.&#039;);&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Variable Length Array (Multi Flexible Text) question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows a respondent to add or remove rows of an Array (Multi Flexible Text) question. It&#039;s useful to avoid the page being cluttered with unnecessary array rows.&lt;br /&gt;
&lt;br /&gt;
A function is placed in the template.js file of your template (use template editor). This function hides all of the array rows except the first and inserts two elements that when clicked show or hide rows accordingly.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=53132&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
It must be noted that you can not make this question Mandatory as the respondent will have no way to complete hidden fields. If you want the displayed fields to be mandatory you will need to validate them in another function or modify this function to only allow the addition of rows if all fields in the last row are completed and then disable those fields - that, however, is a little over the top for this example.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
#Set up your survey to use JavaScript (See instructions [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|here]])&lt;br /&gt;
&lt;br /&gt;
#Add the following script to your &#039;&#039;template.js&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end with the question ID.&lt;br /&gt;
&lt;br /&gt;
#Create one or more Array (Multi Flexible Text) questions&lt;br /&gt;
&lt;br /&gt;
#If you want to apply it to more arrays on the same page simply add more calls with the appropriate question IDs. (eg. varLengthArray(1); varLengthArray(2);...)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // A function to add or remove rows of an Array (Multi Flexible)(Text) question&lt;br /&gt;
	function varLengthArray(qID) {&lt;br /&gt;
&lt;br /&gt;
		if ($(&#039;#question&#039;+qID+&#039;&#039;).length &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
			// The HTML content of the Add/Remove elements - modify as you wish&lt;br /&gt;
			var addContent = &#039;[+]&#039;;&lt;br /&gt;
			var removeContent = &#039;[-]&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Create the Add and Remove elements &amp;amp; insert them&lt;br /&gt;
			var el1 = document.createElement(&#039;div&#039;);&lt;br /&gt;
			el1.setAttribute(&#039;id&#039;,&#039;addButton&#039;+qID);&lt;br /&gt;
			document.body.appendChild(el1);&lt;br /&gt;
			var el2 = document.createElement(&#039;div&#039;);&lt;br /&gt;
			el2.setAttribute(&#039;id&#039;,&#039;removeButton&#039;+qID);&lt;br /&gt;
			document.body.appendChild(el2);&lt;br /&gt;
&lt;br /&gt;
			// Move them to after the array&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).appendTo($( &#039;#question&#039; + qID + &#039; table.question&#039; ).parent());&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).appendTo($( &#039;#question&#039; + qID + &#039; table.question&#039; ).parent());&lt;br /&gt;
&lt;br /&gt;
			// Insert their HTML&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).html( addContent );&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).html( removeContent );&lt;br /&gt;
&lt;br /&gt;
			// Style the elements - you can modify here if you wish&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).css({&lt;br /&gt;
				&#039;margin&#039;:&#039;10px 0 0 10px&#039;,&lt;br /&gt;
				&#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
				&#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
				&#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
				&#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
				&#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
				&#039;float&#039;:&#039;left&#039;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).css({&lt;br /&gt;
				&#039;margin&#039;:&#039;10px 0 0 10px&#039;,&lt;br /&gt;
				&#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
				&#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
				&#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
				&#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
				&#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
				&#039;float&#039;:&#039;left&#039;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Initially hide the Remove element&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).hide();&lt;br /&gt;
&lt;br /&gt;
			// Call the functions below when clicked&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).click(function (event) {&lt;br /&gt;
				addRow(qID);&lt;br /&gt;
			});&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).click(function (event) {&lt;br /&gt;
				removeRow(qID);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Function to add a row, also shows the Remove element and hides the&lt;br /&gt;
			//Add element if all rows are shown&lt;br /&gt;
			function addRow(qID) {&lt;br /&gt;
				var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
				var rowCount = $( arrayRow ).size() - 1;&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
				$( &#039;div#removeButton&#039;+qID ).show();&lt;br /&gt;
				if ( $( arrayRow + &#039;:eq(&#039; + rowCount + &#039;)&#039; ).attr(&#039;name&#039;) == &#039;visible&#039; )  {&lt;br /&gt;
					$( &#039;div#addButton&#039;+qID ).hide();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Function to remove a row, also clears the contents of the removed row,&lt;br /&gt;
			// shows the Add element if the last row is hidden and hides the Remove&lt;br /&gt;
			// element if only the first row is shown&lt;br /&gt;
			function removeRow(qID) {&lt;br /&gt;
				var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
				var rowCount = $( arrayRow ).size() - 1;&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last input[type=&amp;quot;text&amp;quot;]&#039; ).val(&#039;&#039;);&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last&#039; ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
				$( &#039;div#addButton&#039;+qID ).show();&lt;br /&gt;
				if ( $( arrayRow + &#039;:eq(1)&#039; ).attr(&#039;name&#039;) == &#039;hidden&#039; )  {&lt;br /&gt;
					$( &#039;div#removeButton&#039;+qID ).hide();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Just some initialization stuff&lt;br /&gt;
			var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
			var rowCount = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Initially hide all except first row or any rows with populated inputs&lt;br /&gt;
			$( arrayRow ).each(function(i) {&lt;br /&gt;
				if ( i &amp;gt; 0 ) {&lt;br /&gt;
					// We also need to give the hidden rows a name cause IE doesn&#039;t&lt;br /&gt;
					// recognize jQuery :visible selector consistently&lt;br /&gt;
					$( this ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
					$(&#039;input[type=text]&#039;, this).each(function(i) {&lt;br /&gt;
						if ($(this).attr(&#039;value&#039;) != &#039;&#039;) {&lt;br /&gt;
							$(this).parents(&#039;tbody:eq(0)&#039;).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
							$( &#039;div#removeButton&#039;+qID ).show();&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
					rowCount = i;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Call the function with a question ID&lt;br /&gt;
	varLengthArray(QQ);&lt;br /&gt;
&lt;br /&gt;
});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expandable Array=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to present an array question incrementally. That is to say that initially only the first option (row) in the array is shown. When that option is answered the next is shown and so-on.&lt;br /&gt;
&lt;br /&gt;
A JavaScript function is placed in the source of the array question. This function hides all of the array rows except the first and then displays them as options are answered.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=94958&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
The workaround supports following question types:&lt;br /&gt;
*Array (flexible labels)&lt;br /&gt;
*Array (flexible labels) by column&lt;br /&gt;
*Array (Yes/No/Uncertain)&lt;br /&gt;
*Array (Increase, Same, Decrease)&lt;br /&gt;
*Array (Flexible Labels) dual scale&lt;br /&gt;
*Array (10 point choice)&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Set up your survey to use JavaScript. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|documentation here]])&lt;br /&gt;
#Create one or more Array questions&lt;br /&gt;
#In the source of the first array question add the following script.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end of the script with the question ID of the array you would like to manipulate.&lt;br /&gt;
#If you want to apply it to more arrays on the same page, simply add more calls with the appropriate question IDs. (eg. expandingArray(1); expandingArray(2);...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// A function to show subsequent rows of an array as options are checked&lt;br /&gt;
		function expandingArray(qID) {&lt;br /&gt;
&lt;br /&gt;
			// Build an array of the question rows&lt;br /&gt;
			var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody tr&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Initially hide all rows unless an input was previously checked&lt;br /&gt;
			$( arrayRow ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
				if ( $( arrayRow  + &#039;:eq(&#039; + i + &#039;) input.radio:checked&#039; ).length != 0 ) {&lt;br /&gt;
					$(this).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					$(this).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Now show the first hidden row&lt;br /&gt;
			addRow();&lt;br /&gt;
&lt;br /&gt;
			// Add another row when an option is checked for the first time&lt;br /&gt;
			$( &#039;#question&#039; + qID + &#039; td.answer input.radio&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
				if ($(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;) != &#039;clickedRow&#039;) {&lt;br /&gt;
					addRow();&lt;br /&gt;
					$(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				// The original function of the click event&lt;br /&gt;
				checkconditions(this.value, this.name, this.type);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Add another row when an table cell is clicked for the first time&lt;br /&gt;
			$( &#039;#question&#039; + qID + &#039; table.question tbody td&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
				if ($(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;) != &#039;clickedRow&#039;) {&lt;br /&gt;
					addRow();&lt;br /&gt;
					$(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Function to add a row&lt;br /&gt;
			function addRow() {&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with a question ID&lt;br /&gt;
		expandingArray(QQ);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions - ENHANCED=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping as many answers at the end of the list as specified by the var insertitems=n, where n is the number of answers you want left unrandomized. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the 5th to 7th displayed last as in the image below (assuming you assigned the number 3 to insertitems):&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [[Optional settings#Survey Behavior|$shownoanswer option]] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Set var insertitems=n (n = the number of items you want un-randomized)&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
Onload code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Function to allow randomization of all answers except the last one in Multiple options and List/radio questions&lt;br /&gt;
&lt;br /&gt;
       function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
           //var to define how many lists to be added at the end&lt;br /&gt;
&lt;br /&gt;
           var insertitems=3;&lt;br /&gt;
&lt;br /&gt;
           // Find the number of answers&lt;br /&gt;
&lt;br /&gt;
           var ansCount = &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
           lastitems=new Array();&lt;br /&gt;
&lt;br /&gt;
           var liid=new Array();&lt;br /&gt;
&lt;br /&gt;
           var $ul;&lt;br /&gt;
&lt;br /&gt;
           var j=0;&lt;br /&gt;
&lt;br /&gt;
           $( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                           ansCount = (i + 1);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                           if(i&amp;gt;ansCount-(insertitems+1)){&lt;br /&gt;
&lt;br /&gt;
                             lastitems[j]=$(this).html();&lt;br /&gt;
&lt;br /&gt;
                             liid[j]=$(this).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                             j++;&lt;br /&gt;
&lt;br /&gt;
                             $(this).remove();&lt;br /&gt;
&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
// get current ul&lt;br /&gt;
&lt;br /&gt;
$ul = $(this).parent();&lt;br /&gt;
&lt;br /&gt;
// get array of list items in current ul&lt;br /&gt;
&lt;br /&gt;
var $liArr = $ul.children(&#039;li&#039;);&lt;br /&gt;
&lt;br /&gt;
// sort array of list items in current ul randomly&lt;br /&gt;
&lt;br /&gt;
$liArr.sort(function(a,b){&lt;br /&gt;
&lt;br /&gt;
// Get a random number between 0 and 100&lt;br /&gt;
&lt;br /&gt;
var temp = parseInt( Math.random()*100 );&lt;br /&gt;
&lt;br /&gt;
// Get 1 or 0, whether temp is odd or even&lt;br /&gt;
&lt;br /&gt;
var isOddOrEven = temp%2;&lt;br /&gt;
&lt;br /&gt;
// Get +1 or -1, whether temp greater or smaller than 5&lt;br /&gt;
&lt;br /&gt;
var isPosOrNeg = temp&amp;gt;5 ? 1 : -1;&lt;br /&gt;
&lt;br /&gt;
// Return -1, 0, or +1&lt;br /&gt;
&lt;br /&gt;
return( isOddOrEven*isPosOrNeg );&lt;br /&gt;
&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
// append list items to ul&lt;br /&gt;
&lt;br /&gt;
.appendTo($ul);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$.each(lastitems,function(i){&lt;br /&gt;
&lt;br /&gt;
$( $ul ).append(&amp;quot;&amp;lt;li id=&amp;quot;+liid[i]+&amp;quot;&amp;gt;&amp;quot;+this+&amp;quot;&amp;lt;/li&amp;gt;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Call the function with the SID, GID and QID&lt;br /&gt;
&lt;br /&gt;
       partRand(SSSSS, GG, QQ);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last as in the image below:&lt;br /&gt;
&lt;br /&gt;
[[File:random_336x179gif.gif]]&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [[Optional settings#Survey Behavior|$shownoanswer option]] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [[Advanced question settings#random_order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers except the last one in Multiple options and List/radio questions&lt;br /&gt;
		function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = (i + 1);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list&lt;br /&gt;
			$( &#039;input#answer&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).parent().appendTo($( &#039;#question&#039; + qID + &#039; td.answer ul&#039; ));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
			partRand(SSSSS, GG, QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - List (dropdown) questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the one above, allows the answers of List (dropdown) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more List (dropdown) questions with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers&lt;br /&gt;
		//except the last one in List/dropdown questions&lt;br /&gt;
		function partRandDD(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; select option&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = i;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list&lt;br /&gt;
			$( &#039;option[value=&amp;quot;&#039; + ansCount + &#039;&amp;quot;]&#039; ).appendTo($( &#039;div#question&#039; + qID + &#039; select&#039; ));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
		partRandDD(89344, 72, 244);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple numerical input=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, Safari 5.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the ones above, allows the answers of Multiple numerical input questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple numerical input question with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers except the last one in multiple numeric input questions&lt;br /&gt;
		function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; div.answers li&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = (i - 1);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list - but before the first helping sum&lt;br /&gt;
			$( &#039;li#javatbd&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).insertBefore($( &#039;div#question&#039; + qID + &#039; div.answers li.multiplenumerichelp&#039; ).first());&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
		partRand(SID, GID, QID);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using this solution for Multiple numerical input questions might be a bit more complicated than for other question types. All answers are organized in an unordered list (&amp;lt;nowiki&amp;gt;&amp;lt;ul&amp;gt;&amp;lt;/nowiki&amp;gt;) structure. However, if advanced question settings like &#039;&#039;Equals sum value&#039;&#039; are used, LimeSurvey adds helping information (e.g. sum of all entries and remainder) to the same unordered list using the class &#039;&#039;multiplenumerichelp&#039;&#039; for these additional list items. The above example  assumes that at least one of these list items is present and moves the last answer to the position right above the first helper item. Without such advanced settings, the code will most certainly need adaptation.&lt;br /&gt;
&lt;br /&gt;
=Making one (or more) rows of an array mandatory=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, Firefox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to define one or more rows of an array question as mandatory (instead of all of them which the &amp;quot;Mandatory&amp;quot; question setting does). It is [http://www.partnersinc.biz/surveys//index.php?sid=26842&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
A JavaScript function interrupts the submit function and checks if the inputs in the mandatory row(s) are populated. If not, an alert is popped up, the offending inputs are turned pink and the submit is aborted. Otherwise the submit goes ahead.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions (see [[Optional settings#Security|documentation here]]).&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following script (see [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]]).&lt;br /&gt;
#Modify the warningText (line10)as required.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; (lines 13 and 14)  with the question ID and add calls as necessary for more rows - the example code renders rows 1 and 3 mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function () {&lt;br /&gt;
&lt;br /&gt;
		// Interrupt the submit function&lt;br /&gt;
		$(&#039;form#limesurvey&#039;).submit(function () {&lt;br /&gt;
&lt;br /&gt;
			// Override the built-in &amp;quot;disable navigation buttons&amp;quot; feature&lt;br /&gt;
			$(&#039;#moveprevbtn, #movenextbtn, #movesubmitbtn&#039;).attr(&#039;disabled&#039;, &#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
			var empty = 0;&lt;br /&gt;
			var warningText = &#039;Please complete the highlighted inputs.&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Call the mandatory row function with question IDs and row numbers&lt;br /&gt;
			mandatoryRow(QQ, 1);&lt;br /&gt;
			mandatoryRow(QQ, 3);&lt;br /&gt;
&lt;br /&gt;
			// A function to render rows of an array mandatory&lt;br /&gt;
			function mandatoryRow(qID, rowNum) {&lt;br /&gt;
&lt;br /&gt;
				$(&#039;div#question&#039; + qID + &#039; table.question tbody[id&amp;lt;/div&amp;gt;=&amp;quot;javatbd&amp;quot;]:eq(&#039; + Number(rowNum - 1) + &#039;) input[type=&amp;quot;text&amp;quot;]&#039;).each(function (i) {&lt;br /&gt;
&lt;br /&gt;
					if ($(this).val() == &#039;&#039;) {&lt;br /&gt;
						$(this).css(&#039;background-color&#039;, &#039;pink&#039;);&lt;br /&gt;
						empty = 1;&lt;br /&gt;
					} &lt;br /&gt;
					else {&lt;br /&gt;
						$(this).css(&#039;background-color&#039;, &#039;#FFFFFF&#039;);&lt;br /&gt;
					}&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (empty == 1) {&lt;br /&gt;
				alert(warningText);&lt;br /&gt;
				return false;&lt;br /&gt;
			} &lt;br /&gt;
			else {&lt;br /&gt;
				return true;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Randomly displaying one of a few YouTube videos, and recording which was displayed=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland has created and documented a method to randomly display one of a number of youtube videos in a single question, and save which one was displayed.&lt;br /&gt;
&lt;br /&gt;
http://www.aptigence.com.au/home/archives/23-Random-display-of-videos-in-a-question-2-YouTube.html&lt;br /&gt;
&lt;br /&gt;
=Randomly displaying one of a few pictures, and recording which was displayed=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.91+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The following steps allow you to randomly display one of a few pictures and record in the dataset which picture was displayed. We use four pictures in this example, but you can easily adapt these scripts according to your needs.&lt;br /&gt;
&lt;br /&gt;
1. Create a new sub-directory &#039;&#039;&#039;pic&#039;&#039;&#039; in your LimeSurvey folder.&lt;br /&gt;
&lt;br /&gt;
2. Copy four pictures (named &#039;&#039;1.jpg&#039;&#039;, &#039;&#039;2.jpg&#039;&#039;, &#039;&#039;3.jpg&#039;&#039;, and &#039;&#039;4.jpg&#039;&#039;) in this pic sub-directory.&lt;br /&gt;
&lt;br /&gt;
3. Deactivate the &#039;&#039;Filter HTML for XSS&#039;&#039; function in LimeSurvey&#039;s &#039;&#039;Global Settings&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
4. Create a &#039;&#039;&#039;Short free text&#039;&#039;&#039; question where you want these pictures to be displayed.&lt;br /&gt;
&lt;br /&gt;
5. Figure out the [[SGQA identifier|SGQA Identifier]] of this question (e.g., 12345X67X89).&lt;br /&gt;
&lt;br /&gt;
6. Paste the following code as question text after activating the editor&#039;s &#039;&#039;Source&#039;&#039; view and replace both SSSSSXGGXQQ strings with your SGQA identifier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please have a look at this picture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(&lt;br /&gt;
&lt;br /&gt;
function(){&lt;br /&gt;
&lt;br /&gt;
// Find a random number (here between 1 and 4)&lt;br /&gt;
&lt;br /&gt;
var randNumber = Math.floor(Math.random()*4 + 1);&lt;br /&gt;
&lt;br /&gt;
// Save the number as answer of this question&lt;br /&gt;
&lt;br /&gt;
$(&#039;input#answerSSSSSXGGXQQ&#039;).val(randNumber);&lt;br /&gt;
&lt;br /&gt;
// Hide this answer field&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&amp;quot;answerSSSSSXGGXQQ&amp;quot;).style.display=&#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
// Show the picture&lt;br /&gt;
&lt;br /&gt;
picString = &#039;&amp;lt;img src=&amp;quot;pic/&#039; + String(randNumber) + &#039;.jpg&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;pic&#039;).innerHTML = picString;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
);&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;pic&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to display the number of this picture in a later question, use the following code as question text (don&#039;t forget to replace the SSSSSXGGXQQ string acordingly):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You saw picture number {INSERTANS:SSSSSXGGXQQ}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perhaps you want to display the same picture again in a later question, but a little bit smaller (100px width, 100px height)? Just paste the following code as question text after activating the editor&#039;s &#039;&#039;Source&#039;&#039; view, and replace the SSSSSXGGXQQ string acordingly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here you see the picture again: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(&lt;br /&gt;
&lt;br /&gt;
function(){&lt;br /&gt;
&lt;br /&gt;
// Get the picture number from previous question&lt;br /&gt;
&lt;br /&gt;
var randNumber = &amp;quot;{INSERTANS:SSSSSXGGXQQ}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Show picture&lt;br /&gt;
&lt;br /&gt;
picString = &#039;&amp;lt;img width=&amp;quot;100&amp;quot; height=&amp;quot;100&amp;quot; src=&amp;quot;pic/&#039; + String(randNumber) + &#039;.jpg&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;pic&#039;).innerHTML = picString;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
);&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;pic&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple numerical input with max_num_value defined in token (personalized limit)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, max_num_value can be an experession, so you can simply enter the {TOKEN} or other variable in that question attribute.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make personalized survey with multiple numerical input when max_num_value (Maximum sum value) is different for each user and is loaded from the token use following tricks:&lt;br /&gt;
*Create 1st group with numerical input field (1000X10X11). &amp;quot;Limit&amp;quot;&lt;br /&gt;
*Add java script into this question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&#039;answer1000X10X11&#039;).value=&#039;{TOKEN:ATTRIBUTE_1}&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&#039;answer1000X10X11&#039;).readOnly=1;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
TOKEN:ATTRIBUTE_1 is individual limit defined in token.&lt;br /&gt;
&lt;br /&gt;
readOnly=1 // user shouldn&#039;t change it.&lt;br /&gt;
*Create 2nd group with multiple numerical input and add &amp;quot;Max value from SGQA&amp;quot; with 1000X10X11 as argument.&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t want to show first field with numerical input (and show definied limit in different way) you can add 2 lines to above script to hide whole question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;question85&#039;).style.display=&#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;display85&#039;).value=&#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
question85 and display85 are field names.&lt;br /&gt;
&lt;br /&gt;
Note: It&#039;s no possible to create it into one group, because all SGQA references can only refer to data on a previous page because when clicking next the answer is stored at the DB and the SGQA is replaced by querying the database.&lt;br /&gt;
&lt;br /&gt;
=Default values in array questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.87+ (7557), IE 6/7, Firefox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of Version 1.92, many more question types support default values.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to allow you to pre-check default answers in all sub-questions of an array type question. You can select a column of the array to be checked as the page loads. The script first checks to see if a sub-question has already been answered and, if not, checks the default answer.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use script]].&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following script.&lt;br /&gt;
#Replace&amp;quot;QQ&amp;quot; with the question ID and &amp;quot;CC&amp;quot; with the column number to be checked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // A function to pre-check a column of an array&lt;br /&gt;
&lt;br /&gt;
       function checkedDefault(qID, column) {&lt;br /&gt;
&lt;br /&gt;
           var checkedCol = column - 1;&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039; + qID + &#039; table.question tbody tr&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
               if ($(&#039;input.radio[checked=true]&#039;, this).length == 0) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;input.radio:eq(&#039; + checkedCol + &#039;)&#039;, this).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       // Call the function with a question ID and column number&lt;br /&gt;
&lt;br /&gt;
       checkedDefault(QQ, CC);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Record group view time=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.87+ (8518), IE 6/7, Firefox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, group view time is accurately recorded in the timings table if you choose the Record Timings survey option.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to populate a hidden question with the total time that a respondent views a group. If used in a group with only one question, it could be used to track the amount of time required to answer the question.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#In the group, create a short-text question. We will hide this later with JavaScript and populate it with the elapsed time.&lt;br /&gt;
#Place the following script in the source of the short-text question.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in line 6 with the ID of the short-text question.&lt;br /&gt;
&lt;br /&gt;
The script populates the hidden question with the elapsed time since the group was opened. If a respondent leaves the group and then returns, the timer continues up from the elapsed time of the last visit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
       // call the functions with the hidden timer question ID&lt;br /&gt;
&lt;br /&gt;
       runTimer(QQ);&lt;br /&gt;
&lt;br /&gt;
       function runTimer(timeQID) {&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+timeQID).hide();&lt;br /&gt;
&lt;br /&gt;
           var initSec = &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
           // Check for elapsed time from previous visits&lt;br /&gt;
&lt;br /&gt;
           if ($(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val()) {&lt;br /&gt;
&lt;br /&gt;
               var initTime = $(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               initTimeArr = initTime.split(&#039;:&#039;);&lt;br /&gt;
&lt;br /&gt;
               initSec = Number[[initTimeArr[0]*3600]]+Number[[initTimeArr[1]*60]]+Number(initTimeArr[2]);&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Run the timer update function&lt;br /&gt;
&lt;br /&gt;
           recordTime(initSec, timeQID);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Timer update function&lt;br /&gt;
&lt;br /&gt;
   function recordTime(elapsedSec, timeQID){&lt;br /&gt;
&lt;br /&gt;
       elapsedSec++;&lt;br /&gt;
&lt;br /&gt;
       var h = Math.floor(elapsedSec / 3600);&lt;br /&gt;
&lt;br /&gt;
       var m = Math.floor(elapsedSec % 3600 / 60);&lt;br /&gt;
&lt;br /&gt;
       var s = Math.floor(elapsedSec % 3600 % 60);&lt;br /&gt;
&lt;br /&gt;
       var elapsedTime = [[h &amp;gt; 0 ? h + &amp;quot;:&amp;quot; : &amp;quot;00:&amp;quot;) + (m &amp;gt; 0 ? (m &amp;lt; 10 ? &amp;quot;0&amp;quot; : &amp;quot;&amp;quot;) + m + &amp;quot;:&amp;quot; : &amp;quot;00:&amp;quot;) + (s &amp;lt; 10 ? &amp;quot;0&amp;quot; : &amp;quot;&amp;quot;) + s);&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val(elapsedTime);&lt;br /&gt;
&lt;br /&gt;
        // Run the timer update function every second&lt;br /&gt;
&lt;br /&gt;
        setTimeout(&#039;recordTime(&#039;+elapsedSec+&#039;, &#039;+timeQID+&#039;)&#039;,1000);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Toggle visibility of groups=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to toggle the visibility of groups in an &amp;quot;all in one&amp;quot; survey. Initially the groups are hidden and there are links inserted to display the groups. It&#039;s useful to avoid the page being cluttered with many groups and lets the respondent focus on one at a time.&lt;br /&gt;
&lt;br /&gt;
It&#039;s [http://www.partnersinc.biz/surveys//index.php?sid=33613&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Set the survey to run in &amp;quot;all in one&amp;quot; mode.&lt;br /&gt;
#Add your groups and questions.&lt;br /&gt;
#Place the following script in the source of one of the questions in the first group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The comments in the script are pretty self-explanatory but it does the following:&lt;br /&gt;
&lt;br /&gt;
#initially hides all of the groups&lt;br /&gt;
#inserts a link above each one to toggle its display&lt;br /&gt;
#some styles are added to the clickable links but these could be done in template.css instead&lt;br /&gt;
#shows any groups that have an unanswered mandatory after a submit attempt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
		// Insert show/hide divs before all group wrapper divs&lt;br /&gt;
		$(&#039;&amp;lt;div class=&amp;quot;groupToggler&amp;quot;&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;).insertBefore(&#039;div[id^=&amp;quot;group-&amp;quot;]&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Add some text to the show/hide divs&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).each(function(i) {&lt;br /&gt;
			($( this ).text(&#039;Show/Hide Group &#039;+(i+1)+&#039;&#039;));&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Add some styles to the show/hide divs&lt;br /&gt;
		$(&#039;.groupToggler&#039;).css({&lt;br /&gt;
			&#039;padding&#039;:&#039;5px 0 10px 0&#039;,&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).css({&lt;br /&gt;
			&#039;text-decoration&#039;:&#039;underline&#039;,			&lt;br /&gt;
			&#039;cursor&#039;:&#039;pointer&#039;&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Add some hover effects to the show/hide divs&lt;br /&gt;
		$(&amp;quot;.groupToggler span&amp;quot;).hover(&lt;br /&gt;
			function () {&lt;br /&gt;
				$(this).css({&lt;br /&gt;
					&#039;text-decoration&#039;:&#039;none&#039;,&lt;br /&gt;
					&#039;font-weight&#039;:&#039;bold&#039;&lt;br /&gt;
				});&lt;br /&gt;
			}, &lt;br /&gt;
			function () {&lt;br /&gt;
				$(this).css({&lt;br /&gt;
					&#039;text-decoration&#039;:&#039;underline&#039;,&lt;br /&gt;
					&#039;font-weight&#039;:&#039;normal&#039;&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
		);&lt;br /&gt;
		&lt;br /&gt;
		// Initially hide all of the groups&lt;br /&gt;
		// Toggle their visibility when the show/hide is clicked&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).click(function() {&lt;br /&gt;
			$(this).parent().next().toggle();&lt;br /&gt;
			return false;&lt;br /&gt;
		}).parent().next().hide();&lt;br /&gt;
		&lt;br /&gt;
		// Display any groups that have unanswered mandatories&lt;br /&gt;
		$(&#039;.errormandatory&#039;).parents(&#039;div[id^=&amp;quot;group-&amp;quot;]&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Some tidying up&lt;br /&gt;
		$(&#039;h1&#039;).next().next().hide();&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).css({&#039;margin-bottom&#039;:&#039;10px&#039;});&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).next().hide();&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).next().next().hide();&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use jQuery Autocomplete plugin to suggest answers for text inputs=&lt;br /&gt;
&lt;br /&gt;
== 1.90 and previous versions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://docs.jquery.com/Plugins/Autocomplete jQuery Autocomplete] plugin to provide a respondent a list of suggested answers that the they can select from as they type in a text input.&lt;br /&gt;
&lt;br /&gt;
Although the plugin allows for much more complex applications, the two that I use most frequently are outlined below. The first method uses a relatively small list of suggestions that is stored in an array locally. The second is a little more complex - it uses a remote CSV file of suggestions that is accessed through AJAX an PHP.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve put together a small demonstration [http://www.partnersinc.biz/surveys//index.php?sid=78611&amp;amp;newtest=Y&amp;amp;lang=en here] and implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Both methods:&#039;&#039;&#039;&lt;br /&gt;
*[http://docs.jquery.com/Plugins/Autocomplete Download the plugin]&lt;br /&gt;
*Place the files &#039;&#039;jquery.autocomplete.css&#039;&#039; and &#039;&#039;jquery.autocomplete.js&#039;&#039; in your template directory&lt;br /&gt;
*Add the following code inside the &amp;lt;head&amp;gt; element of startpage.pstpl&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autocomplete.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;{TEMPLATEURL}jquery.autocomplete.css&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 1 (&amp;quot;States&amp;quot; question in the demo):&#039;&#039;&#039;&lt;br /&gt;
*Create a text input question&lt;br /&gt;
*Add the following script to the source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace the states with your list of suggestions (comma separated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var q1ID = QQ;&lt;br /&gt;
&lt;br /&gt;
		var states = &amp;quot;Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware, District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky, Louisiana,Maine,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York, North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Maryland,Massachusetts,Michigan, Minnesota,Mississippi,Missouri,Pennsylvania,Rhode Island,South Carolina,South Dakota, Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming&amp;quot;.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.text&#039;).autocomplete(states, {&lt;br /&gt;
			matchContains: true,&lt;br /&gt;
			minChars: 0&lt;br /&gt;
		});&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 2 (&amp;quot;Countries&amp;quot; question in the demo):&#039;&#039;&#039;&lt;br /&gt;
*Place the CSV file of suggestions in your template directory. &lt;br /&gt;
*Place a PHP file containing the code below in your template directory&lt;br /&gt;
*Replace &amp;quot;countries2.csv&amp;quot; with your CSV filename (you could make this more universal by passing the filename in the URL)&lt;br /&gt;
*This file will grab the contents of the CSV and encode them in JSON format that the JavaScript can use&lt;br /&gt;
*Place the JavaScript code below in ths source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace &amp;quot;templates/yourTemplate/countries.php&amp;quot; with the path to the PHP file (from LimeSurvey root)&lt;br /&gt;
*This script will grab the jsonized data from the PHP file and load it into an array that the plugin can use&lt;br /&gt;
&lt;br /&gt;
PHP code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
	$countriesArr = array();&lt;br /&gt;
&lt;br /&gt;
	$file_handle = fopen(&amp;quot;countries2.csv&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	while (!feof($file_handle) ) {&lt;br /&gt;
		$line_of_text = fgetcsv($file_handle);&lt;br /&gt;
		array_push($countriesArr, $line_of_text[0]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose($file_handle);&lt;br /&gt;
&lt;br /&gt;
	echo json_encode($countriesArr);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qID = QQ;&lt;br /&gt;
		var url = &amp;quot;templates/yourTemplate/countries.php&amp;quot;;&lt;br /&gt;
		var countriesArr = new Array();&lt;br /&gt;
&lt;br /&gt;
		$.getJSON(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			$(data).each(function(i, item){&lt;br /&gt;
				countriesArr.push(item);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#question&#039;+qID+&#039; input.text&#039;).autocomplete(countriesArr, {&lt;br /&gt;
				matchContains: true,&lt;br /&gt;
				minChars: 0&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.91 and later versions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://jqueryui.com/demos/autocomplete/ Autocomplete widget] included with jQuery UI to provide a respondent a list of suggested answers that the they can select from as they type in a text input.&lt;br /&gt;
&lt;br /&gt;
Although the plugin allows for much more complex applications, the two that I use most frequently are outlined below. The first method uses a relatively small list of suggestions that is stored in an array locally. The second is a little more complex - it uses a remote CSV file of suggestions that is accessed through AJAX an PHP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Both methods:&#039;&#039;&#039;&lt;br /&gt;
*Add the following styles to the end of your &#039;template.css&#039; file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;/* Autocomplete styles */&lt;br /&gt;
&lt;br /&gt;
ul.ui-autocomplete {&lt;br /&gt;
	width: 250px !important;&lt;br /&gt;
	padding: 5px 10px;&lt;br /&gt;
	list-style: none;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 1 (use local JavaScript array for data):&#039;&#039;&#039;&lt;br /&gt;
*Create a text input question&lt;br /&gt;
*Add the following script to the source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace the states with your list of suggestions (comma separated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var q1ID = QQ;&lt;br /&gt;
&lt;br /&gt;
		var states = &amp;quot;Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware, District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky, Louisiana,Maine,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York, North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Maryland,Massachusetts,Michigan, Minnesota,Mississippi,Missouri,Pennsylvania,Rhode Island,South Carolina,South Dakota, Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming&amp;quot;.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
			source: states&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 2 (use remote CSV file for data):&#039;&#039;&#039;&lt;br /&gt;
*Place the CSV file of suggestions in your template directory&lt;br /&gt;
*Place a PHP file containing the code below in your template directory&lt;br /&gt;
*Replace &amp;quot;countries2.csv&amp;quot; with your CSV filename (you could make this more universal by passing the filename in the URL)&lt;br /&gt;
*This file will grab the contents of the CSV and encode them in JSON format that the JavaScript can use&lt;br /&gt;
*Place the JavaScript code below in ths source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace &amp;quot;templates/yourTemplate/countries.php&amp;quot; with the path to the PHP file (from LimeSurvey root)&lt;br /&gt;
*This script will grab the jsonized data from the PHP file and load it into an array that the plugin can use&lt;br /&gt;
&lt;br /&gt;
PHP code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
	$countriesArr = array();&lt;br /&gt;
&lt;br /&gt;
	$file_handle = fopen(&amp;quot;countries2.csv&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	while (!feof($file_handle) ) {&lt;br /&gt;
		$line_of_text = fgetcsv($file_handle);&lt;br /&gt;
		array_push($countriesArr, $line_of_text[0]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose($file_handle);&lt;br /&gt;
&lt;br /&gt;
	echo json_encode($countriesArr);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qID = QQ;&lt;br /&gt;
		var url = &amp;quot;templates/yourTemplate/countries.php&amp;quot;;&lt;br /&gt;
		var dataArr = [];&lt;br /&gt;
&lt;br /&gt;
		$.getJSON(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			$.each(data,function(i, item){&lt;br /&gt;
				dataArr.push(item);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#question&#039;+qID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
				source: dataArr&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Use autocomplete to populate several fields==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, IE 7/8/9, Firefox 18&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://jqueryui.com/demos/autocomplete/ Autocomplete widget] included with jQuery UI and the [https://code.google.com/p/jquery-csv/source/browse/jquery.csv.js?r=f13189b2550a770ccaa777f1d747bc860b943fe7 jquery.csv.js] plugin to provide a respondent with a list of suggested answers as they type in a text input and then to automatically populate other fields depending on the selection.&lt;br /&gt;
&lt;br /&gt;
For example, if you have 3 questions - &amp;quot;Name&amp;quot;, &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; - you can use this workaround to autocomplete the &amp;quot;Name&amp;quot; question and then the &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; questions can be automatically populated with values associated with the selected name.&lt;br /&gt;
*Download the [https://code.google.com/p/jquery-csv/source/browse/jquery.csv.js?r=f13189b2550a770ccaa777f1d747bc860b943fe7 jquery.csv.js] plugin and place it in your template folder&lt;br /&gt;
*If using LimeSurvey 1.9x, add the following line to your startpage.pstpl BEFORE the tag for template.js, if using 2.x, add it AFTER the {TEMPLATEJS} placeholder&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.csv.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Create your CSV file with 3 columns (name, ID, email) as in this example and place it in your template folder&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Bob,    Bob&#039;s ID,    Bob&#039;s email&lt;br /&gt;
&lt;br /&gt;
Andy,    Andy&#039;s ID,    Andy&#039;s email&lt;br /&gt;
&lt;br /&gt;
Sam,    Sam&#039;s ID,    Sam&#039;s email&lt;br /&gt;
&lt;br /&gt;
Tony,    Tony&#039;s ID,    Tony&#039;s email&lt;br /&gt;
&lt;br /&gt;
Fred,    Fred&#039;s ID,    Fred&#039;s email&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Create your 3 questions - &amp;quot;Name&amp;quot;, &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot;. They must be in the same group/page.&lt;br /&gt;
*Add the following styles to the end of your &#039;template.css&#039; file&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;/* Autocomplete styles */&lt;br /&gt;
&lt;br /&gt;
ul.ui-autocomplete {&lt;br /&gt;
&lt;br /&gt;
   width: 250px !important;&lt;br /&gt;
&lt;br /&gt;
   padding: 5px 10px;&lt;br /&gt;
&lt;br /&gt;
   list-style: none;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Add the following script to the source of one of the questions&lt;br /&gt;
*Replace:&lt;br /&gt;
**&amp;quot;NN&amp;quot; with the &amp;quot;Name&amp;quot; question ID&lt;br /&gt;
**&amp;quot;II&amp;quot; with the &amp;quot;ID&amp;quot; question ID&lt;br /&gt;
**&amp;quot;EE&amp;quot; with the &amp;quot;Email&amp;quot; question ID&lt;br /&gt;
*Modify the path to your CSV file&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qNameID = NN;&lt;br /&gt;
&lt;br /&gt;
		var qIDID = II;&lt;br /&gt;
&lt;br /&gt;
		var qEmailID = EE;&lt;br /&gt;
&lt;br /&gt;
		var url = &amp;quot;upload/templates/yourTemplate/yourCsvFile.csv&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		// Create an array to hold the names&lt;br /&gt;
		var namesArr = new Array();&lt;br /&gt;
&lt;br /&gt;
		// Grab the CSV contents&lt;br /&gt;
		$.get(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			// Convert CSV contents to an array of arrays&lt;br /&gt;
			fullArray = $.csv.toArrays(data);&lt;br /&gt;
&lt;br /&gt;
			// Load the names array&lt;br /&gt;
			$(fullArray).each(function(i, item){&lt;br /&gt;
				namesArr.push(item[0]);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Initialise the autocomplete plugin&lt;br /&gt;
			$(&#039;#question&#039;+qNameID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
				source: namesArr,&lt;br /&gt;
				// Event fired when a selection is made (ui.item.value refers to the selected item)&lt;br /&gt;
				select: function(event, ui) {&lt;br /&gt;
					// Find the &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; values associated with the selected name value and load those questions&lt;br /&gt;
					$(fullArray).each(function(i, item){&lt;br /&gt;
						if(item[0] == ui.item.value) {&lt;br /&gt;
							// The value from column 2 of the CSV&lt;br /&gt;
							$(&#039;#question&#039;+qIDID+&#039; input.text&#039;).val(item[1]);&lt;br /&gt;
							// The value from column 3 of the CSV&lt;br /&gt;
							$(&#039;#question&#039;+qEmailID+&#039; input.text&#039;).val(item[2]);&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Drag and Drop Rankings {{Deprecated|2.0}} =&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }} &lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking - Version 1.90 to 1.92==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+ &amp;amp; 1.91RC4, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }} &lt;br /&gt;
&lt;br /&gt;
This workaround is a modification of the workaround below and also uses [http://jqueryui.com/demos/sortable/#connect-lists JQuery connected sortables]. Thanks to the author of that workaround.&lt;br /&gt;
&lt;br /&gt;
[[File:Untitled-12.png]]&lt;br /&gt;
&lt;br /&gt;
Modifications include:&lt;br /&gt;
*Allow for multiple drag-n-drop ranking questions on a page&lt;br /&gt;
*Handle minimum and maximum answers settings&lt;br /&gt;
*Allow double clicking of items to add or remove them from the ranking list&lt;br /&gt;
*Work with the new shipped jQuery UI&lt;br /&gt;
&lt;br /&gt;
There is a &#039;&#039;&#039;[http://www.partnersinc.biz/surveys//index.php?sid=36981&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the large script below in your template.js file.&lt;br /&gt;
#Place the small script below in the source a ranking question, (this applies the &amp;quot;dragDropRank&amp;quot; function to the question). Replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID].&lt;br /&gt;
**Note: the LimeSurvey translations will be automatically used for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; header labels but can be overridden with custom labels - see the example calls below.&lt;br /&gt;
#Insert the CSS below at the end of template.css (these styles are for the default template).&lt;br /&gt;
&lt;br /&gt;
NOTE: I have not tested this workaround with conditions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code for template.js:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
function dragDropRank(qID, choiceText, rankText) {&lt;br /&gt;
&lt;br /&gt;
	if(!choiceText) {&lt;br /&gt;
		choiceText = $(&#039;#question&#039;+qID+&#039; td.label label&#039;).text();&lt;br /&gt;
	}&lt;br /&gt;
	if(!rankText) {&lt;br /&gt;
		rankText = $(&#039;#question&#039;+qID+&#039; td.output tr:first td:eq(1)&#039;).text();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Add a class to the question&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039;&#039;).addClass(&#039;dragDropRanking&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Hide the original question in LimeSurvey (so that we can replace with drag and drop)&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; .rank, #question&#039;+qID+&#039; .questionhelp&#039;).hide();&lt;br /&gt;
	&lt;br /&gt;
	// Turn off display of question (to override error checking built into LimeSurvey ranking question)&lt;br /&gt;
	//$(&#039;#display&#039;+qID).val(&#039;off&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Add connected sortables elements to the question&lt;br /&gt;
	var htmlCode = &#039;&amp;lt;table class=&amp;quot;dragDropTable&amp;quot;&amp;gt; \&lt;br /&gt;
		&amp;lt;tbody&amp;gt; \&lt;br /&gt;
			&amp;lt;tr&amp;gt; \&lt;br /&gt;
				&amp;lt;td&amp;gt; \&lt;br /&gt;
					&amp;lt;span class=&amp;quot;dragDropHeader choicesLabel&amp;quot;&amp;gt;&#039;+choiceText+&#039;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt; \&lt;br /&gt;
					&amp;lt;div class=&amp;quot;ui-state-highlight dragDropChoices&amp;quot;&amp;gt; \&lt;br /&gt;
						&amp;lt;ul id=&amp;quot;sortable1&#039;+qID+&#039;&amp;quot; class=&amp;quot;connectedSortable&#039;+qID+&#039; dragDropChoiceList&amp;quot;&amp;gt; \&lt;br /&gt;
							&amp;lt;li&amp;gt;Choices&amp;lt;/li&amp;gt; \&lt;br /&gt;
						&amp;lt;/ul&amp;gt; \&lt;br /&gt;
					&amp;lt;/div&amp;gt; \&lt;br /&gt;
				&amp;lt;/td&amp;gt; \&lt;br /&gt;
				&amp;lt;td&amp;gt; \&lt;br /&gt;
					&amp;lt;span class=&amp;quot;dragDropHeader rankingLabel&amp;quot;&amp;gt;&#039;+rankText+&#039;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt; \&lt;br /&gt;
					&amp;lt;div class=&amp;quot;ui-state-highlight dragDropRanks&amp;quot;&amp;gt; \&lt;br /&gt;
						&amp;lt;ol id=&amp;quot;sortable2&#039;+qID+&#039;&amp;quot; class=&amp;quot;connectedSortable&#039;+qID+&#039; dragDropRankList&amp;quot;&amp;gt; \&lt;br /&gt;
							&amp;lt;li&amp;gt;Ranks&amp;lt;/li&amp;gt; \&lt;br /&gt;
						&amp;lt;/ol&amp;gt; \&lt;br /&gt;
					&amp;lt;/div&amp;gt; \&lt;br /&gt;
				&amp;lt;/td&amp;gt; \&lt;br /&gt;
			&amp;lt;/tr&amp;gt; \&lt;br /&gt;
		&amp;lt;/tbody&amp;gt; \&lt;br /&gt;
					&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
	$(htmlCode).insertAfter(&#039;#question&#039;+qID+&#039; table.rank&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Remove placeholder list items (have to have one item so that LimeSurvey doesn&amp;quot;t remove the &amp;lt;ul&amp;gt;)&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li, #sortable2&#039;+qID+&#039; li&#039;).remove();&lt;br /&gt;
	&lt;br /&gt;
	// Load any previously-set values&lt;br /&gt;
	loadDragDropRank(qID);&lt;br /&gt;
	&lt;br /&gt;
	// Find the number of LimeSurvey ranking inputs (&amp;quot;Maximum answers&amp;quot;)&lt;br /&gt;
	var maxAnswer = $(&#039;#question&#039;+qID+&#039; td.output input.text&#039;).length;&lt;br /&gt;
	&lt;br /&gt;
	// Set up the connected sortable&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039;, #sortable2&#039;+qID+&#039;&#039;).sortable({&lt;br /&gt;
		connectWith: &#039;.connectedSortable&#039;+qID+&#039;&#039;,&lt;br /&gt;
		placeholder: &#039;ui-sortable-placeholder&#039;,&lt;br /&gt;
		helper: &#039;clone&#039;,&lt;br /&gt;
		revert: 50,&lt;br /&gt;
		receive: function(event, ui) {&lt;br /&gt;
			if($(&#039;#sortable2&#039;+qID+&#039; li&#039;).length &amp;gt; maxAnswer) {&lt;br /&gt;
				alert (&#039;You can only rank a maximum of &#039;+maxAnswer+&#039; choices.&#039;);&lt;br /&gt;
				$(ui.sender).sortable(&#039;cancel&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		stop: function(event, ui) {&lt;br /&gt;
			$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			updateDragDropRank(qID);&lt;br /&gt;
		}&lt;br /&gt;
	}).disableSelection();&lt;br /&gt;
	&lt;br /&gt;
	// Get the list of choices from the LimeSurvey question and copy them as items into the sortable choices list&lt;br /&gt;
	$(&#039;#CHOICES_&#039; + qID).children().each(function(index, Element) {&lt;br /&gt;
		var liCode = &#039;&amp;lt;li class=&amp;quot;ui-state-default&amp;quot; id=&amp;quot;choice_&#039; + $(this).attr(&amp;quot;value&amp;quot;) + &#039;&amp;quot;&amp;gt;&#039; + this.text + &#039;&amp;lt;/li&amp;gt;&#039;&lt;br /&gt;
		$(liCode).appendTo(&#039;#sortable1&#039;+qID+&#039;&#039;);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Allow users to double click to move to selections from list to list&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li&#039;).live(&#039;dblclick&#039;, function() {&lt;br /&gt;
		if($(&#039;#sortable2&#039;+qID+&#039; li&#039;).length == maxAnswer) {&lt;br /&gt;
			alert (&#039;You can only rank a maximum of &#039;+maxAnswer+&#039; choices.&#039;);&lt;br /&gt;
			return false;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(this).appendTo(&#039;#sortable2&#039;+qID+&#039;&#039;);&lt;br /&gt;
			$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			updateDragDropRank(qID);&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	$(&#039;#sortable2&#039;+qID+&#039; li&#039;).live(&#039;dblclick&#039;, function() {&lt;br /&gt;
		$(this).appendTo(&#039;#sortable1&#039;+qID+&#039;&#039;);&lt;br /&gt;
		$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
		$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
		updateDragDropRank(qID);&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function copies the drag and drop sortable data into the LimeSurvey ranking list.&lt;br /&gt;
function updateDragDropRank(qID) {&lt;br /&gt;
&lt;br /&gt;
	// Reload the LimeSurvey choices select element&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	$(&#039;#sortable2&#039;+qID+&#039; li&#039;).each(function(index) {&lt;br /&gt;
		$(this).attr(&#039;value&#039;, index+1);&lt;br /&gt;
		&lt;br /&gt;
		// Get value of ranked item&lt;br /&gt;
		var liID = $(this).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Save to an array&lt;br /&gt;
		rankees[rankees.length] = { &amp;quot;r_name&amp;quot;:$(this).text(),&amp;quot;r_value&amp;quot;:liIDArray[1] };&lt;br /&gt;
	});&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
		if (rankees.length &amp;gt; index) {&lt;br /&gt;
			$(this).val(rankees[index].r_name);&lt;br /&gt;
			$(this).next(&#039;input&#039;).attr(&#039;value&#039;, rankees[index].r_value);&lt;br /&gt;
		} else {&lt;br /&gt;
			$(this).val(&#039;&#039;);&lt;br /&gt;
			$(this).next().val(&#039;&#039;);&lt;br /&gt;
		}&lt;br /&gt;
	 });&lt;br /&gt;
	 &lt;br /&gt;
	// Reload the LimeSurvey choices select element (we need this for &amp;quot;Minimum answers&amp;quot; code)&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; td.label select option&#039;).remove();&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li&#039;).each(function(index) {&lt;br /&gt;
		var liText = $(this).text();&lt;br /&gt;
		var liID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		var optionCode = &#039;&amp;lt;option value=&amp;quot;&#039;+liIDArray[1]+&#039;&amp;quot;&amp;gt;&#039;+liText+&#039;&amp;lt;/option&amp;gt;&#039;;&lt;br /&gt;
		$(optionCode).appendTo(&#039;#question&#039;+qID+&#039; td.label select&#039;);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Hack for IE6&lt;br /&gt;
	if ($.browser.msie &amp;amp;&amp;amp; $.browser.version.substr(0,1)&amp;lt;7) {&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; select&#039;).show();&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; select&#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function is called on page load to see if there are any items already ranked (from a previous visit&lt;br /&gt;
// or cached due to a page change.  If so, the already-ranked items are loaded into the sortable list&lt;br /&gt;
function loadDragDropRank(qID) {&lt;br /&gt;
&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	&lt;br /&gt;
	// Loop through each item in the built-in LimeSurvey ranking list looking for non-empty values&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;/div&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
	&lt;br /&gt;
		// Check to see if the current item has a value&lt;br /&gt;
		if ($(this).val()) {&lt;br /&gt;
		&lt;br /&gt;
			// Item has a value - save to the array&lt;br /&gt;
			// Use this element to contain the name and the next for the value (numeric)&lt;br /&gt;
			rankees[rankees.length] = { &amp;quot;r_name&amp;quot;:$(this).val(),&amp;quot;r_value&amp;quot;:$(this).next().val() };&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Now that we have a list of all the pre-ranked items, populate the sortable list&lt;br /&gt;
	// Note that the items *won&amp;quot;t* appear in the main list because LimeSurvey has removed them.&lt;br /&gt;
	$.each(rankees, function(index, value) {&lt;br /&gt;
	&lt;br /&gt;
		// Create the items in the sortable&lt;br /&gt;
		var liCode = &#039;&amp;lt;li class=&amp;quot;ui-state-default&amp;quot; id=&amp;quot;choice_&#039; + value.r_value + &#039;&amp;quot;&amp;gt;&#039; + value.r_name + &#039;&amp;lt;/li&amp;gt;&#039;;&lt;br /&gt;
		$(liCode).appendTo(&#039;#sortable2&#039;+qID+&#039;&#039;);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s) using the LimeSurvey translations for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; element header labels&#039;&#039;&#039; (replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRank(QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix for later versions of 1.91+&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In my version of LimeSurvey 1.91+, build 11026, this drag-n-drop workaround was not saving the selections properly. I&#039;m not sure if that&#039;s because of my template, or other jquery uses, but I fixed it by making the following modifications to the above code placed into template.js.&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having problems (and it&#039;s definitely worth testing that the rankings are actually saving into your response table before proceeding with the survey) give this a try.&lt;br /&gt;
&lt;br /&gt;
In the &#039;updateDragDropRank(qID)&#039; function, replace the line:&lt;br /&gt;
&amp;lt;syntaxhighlight  lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name^=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the &#039;loadDragDropRank(qID) function, replace the line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;/div&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name^=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s) using custom text for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; element header labels&#039;&#039;&#039; (replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRank(QQ, &#039;Custom Choices Label&#039;, &#039;Custom Rankings Label&#039;);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Styles for template.css:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
/* Drag-n-drop ranking styles */&lt;br /&gt;
.dragDropTable {&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable td {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	width: 50%;&lt;br /&gt;
	padding-right: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropHeader {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoices,&lt;br /&gt;
.dragDropTable .dragDropRanks {&lt;br /&gt;
	margin: 5px 0 0 0;&lt;br /&gt;
	background: transparent none;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoiceList,&lt;br /&gt;
.dragDropTable .dragDropRankList {&lt;br /&gt;
	float: left;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	min-height: 2.4em;&lt;br /&gt;
	_height: 2.4em; /* IE6 and below hack */&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	list-style-type: none;&lt;br /&gt;
	background: #FBFBFB none;&lt;br /&gt;
	border: 1px solid #CCCCCC;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoiceList li,&lt;br /&gt;
.dragDropTable .dragDropRankList li {&lt;br /&gt;
	margin: 3px;&lt;br /&gt;
	*margin-left: -13px; /* IE7 and below */&lt;br /&gt;
	padding: 3px;&lt;br /&gt;
	min-height: 1.3em;&lt;br /&gt;
	_height: 1.3em; /* IE6 and below hack */&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	cursor: move;&lt;br /&gt;
	display: block; /* Force the li to full width */&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking using Images - Version 1.90 to 1.92==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+ &amp;amp; 1.91RC4, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }}&lt;br /&gt;
&lt;br /&gt;
This workaround works in conjunction with the above workaround to allow ranking of images.&lt;br /&gt;
&lt;br /&gt;
[[File:Untitled-11.png]]&lt;br /&gt;
&lt;br /&gt;
There is a &#039;&#039;&#039;[http://www.partnersinc.biz/surveys//index.php?sid=36981&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
1) Follow the above workaround to get basic drag-n-drop functionality in your ranking question.&lt;br /&gt;
&lt;br /&gt;
2) Insert your images in the ranking question text or help section after any text that you wish to have there (we&#039;ll move them later with JavaScript).&lt;br /&gt;
&lt;br /&gt;
3) Give the images &#039;&#039;&#039;EXACTLY&#039;&#039;&#039; the same IDs as the answer code you would like them to be associated with:[[File:Untitled-8.png]]&lt;br /&gt;
&lt;br /&gt;
4) Place the first script below in your template.js file.&lt;br /&gt;
&lt;br /&gt;
5) Place the second script below in the source the ranking question &#039;&#039;&#039;AFTER&#039;&#039;&#039; the initial call for the dragDropRank function from the workaround above. Replace &amp;quot;QQ&amp;quot; with the ID of the ranking question (this applies the &amp;quot;dragDropRankImages&amp;quot; function to the question).&lt;br /&gt;
&lt;br /&gt;
6) Insert the CSS below at the end of template.css. Replace &amp;quot;11&amp;quot; with your question ID. These styles are for the default template using 50x50px images (as in the demo) and may need to be modified for other templates or image sizes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code for template.js:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function dragDropRankImages(qID) {&lt;br /&gt;
&lt;br /&gt;
	$(&#039;.connectedSortable&#039;+qID+&#039; li&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
		// Remove any text in the sortable choice or rank items&lt;br /&gt;
		$(this).text(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Move the images into the appropriate sortable list item&lt;br /&gt;
		var liID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; img#&#039;+liIDArray[1]+&#039;&#039;).appendTo(this);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRankImages(QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Styles for template.css:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Drag-n-drop for ranking images */&lt;br /&gt;
#question11 .dragDropTable {&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable .dragDropChoiceList,&lt;br /&gt;
#question11 .dragDropTable .dragDropRankList {&lt;br /&gt;
	min-height: 60px;&lt;br /&gt;
	_height: 60px; /* IE6 and below hack */&lt;br /&gt;
	width: auto;&lt;br /&gt;
	min-width: 60px;&lt;br /&gt;
	_width: 60px; /* IE6 and below hack */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable li {&lt;br /&gt;
	background: 0 none;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
	height: 50px;&lt;br /&gt;
	width: 50px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable li img {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking for iPad - Version 1.91 and newer==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LimeSurvey 1.91, iPad 2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround extends the above workarounds to work with the touch interface on iPads.&lt;br /&gt;
&lt;br /&gt;
1) Follow the [[Workarounds: Manipulating a survey at runtime using Javascript#Drag and Drop Ranking - Version 1.90 and newer|Drag and Drop Ranking - Version 1.90 and newer]] workaround above to get basic drag-n-drop functionality in your ranking question.&lt;br /&gt;
&lt;br /&gt;
2) Download the [https://github.com/furf/jquery-ui-touch-punch jQuery.ui.touch-punch.js plugin] and save it in your template directory.&lt;br /&gt;
&lt;br /&gt;
3) Replace this line in your startpage.pstpl:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}template.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;With this:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.ui.touch-punch.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}template.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking - Version 1.86==&lt;br /&gt;
&lt;br /&gt;
Tested with 1.86 on IE 7,8, FireFox 3, Chrome, and Safari 4&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }}&lt;br /&gt;
&lt;br /&gt;
This workaround uses [http://jqueryui.com/demos/sortable/#connect-lists JQuery connected sortables] to modify a ranking question and allow the survey taker to drag and drop choices instead of clicking.  The nice thing is that the choices can be easily re-arranged or removed from the ranking, all by drag and drop.&lt;br /&gt;
&lt;br /&gt;
I used it for a voting application and some of the element names reflect that use.&lt;br /&gt;
&lt;br /&gt;
It looks best when some CSS is added to control the appearance of the boxers around each choice.&lt;br /&gt;
&lt;br /&gt;
[[File:drag-n-drop.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
	// Question ID global variable&lt;br /&gt;
	var questionID;&lt;br /&gt;
	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
	&lt;br /&gt;
		// Grab the question ID[[File:drag-n-drop.png]]&lt;br /&gt;
		// This is something with a class of &amp;quot;ranking&amp;quot; and an ID that starts with &amp;quot;questionXXXXX&amp;quot;.  The X&#039;s represent the question ID&lt;br /&gt;
		var entire_questionID = $(&amp;quot;.ranking[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&#039;question&#039;]&amp;quot;).attr(&#039;id&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Get just the question number (ID)&lt;br /&gt;
		var patt=/\d+$/;&lt;br /&gt;
		questionID=patt.exec(entire_questionID);&lt;br /&gt;
		&lt;br /&gt;
		// Hide the original quetion in LimeSurvey (so that we can replace with drag and drop)&lt;br /&gt;
		$(&amp;quot;.rank, .questionhelp&amp;quot;).hide();&lt;br /&gt;
		&lt;br /&gt;
		// Turn off display of question (to override error checking built into LimeSurvey ranking question)&lt;br /&gt;
		$(&amp;quot;#display&amp;quot;+questionID).val(&amp;quot;off&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Add connected sortables to the question&lt;br /&gt;
		var html_code = &amp;quot;&amp;lt;table style=&#039;border: medium none ; width: 770px; margin-left: auto; \&lt;br /&gt;
								margin-right: auto;&#039;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&#039;width: 590px; vertical-align: top;&#039;&amp;gt;&amp;lt;h3&amp;gt;List of Candidates:&amp;lt;/h3&amp;gt; \&lt;br /&gt;
								&amp;lt;div class=&#039;ui-state-highlight&#039; style=&#039;margin: 5px; float: left;&#039; id=&#039;ballot_list&#039;&amp;gt; \&lt;br /&gt;
								&amp;lt;ul id=&#039;sortable1&#039; class=&#039;connectedSortable&#039;&amp;gt;&amp;lt;li&amp;gt;Candidates&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt; \&lt;br /&gt;
								&amp;lt;td style=&#039;vertical-align: top;&#039;&amp;gt;&amp;lt;h3&amp;gt;Your selections:&amp;lt;/h3&amp;gt;&amp;lt;div class=&#039;ui-state-highlight&#039; \&lt;br /&gt;
								style=&#039;margin: 5px; float: left;&#039; id=&#039;voting_selections&#039;&amp;gt;&amp;lt;ol id=&#039;sortable2&#039; class=&#039;connectedSortable&#039;&amp;gt; \&lt;br /&gt;
								&amp;lt;li&amp;gt;Voting Area&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;;&lt;br /&gt;
		$(html_code).appendTo(&amp;quot;#question&amp;quot; + questionID);&lt;br /&gt;
		&lt;br /&gt;
		// Remove list items (have to have one item so that LimeSurvey doesn&#039;t remove the &amp;lt;ul&amp;gt;)&lt;br /&gt;
		$(&amp;quot;#sortable1 li, #sortable2 li&amp;quot;).remove();&lt;br /&gt;
		&lt;br /&gt;
		// Load any previously-set values&lt;br /&gt;
		loadRanking();&lt;br /&gt;
		&lt;br /&gt;
		// Load jQuery UI&lt;br /&gt;
		$.getScript(&amp;quot;/scripts/jquery/jquery-ui.js&amp;quot;, function() {&lt;br /&gt;
		&lt;br /&gt;
			// After JQuery UI finishes loading, set up the connected sortable.&lt;br /&gt;
			$(&amp;quot;#sortable1, #sortable2&amp;quot;).sortable({&lt;br /&gt;
				connectWith: &#039;.connectedSortable&#039;,&lt;br /&gt;
				placeholder: &#039;ui-sortable-placeholder&#039;,&lt;br /&gt;
				stop: function(event, ui) {&lt;br /&gt;
					$(&amp;quot;#sortable1&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
					$(&amp;quot;#sortable2&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
					updateRanking();&lt;br /&gt;
					}&lt;br /&gt;
			}).disableSelection();&lt;br /&gt;
			&lt;br /&gt;
			// Get the list of candidates from the built-in LimeSurvey question and copy them as items in sortable1&lt;br /&gt;
			$(&amp;quot;#CHOICES_&amp;quot; + questionID).children().each(function(index, Element) {&lt;br /&gt;
				li_tag = &amp;quot;&amp;lt;li class=&#039;ui-state-default&#039; id=&#039;choice_&amp;quot; + $(this).attr(&#039;value&#039;) + &amp;quot;&#039;&amp;gt;&amp;quot; + this.text + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;&lt;br /&gt;
				$(li_tag).appendTo(&amp;quot;#sortable1&amp;quot;); }	);&lt;br /&gt;
				&lt;br /&gt;
			// Make sure the submit button is showing&lt;br /&gt;
			$(&amp;quot;:submit[value|=&#039; Submit&#039;]&amp;quot;).show();&lt;br /&gt;
			&lt;br /&gt;
			// Show a confirmation alert upon submit&lt;br /&gt;
			$(&amp;quot;form&amp;quot;).submit(function() {&lt;br /&gt;
			&lt;br /&gt;
				// Override the built-in &amp;quot;disable navigation buttons&amp;quot; feature&lt;br /&gt;
				$(&#039;#moveprevbtn, #movenextbtn, #movesubmitbtn&#039;).attr(&#039;disabled&#039;, &#039;&#039;);&lt;br /&gt;
				var validated = confirm(&amp;quot;Cast your ballot now?&amp;quot;);&lt;br /&gt;
				if (validated) { return true; } else { return false; }&lt;br /&gt;
			});&lt;br /&gt;
			&lt;br /&gt;
			// Allow users to double click to move to selection list&lt;br /&gt;
			$(&amp;quot;#sortable1 li&amp;quot;).assignDblClick();&lt;br /&gt;
		});  // End of JQuery UI loading&lt;br /&gt;
		&lt;br /&gt;
	}); // End of JQuery ready function&lt;br /&gt;
	&lt;br /&gt;
// Define the actions when an item is double clicked&lt;br /&gt;
$.fn.assignDblClick = function() {&lt;br /&gt;
	$(this).dblclick(function(){&lt;br /&gt;
		$(this).appendTo(&#039;#sortable2&#039;);&lt;br /&gt;
		$(&amp;quot;#sortable1&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
		$(&amp;quot;#sortable2&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
		updateRanking();&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function copies the drag and drop sortable data into the standard LimeSurvey ranking structure.&lt;br /&gt;
function updateRanking() {&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	$(&#039;#sortable2 li&#039;).each(function(index) {&lt;br /&gt;
	$(this).attr(&amp;quot;value&amp;quot;, index+1);&lt;br /&gt;
	&lt;br /&gt;
		// Get value of person&lt;br /&gt;
		li_tag = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		li_tag_array = li_tag.split(&amp;quot;_&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Save to an array&lt;br /&gt;
		rankees[rankees.length] = { &#039;r_name&#039;:$(this).text(),&#039;r_value&#039;:li_tag_array[1] };&lt;br /&gt;
	});&lt;br /&gt;
	$(&amp;quot;input[name&amp;lt;/div&amp;gt;=&#039;RANK_&#039;]&amp;quot;).each(function(index) {&lt;br /&gt;
		if (rankees.length &amp;gt; index) {&lt;br /&gt;
			$(this).val(rankees[index].r_name);&lt;br /&gt;
			$(this).next().val(rankees[index].r_value);&lt;br /&gt;
		} else {&lt;br /&gt;
			$(this).val(&amp;quot;&amp;quot;);&lt;br /&gt;
			$(this).next().val(&amp;quot;&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	 });&lt;br /&gt;
	 &lt;br /&gt;
	// Re-assign double click action to first list items and remove&lt;br /&gt;
	// double click action from section list items&lt;br /&gt;
	$(&#039;#sortable1 li&#039;).unbind(&#039;dblclick&#039;).assignDblClick();&lt;br /&gt;
	$(&#039;#sortable2 li&#039;).unbind(&#039;dblclick&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function is called on page load to see if there are any items already ranked (from a previous visit&lt;br /&gt;
// or cached due to a page change.  If so, the already-ranked items are loaded into the sortable list&lt;br /&gt;
function loadRanking() {&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	&lt;br /&gt;
	// Loop through each item in the built-in LimeSurvey ranking list looking for non-empty values&lt;br /&gt;
	$(&amp;quot;input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&#039;RANK_&#039;]&amp;quot;).each(function(index) {&lt;br /&gt;
	&lt;br /&gt;
		// Check to see if the current item has a value&lt;br /&gt;
		if ($(this).val()) {&lt;br /&gt;
			// Item has a value - save to the array&lt;br /&gt;
			// Use this element to contain the name and the next for the value (numeric)&lt;br /&gt;
			rankees[rankees.length] = { &#039;r_name&#039;:$(this).val(),&#039;r_value&#039;:$(this).next().val() };&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Now that we have a list of all the pre-ranked items, populate the sortable list&lt;br /&gt;
	// Note that the items *won&#039;t* appear in the main list because LimeSurvey has removed them.&lt;br /&gt;
	$.each(rankees, function(index, value) {&lt;br /&gt;
		// Create the items in the sortable&lt;br /&gt;
		li_tag = &amp;quot;&amp;lt;li class=&#039;ui-state-default&#039; id=&#039;choice_&amp;quot; + value.r_value + &amp;quot;&#039;&amp;gt;&amp;quot; + value.r_name + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
		$(li_tag).appendTo(&amp;quot;#sortable2&amp;quot;);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Create MaxDiff question type=&lt;br /&gt;
&lt;br /&gt;
See the [[Workarounds: Question design, layout and templating|Question design, layout and templating]] section for a workaround that uses JavaScript to convert an &#039;&#039;&#039;&#039;&#039;Array (flexible labels) by column&#039;&#039;&#039;&#039;&#039; question into a [http://en.wikipedia.org/wiki/MaxDiff MaxDiff] question type.&lt;br /&gt;
&lt;br /&gt;
[[File:max_diff_596x253.gif]]&lt;br /&gt;
&lt;br /&gt;
=In a checkbox matrix, have the &#039;none&#039; option in a row disable all other columns in that row=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LimeSurvey 1.90+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The questionId parameter is the base ID of the question matrix (multiflexible).&lt;br /&gt;
&lt;br /&gt;
numColumns and numRows speak for themselves&lt;br /&gt;
&lt;br /&gt;
specialColumns is an array of the columns that have the special ability that when one of them&lt;br /&gt;
&lt;br /&gt;
is checked, none of the others can be checked. E.g., a &#039;none of these&#039; and/or a &#039;do now know&#039; option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
numColumns=13;&lt;br /&gt;
&lt;br /&gt;
numRows=18;&lt;br /&gt;
&lt;br /&gt;
questionId=&#039;28417X2X24&#039;;&lt;br /&gt;
&lt;br /&gt;
specialColumns=[1,12,13];&lt;br /&gt;
&lt;br /&gt;
function action(obj){&lt;br /&gt;
&lt;br /&gt;
   locator=obj.id.replace(&#039;cbox_&#039;+questionId, &#039;&#039;).split(&#039;_&#039;);&lt;br /&gt;
&lt;br /&gt;
   row=locator[0];&lt;br /&gt;
&lt;br /&gt;
   column=locator[1];&lt;br /&gt;
&lt;br /&gt;
   //alert(&#039;Action for row,column=&#039;+row+&#039;,&#039;+column);&lt;br /&gt;
&lt;br /&gt;
   my_id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+column+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   if($(my_id).attr(&#039;checked&#039;) == false) {&lt;br /&gt;
&lt;br /&gt;
       for( var i=1; i&amp;lt;=numColumns; i++ ) {&lt;br /&gt;
&lt;br /&gt;
           if(i==column) continue;&lt;br /&gt;
&lt;br /&gt;
           id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;disabled&#039;,false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   } else {&lt;br /&gt;
&lt;br /&gt;
       for( var i=1; i&amp;lt;=numColumns; i++ ) {&lt;br /&gt;
&lt;br /&gt;
           if(i==column) continue;&lt;br /&gt;
&lt;br /&gt;
           id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           aid=&#039;#answer&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           $(aid).val(0);&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;checked&#039;,false);&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;disabled&#039;,true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function customOnLoad(){&lt;br /&gt;
&lt;br /&gt;
   for( var row=1; row&amp;lt;=numRows; row++ ) {&lt;br /&gt;
&lt;br /&gt;
       for( var k=0; k&amp;lt;specialColumns.length; k++ )&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           column=specialColumns[k];&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+column).change(function() {&lt;br /&gt;
&lt;br /&gt;
               action(this);&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
   customOnLoad();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Last Option In Array (Numbers) (Checkboxes) Row Excludes All Others=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 2.05, IE 7-10, Firefox&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to make the last option of each Array (Numbers) (Checkboxes) row exclude all other options in the same row.&lt;br /&gt;
&lt;br /&gt;
The script will uncheck all options in a row if the last option is checked and uncheck the last option in a row if any other options are checked.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following script in the source of the array question.&lt;br /&gt;
&lt;br /&gt;
NOTE: Care should be taken when using this script and conditional questions on the same page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Call the exclude function using question ID&lt;br /&gt;
		excludeOpt ({QID});&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// A function to make the last option in each array row exclusive&lt;br /&gt;
	function excludeOpt (qID) {&lt;br /&gt;
		&lt;br /&gt;
		var thisQuestion = $(&#039;#question&#039;+qID)&lt;br /&gt;
&lt;br /&gt;
		// Add some classes to the checkbox cells&lt;br /&gt;
		$(&#039;table.question tbody td&#039;, thisQuestion).addClass(&#039;normalOpt&#039;);&lt;br /&gt;
		$(&#039;table.question tbody tr&#039;, thisQuestion).each(function(i) {&lt;br /&gt;
			$(&#039;.normalOpt:last&#039;, this).removeClass(&#039;normalOpt&#039;).addClass(&#039;exlusiveOpt&#039;)&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// A listener on the checkbox cells&lt;br /&gt;
		$(&#039;table.question tbody td&#039;, thisQuestion).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Set some vars&lt;br /&gt;
			var thisRow = $(this).closest(&#039;tr&#039;);&lt;br /&gt;
&lt;br /&gt;
			// Uncheck the appropriate boxes in a row&lt;br /&gt;
			if ($(this).hasClass(&#039;normalOpt&#039;)) {&lt;br /&gt;
				$(&#039;.exlusiveOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;.normalOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// A listener on the checkboxes&lt;br /&gt;
		$(&#039;table.question tbody td input[type=checkbox]&#039;, thisQuestion).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Set some vars&lt;br /&gt;
			var thisRow = $(this).closest(&#039;tr&#039;);&lt;br /&gt;
			var thisCell = $(this).closest(&#039;td&#039;);&lt;br /&gt;
&lt;br /&gt;
			// Uncheck the appropriate boxes in a row&lt;br /&gt;
			if ($(thisCell).hasClass(&#039;normalOpt&#039;)) {&lt;br /&gt;
				$(&#039;.exlusiveOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;.normalOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Add Navigation Buttons (Next and Previous) To Top Of Page=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add the following to the end of template.js. It will insert a new div after the progress bar and then insert clones of the nav buttons in the new div.&lt;br /&gt;
&lt;br /&gt;
This example is for the default template in 1.90 or 1.91. The placement of the new div may need to be modified for other templates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Insert a new div after the progress bar&lt;br /&gt;
		$(&#039;&amp;lt;div id=&amp;quot;navigator2&amp;quot; /&amp;gt;&#039;).insertAfter(&#039;#progress-wrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Style the new div&lt;br /&gt;
		$(&#039;#navigator2&#039;).css({&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// Insert clones of the nav buttons in the new div&lt;br /&gt;
		$(&#039;input.submit:eq(0)&#039;).clone().appendTo(&#039;#navigator2&#039;);&lt;br /&gt;
		$(&#039;input.submit:eq(2)&#039;).clone().appendTo(&#039;#navigator2&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Give the new buttons some new IDs&lt;br /&gt;
		$(&#039;#navigator2 input.submit&#039;).each(function(i) {&lt;br /&gt;
			var oldID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
			var newID = oldID + &#039;2&#039;;&lt;br /&gt;
			$(this).attr(&#039;id&#039;, newID)&lt;br /&gt;
		});&lt;br /&gt;
	});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:extra_buttons.png]]&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;add&#039;&#039; an opt out link to your survey=&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.91+, Firefox 5.0&lt;br /&gt;
&lt;br /&gt;
This javascript inserts a link to opt out of the survey above the progress bar.&lt;br /&gt;
&lt;br /&gt;
[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]]&lt;br /&gt;
&lt;br /&gt;
Then insert the following code into to the source of a group description or a question. I used the group description.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt; &amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Find the survey ID&lt;br /&gt;
		if($(&#039;input#fieldnames&#039;).length != 0) {&lt;br /&gt;
			var fieldNames = $(&#039;input#fieldnames&#039;).attr(&#039;value&#039;);&lt;br /&gt;
			var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
			var sID = tmp[0];&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Insert a new div after the progress bar&lt;br /&gt;
		$(&#039;&amp;lt;div id=&amp;quot;optOutLink&amp;quot; /&amp;gt;&#039;).insertBefore(&#039;#progress-wrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Style the new div&lt;br /&gt;
		$(&#039;#optOutLink&#039;).css({&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// Insert opt out url in the new div&lt;br /&gt;
		$(&#039;#optOutLink&#039;).html(&#039;&amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;optout.php?lang=en&amp;amp;sid;=&#039;+sID+&#039;&amp;amp;token;={TOKEN}&amp;quot;&amp;gt;Click here to opt out of this survey.&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;br&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Anonymously track respondents answers across multiple surveys=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+ and 1.92+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to enable tracking of respondents across multiple surveys ensuring anonymity (it does not use tokens).&lt;br /&gt;
&lt;br /&gt;
To do this you have to use this question in all the surveys you want to link respondents answers.&lt;br /&gt;
&lt;br /&gt;
This workaround create an ID by asking some partial personal information (like initials, birth month ...). The ID will be encrypted using a one-way function (in this case SHA-1) and stored in a short text answer.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following code in the source of a short text question.&lt;br /&gt;
#Optional: you can also add other select field to avoid collisions (e.g. for large population sample)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This answers are used to generate your ID. These information will be encrypted, it will not be possible in any case to identify you neither from your answers nor from your ID.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;Initial of your name&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select id=&amp;quot;field1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;A&amp;quot;&amp;gt;A&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;B&amp;quot;&amp;gt;B&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;C&amp;quot;&amp;gt;C&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;D&amp;quot;&amp;gt;D&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;E&amp;quot;&amp;gt;E&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;F&amp;quot;&amp;gt;F&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;G&amp;quot;&amp;gt;G&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;H&amp;quot;&amp;gt;H&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;I&amp;quot;&amp;gt;I&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;J&amp;quot;&amp;gt;J&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;K&amp;quot;&amp;gt;K&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;L&amp;quot;&amp;gt;L&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;M&amp;quot;&amp;gt;M&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;N&amp;quot;&amp;gt;N&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;O&amp;quot;&amp;gt;O&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;P&amp;quot;&amp;gt;P&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Q&amp;quot;&amp;gt;Q&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;R&amp;quot;&amp;gt;R&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;S&amp;quot;&amp;gt;S&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;T&amp;quot;&amp;gt;T&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;U&amp;quot;&amp;gt;U&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;V&amp;quot;&amp;gt;V&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;W&amp;quot;&amp;gt;W&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;X&amp;quot;&amp;gt;X&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Y&amp;quot;&amp;gt;Y&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Z&amp;quot;&amp;gt;Z&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;Your birth month&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select id=&amp;quot;field2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;01&amp;quot;&amp;gt;January&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;02&amp;quot;&amp;gt;February&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;03&amp;quot;&amp;gt;March&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;04&amp;quot;&amp;gt;April&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;05&amp;quot;&amp;gt;May&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;06&amp;quot;&amp;gt;June&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;07&amp;quot;&amp;gt;July&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;08&amp;quot;&amp;gt;August&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;09&amp;quot;&amp;gt;September&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;10&amp;quot;&amp;gt;October&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;11&amp;quot;&amp;gt;November&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;12&amp;quot;&amp;gt;December&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/sha1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   $(&amp;quot;#answer{SGQ}&amp;quot;).attr(&#039;readonly&#039;, &#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
   //$(&amp;quot;#answer{SGQ}&amp;quot;).css(&#039;display&#039;, &#039;none&#039;); //uncomment this line for not displaying the code&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(&#039;#field1, #field2&#039;).bind(&#039;change keyup&#039;, function() {&lt;br /&gt;
&lt;br /&gt;
   if ($(&amp;quot;#field1&amp;quot;).val()==&#039;&#039; || $(&amp;quot;#field2&amp;quot;).val()==&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;#answer{SGQ}&amp;quot;).val(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
   else {&lt;br /&gt;
&lt;br /&gt;
       var sha1 = CryptoJS.algo.SHA1.create();&lt;br /&gt;
&lt;br /&gt;
       sha1.update($(&amp;quot;#field1&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       sha1.update($(&amp;quot;#field2&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       // sha1.update($(&amp;quot;#otherfield&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       var hash = sha1.finalize();&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;#answer{SGQ}&amp;quot;).val(hash);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Check validity of international phone number in subquestion=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, Firefox 8, Chrome 15&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As of version 1.92, you can use the core Validation querstion option to validate multiple short text and array text questions. Any question that fails that validation check will have its background color changed to red.&lt;br /&gt;
&lt;br /&gt;
Note, the below workaround will fail in version 1.92 because it contains a regular expression with curly braces.  However, as described above, support for this feature is now built-in to version 1.92&lt;br /&gt;
&lt;br /&gt;
This workaround uses javascript to check the validity of an international phone number in a subquestion of multiple short text.&lt;br /&gt;
&lt;br /&gt;
Add the following code to the source of your question.&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;NN&amp;quot; with the row number that you want to validate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the phone function with the question ID and the row number&lt;br /&gt;
&lt;br /&gt;
       phoneTest(QQ, NN);&lt;br /&gt;
&lt;br /&gt;
       function phoneTest(qID, inputNum) {&lt;br /&gt;
&lt;br /&gt;
           // Interrupt next/submit function&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               // Some vars - modify as required&lt;br /&gt;
&lt;br /&gt;
               var phoneMatch = /^[0-9,+,(), ,]{1,}(,[0-9]+){0,}$/;&lt;br /&gt;
&lt;br /&gt;
               var msg1 = &#039;Please enter a valid phone number.&#039;;&lt;br /&gt;
&lt;br /&gt;
               // Test the input&lt;br /&gt;
&lt;br /&gt;
               var phoneInput = $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               if(phoneInput != &#039;&#039; &amp;amp;&amp;amp; !phoneMatch.test(phoneInput)) {&lt;br /&gt;
&lt;br /&gt;
                   alert(msg1);&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;pink&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The regex is from: [http://www.regexlib.com/REDetails.aspx?regexp_id=1136 regexlib.com blank]&lt;br /&gt;
&lt;br /&gt;
=Check validity of email address in subquestion=&lt;br /&gt;
&lt;br /&gt;
&#039;Tested with: 1.91+, Firefox 8, Chrome 15&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, you can use the core Validation querstion option to validate multiple short text and array text questions. Any question that fails that validation check will have its background color changed to red.&amp;lt;br /&amp;gt;Note, the below workaround will fail in version 1.92 because it contains a regular expression with curly braces.  However, as described above, support for this feature is now built-in to version 1.92&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses javascript to check the validity of an email address in a subquestion of multiple short text.&lt;br /&gt;
&lt;br /&gt;
Add the following code to the source of your question.&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;NN&amp;quot; with the row number that you want to validate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the email function with the question ID and the row number&lt;br /&gt;
&lt;br /&gt;
       emailTest(QQ, NN);&lt;br /&gt;
&lt;br /&gt;
       function emailTest(qID, inputNum) {&lt;br /&gt;
&lt;br /&gt;
           // Interrupt next/submit function&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               // Some vars - modify as required&lt;br /&gt;
&lt;br /&gt;
               var emailMatch = /^[a-zA-Z0-9\_\-]+[a-zA-Z0-9\.\_\-]*@([a-zA-Z0-9\_\-]+\.)+([a-zA-Z]{2,4}|travel|museum)$/;&lt;br /&gt;
&lt;br /&gt;
               var msg1 = &#039;Please enter a valid email address.&#039;;&lt;br /&gt;
&lt;br /&gt;
               // Test the input&lt;br /&gt;
&lt;br /&gt;
               var emailInput = $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               if(emailInput != &#039;&#039; &amp;amp;&amp;amp; !emailMatch.test(emailInput)) {&lt;br /&gt;
&lt;br /&gt;
                   alert(msg1);&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;pink&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The regex is from: [http://www.regexlib.com/REDetails.aspx?regexp_id=1653 regexlib.com blank]&lt;br /&gt;
&lt;br /&gt;
=Hiding the help-text when it&#039;s empty=&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.91+&lt;br /&gt;
&lt;br /&gt;
I had made a style in my template putting a border around my help-text. To avoid empty help-text to show up (and have lines instead of just &#039;nothing&#039; when there was no help text, I used this piece of code in question.pstpl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                   var questionhelp=&amp;quot;{QUESTIONHELP}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
                   if (questionhelp==&amp;quot;&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
                          document.write(&amp;quot;&amp;quot;);}&lt;br /&gt;
&lt;br /&gt;
                   else {&lt;br /&gt;
&lt;br /&gt;
                   document.write(&#039;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;survey-question-help&amp;quot;&amp;gt;&#039;+ questionhelp +&#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;);}&lt;br /&gt;
&lt;br /&gt;
               &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
it can probably be optimized but it worked for me&lt;br /&gt;
&lt;br /&gt;
=Disable or hide selected fields in a matrix question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+, IE 7/8/9, FireFox 12/13&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
TASK&lt;br /&gt;
&lt;br /&gt;
Hide or disable selected fields in a Matrix, so that users cannot make any input.&lt;br /&gt;
&lt;br /&gt;
(See example, where users should not make input into red framed fields)&lt;br /&gt;
&lt;br /&gt;
[[File:snap035.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Prevent users from input into first two fields (as an example)&lt;br /&gt;
&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
First find the name of the fields you want to hide / disable. In my case I used Firebug with firefox to figure that out.&lt;br /&gt;
&lt;br /&gt;
[[File:snap037.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 2: Figure out the name(s) of the field(s)&lt;br /&gt;
&lt;br /&gt;
Then put the following script-code into the HTML-source code as described above:&lt;br /&gt;
&lt;br /&gt;
Note: you have to change the code to match the names of your fields!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;input[name=&amp;quot;69965X2X10SQ001_SQ001&amp;quot;]&#039;).attr(&#039;disabled&#039;, &#039;disabled&#039;);&lt;br /&gt;
&lt;br /&gt;
       $(&#039;input[name=&amp;quot;69965X2X10SQ001_SQ002&amp;quot;]&#039;).attr(&#039;hidden&#039;, &#039;hidden&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:snap039.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 3: Result: first field is diabled (&amp;quot;greyed out&amp;quot;), second one is completely hidden&lt;br /&gt;
&lt;br /&gt;
I think this way one can apply many other attributes to a field like color etc. But did not try that myself.&lt;br /&gt;
&lt;br /&gt;
Thanks to roB2009 for the input in the forum!&lt;br /&gt;
&lt;br /&gt;
=Add prefix or suffix to question type &amp;quot;Array (Texts)&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
TASK&lt;br /&gt;
&lt;br /&gt;
Add a prefix or suffix to the text fields in questions of the &amp;quot;Array (Texts)&amp;quot; type.&lt;br /&gt;
&lt;br /&gt;
[[File:suffix.png]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Suffix&lt;br /&gt;
&lt;br /&gt;
[[File:prefix.png]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Prefix&lt;br /&gt;
&lt;br /&gt;
SOLUTION&lt;br /&gt;
*Set up your survey to use JavaScript.&lt;br /&gt;
*Add the following script to the source of the array. Replace &amp;quot;12345&amp;quot; with the array question ID and modify the suffixes/prefixes as required.&lt;br /&gt;
*The function call must consist of a question ID followed by the suffixes for each column. Suffixes/Prefixes must be enclosed in quotes and comma separated.&lt;br /&gt;
*In this example question ID 12345 will get an &amp;quot;in &amp;amp;euro;&amp;quot; suffix in the first column and an &amp;quot;in %&amp;quot; in the next 3 columns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the function with the question ID followed by a comma-separated list of suffixes&lt;br /&gt;
&lt;br /&gt;
       addSuffix(12345, &#039;in &amp;amp;euro;&#039;, &#039;in %&#039;, &#039;in %&#039;, &#039;in %&#039;);&lt;br /&gt;
&lt;br /&gt;
       function addSuffix() {&lt;br /&gt;
&lt;br /&gt;
           var qID = $(arguments)[0];&lt;br /&gt;
&lt;br /&gt;
           // Assign some column-specific classes&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+qID+&#039; table.question tbody tr&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
               $(&#039;td&#039;, this).each(function(i){&lt;br /&gt;
&lt;br /&gt;
                   $(this).addClass(&#039;answerCol-&#039;+(i+1)+&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
               });&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Some styling&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+qID+&#039; table.question tbody input[type=&amp;quot;text&amp;quot;]&#039;).css({&lt;br /&gt;
&lt;br /&gt;
               &#039;width&#039;: &#039;50%&#039;&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Insert the suffixes&lt;br /&gt;
&lt;br /&gt;
           $(arguments).each(function(i, val){&lt;br /&gt;
&lt;br /&gt;
               if(i &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).append(val);&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For adding a prefix you need to substitute the following line in the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).append(val);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).prepend(val);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Time question (Date question-like)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to build a Time question just like to the Date one.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Download the file at [http://trentrichardson.com/examples/timepicker/jquery-ui-timepicker-addon.js trentrichardson.com/examples/timepicker/jquery-ui-timepicker-addon.js] and upload it to your survey.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following code in the source of a short text question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;/upload/surveys/{SID}/jquery-ui-timepicker-addon.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer{SGQ}&#039;).timepicker({&lt;br /&gt;
			timeText: &#039;Time&#039;, //here translation&lt;br /&gt;
			hourText: &#039;hour&#039;, //here translation&lt;br /&gt;
			minuteText: &#039;minute&#039;, //here translation&lt;br /&gt;
			closeText: &#039;Done&#039; //here translation&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer{SGQ}&#039;).attr(&#039;readonly&#039;, &#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
		$( &amp;quot;&amp;lt;style&amp;gt;&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-widget-header, .ui-datepicker-current { display:none; }&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }&amp;quot;&lt;br /&gt;
		+&amp;quot; }&amp;quot;&lt;br /&gt;
		+&amp;quot;&amp;lt;/style&amp;gt;&amp;quot;).appendTo( &amp;quot;head&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Calculating date difference=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+ Build 120909&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround explains how calculate difference between two dates (in: days, weeks, months and years) and is based on this [http://ditio.net/2010/05/02/javascript-date-difference-calculation/ resource external].&lt;br /&gt;
&lt;br /&gt;
Requieres 2 groups and &#039;group by group&#039; or &#039;question by question&#039; presentation.&lt;br /&gt;
&lt;br /&gt;
Group 1 (2 date questions)&lt;br /&gt;
*1st question - Question code: &amp;quot;DD&amp;quot;&lt;br /&gt;
*2nd question - Question code: &amp;quot;D2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Group 2&lt;br /&gt;
*1 numerical input question.&lt;br /&gt;
&lt;br /&gt;
This question retrieves the number of days between the 2 dates, and check if D2 is posterior than DD.&lt;br /&gt;
&lt;br /&gt;
All the requiered code have to be added in the source of this numerical question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
Adapted from http://ditio.net/2010/05/02/javascript-date-difference-calculation/&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var DateDiff = {&lt;br /&gt;
&lt;br /&gt;
   inDays: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var t2 = d2.getTime();&lt;br /&gt;
&lt;br /&gt;
       var t1 = d1.getTime();&lt;br /&gt;
&lt;br /&gt;
       return parseInt[[t2-t1)/(24*3600*1000]];&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inWeeks: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var t2 = d2.getTime();&lt;br /&gt;
&lt;br /&gt;
       var t1 = d1.getTime();&lt;br /&gt;
&lt;br /&gt;
       return parseInt[[t2-t1)/(24*3600*1000*7]];&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inMonths: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var d1Y = d1.getFullYear();&lt;br /&gt;
&lt;br /&gt;
       var d2Y = d2.getFullYear();&lt;br /&gt;
&lt;br /&gt;
       var d1M = d1.getMonth();&lt;br /&gt;
&lt;br /&gt;
       var d2M = d2.getMonth();&lt;br /&gt;
&lt;br /&gt;
       return (d2M+12*d2Y)-(d1M+12*d1Y);&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inYears: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       return d2.getFullYear()-d1.getFullYear();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
d1 = new Date({substr(DD,0,4)}, {substr(DD,5,2)}, {substr(DD,8,2)});&lt;br /&gt;
&lt;br /&gt;
d2 = new Date({substr(D2,0,4)}, {substr(D2,5,2)}, {substr(D2,8,2)});&lt;br /&gt;
&lt;br /&gt;
// Displays result&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;days&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inDays(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;weeks&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inWeeks(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;months&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inMonths(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;years&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inYears(d1, d2));&lt;br /&gt;
&lt;br /&gt;
// filled the numerical input with number of days (or nights)&lt;br /&gt;
&lt;br /&gt;
var nDays = +DateDiff.inDays(d1, d2);&lt;br /&gt;
&lt;br /&gt;
    jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;.numeric:eq(0) input.text&amp;quot;).val(nDays);&lt;br /&gt;
&lt;br /&gt;
               $(&amp;quot;.numeric:eq(0) input.text&amp;quot;).attr(&#039;readonly&#039;,&#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
// check if d2 &amp;gt; d1&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#movenextbtn&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#movesubmitbtn&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               if(nDays &amp;gt;= 0){&lt;br /&gt;
&lt;br /&gt;
       // automatic submit (uncomment if needed)&lt;br /&gt;
&lt;br /&gt;
               // document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
               // $(&#039;body&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
               else alert(&amp;quot;Check out date must be posterior than Check in\nPlease return to the previous page and edit your answers&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How to set minDate/maxDate based on other Datequestions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039; tested with Version 2.00+ Build 130708&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
QQ1 and QQ2 are the question identifiers. QQ2 gets as maxDate today and as minDate the date set in QQ1. The onClose event is needed because on document.ready the value of QQ1 is not yet known, although the value of today is.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        &#039;use strict&#039;;&lt;br /&gt;
        var qID1 = QQ1,&lt;br /&gt;
            qID2 = QQ2,&lt;br /&gt;
            q1 = $(&#039;#question&#039; + &#039;QQ1&#039; + &#039; .popupdate&#039;), &lt;br /&gt;
            q2 = $(&#039;#question&#039; + &#039;QQ2&#039; + &#039; .popupdate&#039;);&lt;br /&gt;
	&lt;br /&gt;
        //if q1 loses focus, its value is taken and used as minDate in q2   &lt;br /&gt;
        q1.datepicker(&amp;quot;option&amp;quot;, &amp;quot;onClose&amp;quot;, function (datum){&lt;br /&gt;
            q2.datepicker( &amp;quot;option&amp;quot;, &amp;quot;minDate&amp;quot;, datum );&lt;br /&gt;
        });&lt;br /&gt;
        //q2 gets today as its maxDate&lt;br /&gt;
        q2.datepicker( &#039;option&#039;, &#039;maxDate&#039;, new Date() );&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Remove Question Help if empty=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Version 2.00+ Build 130513&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Change your question.pstpl in your Template Editor so that the line looks like below. I&#039;ve added the ID tag help_{question_number}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;survey-question-help&amp;quot; id=help_{QUESTION_NUMBER}&amp;gt;{QUESTIONHELP}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add the following javascript at the end of question.pstpl. If the contents of the help tag is empty then hide the element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
$(document).ready(function(){&lt;br /&gt;
  if($(&#039;#help_{QUESTION_NUMBER}&#039;).is(&#039;:empty&#039;)){&lt;br /&gt;
  $(&#039;#help_{QUESTION_NUMBER}&#039;).hide();&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Implicit Association Test (IAT)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 2.0, IE 7-10, Firefox, Chrome, iPad&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to insert an IAT interface into an Array (Texts) question. The workaround prompts respondents to assign words or phrases using the &amp;quot;E&amp;quot; or &amp;quot;I&amp;quot; keys. In mobile devices, &amp;quot;E&amp;quot; and &amp;quot;I&amp;quot; buttons are provided.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Iat_1.png]]&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download a [[Media:Demo_IAT_Concept.zip|working template]] and [[Media:Demo_iat_concept.lss|working survey]].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
1) [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
&lt;br /&gt;
2) Create your Array (Texts) with sub-questions as follows:&amp;lt;br /&amp;gt;&lt;br /&gt;
- Y scale - all of your &amp;quot;attribut&amp;quot; words or phrases&amp;lt;br /&amp;gt;&lt;br /&gt;
- X scale - &amp;quot;Key Pressed&amp;quot; and &amp;quot;Elapsed Time (ms)&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Iat_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
3) Insert your association terms and the other text elements for the interface into the Question Help section as depicted below. The text strings must be separated with &amp;quot;double pipes&amp;quot; (||) and you will need to place them in the following order:&amp;lt;br /&amp;gt;&lt;br /&gt;
- Left association term&amp;lt;br /&amp;gt;&lt;br /&gt;
- Right association term&amp;lt;br /&amp;gt;&lt;br /&gt;
- Instructional text&amp;lt;br /&amp;gt;&lt;br /&gt;
- Finished text&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Iat_3.png]]&lt;br /&gt;
&lt;br /&gt;
4) Add the following to the end of template.js:&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// A plugin to insert an IAT interface&lt;br /&gt;
function implicitAssociation(el, showAnswers) {&lt;br /&gt;
		&lt;br /&gt;
	$(el).each(function() {&lt;br /&gt;
			&lt;br /&gt;
		var thisQuestion = $(this);&lt;br /&gt;
		var thisQuestionHelp = $(&#039;img[src$=&amp;quot;help.gif&amp;quot;]&#039;, thisQuestion).parent();&lt;br /&gt;
		var thisQuestionAnswers = $(&#039;table.question&#039;, thisQuestion).parent();&lt;br /&gt;
		var startTime = &#039;&#039;;&lt;br /&gt;
		var endTime = &#039;&#039;;	&lt;br /&gt;
		var agent = navigator.userAgent.toLowerCase();&lt;br /&gt;
		var mobile = false;&lt;br /&gt;
		if( /android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent) ) { // Mobile devices&lt;br /&gt;
			mobile = true;&lt;br /&gt;
		}&lt;br /&gt;
		mobile = true;&lt;br /&gt;
		&lt;br /&gt;
		// Some classes&lt;br /&gt;
		$(thisQuestion).addClass(&#039;iatQuestion&#039;);&lt;br /&gt;
		$(&#039;.subquestion-list&#039;).addClass(&#039;unanswered&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Hide the question help element&lt;br /&gt;
		$(thisQuestionHelp).hide();&lt;br /&gt;
		&lt;br /&gt;
		// Hide the answers&lt;br /&gt;
		if(showAnswers != true) {&lt;br /&gt;
			$(&#039;table.question&#039;, thisQuestion).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Insert IAT display&lt;br /&gt;
		var iatTexts = $(thisQuestionHelp).text().split(&#039;||&#039;);&lt;br /&gt;
		var iatDisplayHTML = &#039;&amp;lt;div class=&amp;quot;iatWrapper&amp;quot;&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatLeftLabel&amp;quot;&amp;gt;&#039;+iatTexts[0]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatRightLabel&amp;quot;&amp;gt;&#039;+iatTexts[1]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatWord&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatInstructions&amp;quot;&amp;gt;&#039;+iatTexts[2]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;div class=&amp;quot;iatMobileButtonWrapper&amp;quot;&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatButton iatLeftButton&amp;quot;&amp;gt;E&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatButton iatRightButton&amp;quot;&amp;gt;I&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div style=&amp;quot;width:100%; clear:both;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
		$(thisQuestionAnswers).prepend(iatDisplayHTML);&lt;br /&gt;
		&lt;br /&gt;
		// Show a word&lt;br /&gt;
		function iatShowWord() {&lt;br /&gt;
			$(&#039;div.iatWord&#039;, thisQuestion).text($(&#039;.subquestion-list.unanswered:first .answertext&#039;, thisQuestion).text());&lt;br /&gt;
			startTime = new Date();&lt;br /&gt;
			&lt;br /&gt;
			$(document).bind(&#039;keypress.iatKeypress&#039;, function(e) {&lt;br /&gt;
				if(e.which == 101 || e.which == 105) {&lt;br /&gt;
					var thisRow = $(&#039;.subquestion-list.unanswered:eq(0)&#039;, thisQuestion);&lt;br /&gt;
					$(thisRow).removeClass(&#039;unanswered&#039;);&lt;br /&gt;
					endTime = new Date();&lt;br /&gt;
					$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(1)&#039;, thisRow).val(endTime.valueOf() - startTime.valueOf());&lt;br /&gt;
					if(e.which == 101) {&lt;br /&gt;
						$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val(&#039;E&#039;);&lt;br /&gt;
					}&lt;br /&gt;
					else {&lt;br /&gt;
						$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val(&#039;I&#039;);&lt;br /&gt;
					}&lt;br /&gt;
					$(document).unbind(&#039;keypress.iatKeypress&#039;);&lt;br /&gt;
					if($(&#039;.subquestion-list.unanswered&#039;, thisQuestion).length &amp;gt; 0) {&lt;br /&gt;
						iatShowWord();&lt;br /&gt;
					}&lt;br /&gt;
					else {&lt;br /&gt;
						$(&#039;.iatLeftLabel, .iatWord, .iatRightLabel, .iatInstructions&#039;, thisQuestion).fadeOut(&#039;slow&#039;, function() {&lt;br /&gt;
							$(&#039;div.iatWord&#039;, thisQuestion).text(iatTexts[3]);&lt;br /&gt;
							$(&#039;.iatWord&#039;, thisQuestion).addClass(&#039;done&#039;).fadeIn(&#039;slow&#039;);&lt;br /&gt;
						});&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		function iatShowWordMobile() {&lt;br /&gt;
			$(&#039;div.iatWord&#039;, thisQuestion).text($(&#039;.subquestion-list.unanswered:first .answertext&#039;, thisQuestion).text());&lt;br /&gt;
			startTime = new Date();&lt;br /&gt;
			&lt;br /&gt;
			$(&#039;.iatButton&#039;, thisQuestion).bind(&#039;click.iatButtonClick&#039;, function(e) {&lt;br /&gt;
				var thisRow = $(&#039;.subquestion-list.unanswered:eq(0)&#039;, thisQuestion);&lt;br /&gt;
				$(thisRow).removeClass(&#039;unanswered&#039;);&lt;br /&gt;
				endTime = new Date();&lt;br /&gt;
				$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(1)&#039;, thisRow).val(endTime.valueOf() - startTime.valueOf());&lt;br /&gt;
				$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val($(this).text());&lt;br /&gt;
				$(&#039;.iatButton&#039;, thisQuestion).unbind(&#039;click.iatButtonClick&#039;);&lt;br /&gt;
				if($(&#039;.subquestion-list.unanswered&#039;, thisQuestion).length &amp;gt; 0) {&lt;br /&gt;
					iatShowWordMobile();&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					$(&#039;.iatLeftLabel, .iatWord, .iatRightLabel, .iatInstructions, .iatMobileButtonWrapper&#039;, thisQuestion).fadeOut(&#039;slow&#039;, function() {&lt;br /&gt;
						$(&#039;div.iatWord&#039;, thisQuestion).text(iatTexts[3]);&lt;br /&gt;
						$(&#039;.iatWord&#039;, thisQuestion).addClass(&#039;done&#039;).fadeIn(&#039;slow&#039;);&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Start the IAT display&lt;br /&gt;
		if(mobile == true) { // Mobile devices&lt;br /&gt;
			$(&#039;.iatMobileButtonWrapper&#039;, thisQuestion).show();&lt;br /&gt;
			$(&#039;.iatButton&#039;, thisQuestion).bind(&#039;click.iatStartMobile&#039;, function(e) {&lt;br /&gt;
				$(&#039;.iatButton&#039;, thisQuestion).unbind(&#039;click.iatStartMobile&#039;);&lt;br /&gt;
				iatShowWordMobile();&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(document).bind(&#039;keypress.iatStart&#039;, function(e) { // Non-mobile devices&lt;br /&gt;
				if(e.which == 101 || e.which == 105) {&lt;br /&gt;
					$(document).unbind(&#039;keypress.iatStart&#039;);&lt;br /&gt;
					iatShowWord();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;5) Add the following to the end of template.css:&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
/* IAT questions */&lt;br /&gt;
&lt;br /&gt;
.iatWrapper {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	width: 600px;&lt;br /&gt;
	height: 300px;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
	background-color: #000000;&lt;br /&gt;
	font-size: 21px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatLeftLabel {&lt;br /&gt;
	float: left;&lt;br /&gt;
	padding: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatRightLabel {&lt;br /&gt;
	float: right;&lt;br /&gt;
	padding: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatWord {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	top: 35%;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	font-size: 36px;&lt;br /&gt;
	color:#0F0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatWord.done {&lt;br /&gt;
	color:#FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatInstructions {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	bottom: 0px;&lt;br /&gt;
	padding-bottom: 10px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatMobileButtonWrapper {&lt;br /&gt;
	display: none;&lt;br /&gt;
	position: relative;&lt;br /&gt;
	width: 600px;&lt;br /&gt;
	font-size: 36px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatButton {&lt;br /&gt;
	float: left;&lt;br /&gt;
	margin: 20px;&lt;br /&gt;
	width: 100px;&lt;br /&gt;
	padding: 2px 0 5px 0;&lt;br /&gt;
	border: 5px solid #999;&lt;br /&gt;
	-moz-border-radius: 10px;&lt;br /&gt;
	-webkit-border-radius: 10px;&lt;br /&gt;
	-khtml-border-radius: 10px;&lt;br /&gt;
	border-radius: 10px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	line-height: normal;&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatLeftButton {&lt;br /&gt;
	float: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatRightButton {&lt;br /&gt;
	float: right;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;6) To apply the plugin, add one of the two scripts below to the question source:&amp;lt;br /&amp;gt;&lt;br /&gt;
- With hidden answer table (for normally activated survey)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Apply the IAT plugin to this question&lt;br /&gt;
		implicitAssociation(&#039;#question{QID}&#039;);&lt;br /&gt;
	});	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
- With visible answer table (for testing purposes)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Apply the IAT plugin to this question&lt;br /&gt;
		implicitAssociation(&#039;#question{QID}&#039;, true);&lt;br /&gt;
	});	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Make multiple choice easier=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with Version 2.00 in Chrome, FF, Safar, IE&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The problem:&lt;br /&gt;
We often have multiple choice question, where the user has to select 4 elements out of 78 possible answers or 3 out of 25 and so on.&lt;br /&gt;
If we use pen and paper version for this questions, we noticed that the participants go through the whole list and if an answer doesn&#039;t suit on the first sight, they cross it out.&lt;br /&gt;
&lt;br /&gt;
The solution:&lt;br /&gt;
The script gives the participant the possibility to cross out this answers in a digital way. The script adds a small &amp;quot;X&amp;quot; before the checkbox. When it is clicked, the label text of the checkbox turns grey.&lt;br /&gt;
(see the attached screenshot for an example)&lt;br /&gt;
&lt;br /&gt;
Here is the script, just add it to help text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
* Small script that adds a &amp;quot;X&amp;quot; before a checkbox. &lt;br /&gt;
* On click the text color of the label of the checkbox turns grey&lt;br /&gt;
* If the user has to choose some answers from many options, he can &amp;quot;delete&amp;quot; answers, that on first sight looks wrong&lt;br /&gt;
* Add the script to the question in Limesurvey (for example within the source code of the help text)&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
//Define the X (standard is a X in capitals)&lt;br /&gt;
var x = &amp;quot;X&amp;quot;;&lt;br /&gt;
css_class = &amp;quot;x&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
/*&lt;br /&gt;
* Define the style of the X&lt;br /&gt;
* Of course you can define the style in the stylesheet - if so, the script ignores the following settings&lt;br /&gt;
* If there is a style, than set style var to 1&lt;br /&gt;
*/&lt;br /&gt;
var style = 0;&lt;br /&gt;
var size = &amp;quot;12px&amp;quot;;&lt;br /&gt;
var weight = &amp;quot;bold&amp;quot;;&lt;br /&gt;
var color = &amp;quot;red&amp;quot;;&lt;br /&gt;
var cursor = &amp;quot;pointer&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
//element type - standard is a span element&lt;br /&gt;
var type = &amp;quot;span&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
//Define the new font color of the checkbox label&lt;br /&gt;
label_color = &amp;quot;#bfbfbf&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
//End of configuration - start of the function&lt;br /&gt;
 &lt;br /&gt;
//Define the element that is added&lt;br /&gt;
if(style == 1) {&lt;br /&gt;
	ele = &amp;quot;&amp;lt;&amp;quot;+type+&amp;quot; class=&#039;&amp;quot;+css_class+&amp;quot;&#039;&amp;gt;&amp;quot;+x+&amp;quot;&amp;lt;/&amp;quot;+type+&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
	ele = &amp;quot;&amp;lt;&amp;quot;+type+&amp;quot; class=&#039;&amp;quot;+css_class+&amp;quot;&#039; style=&#039;font-size:&amp;quot;+size+&amp;quot;; font-weight:&amp;quot;+weight+&amp;quot;; color:&amp;quot;+color+&amp;quot;; cursor:&amp;quot;+cursor+&amp;quot;;&#039;&amp;gt;&amp;quot;+x+&amp;quot;&amp;lt;/&amp;quot;+type+&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
//Get the standard font-color of the used style&lt;br /&gt;
st_color = $(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
//insert the X before the checkboxes&lt;br /&gt;
$(document).ready(function() { &lt;br /&gt;
	$(&amp;quot;li&amp;quot;).each(function(){&lt;br /&gt;
		$(this).prepend(ele);&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
//bind an eventhandler on the X (delegate is used, because Limesurvey uses an old jQuery version)&lt;br /&gt;
var css_class_c = &amp;quot;.&amp;quot;+css_class;&lt;br /&gt;
$(document).delegate(css_class_c,&amp;quot;click&amp;quot;,function() {&lt;br /&gt;
	var color_check = $(this).siblings(&amp;quot;label&amp;quot;).data(&amp;quot;color&amp;quot;);&lt;br /&gt;
	if(color_check != &amp;quot;true&amp;quot;) {&lt;br /&gt;
    	$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,label_color).data(&amp;quot;color&amp;quot;,&amp;quot;true&amp;quot;);&lt;br /&gt;
    	$(this).siblings(&#039;input&#039;).attr(&#039;checked&#039;, false);&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,st_color).data(&amp;quot;color&amp;quot;,&amp;quot;false&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
$(&amp;quot;.checkbox&amp;quot;).click(function () {&lt;br /&gt;
	$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,st_color).data(&amp;quot;color&amp;quot;,&amp;quot;false&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Workarounds:_Manipulating_a_survey_at_runtime_using_Javascript&amp;diff=59825</id>
		<title>Workarounds: Manipulating a survey at runtime using Javascript</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Workarounds:_Manipulating_a_survey_at_runtime_using_Javascript&amp;diff=59825"/>
		<updated>2014-01-16T03:58:01Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: /* Drag and Drop Ranking - Version 1.90 to 1.92 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Often you want to manipulate certain elements of a survey at runtime. The only solution without touching the source code is to use JavaScript or jQuery which is shipped with LimeSurvey. Here are some examples to hide and style elements, validate user input or do calculations at runtime.&lt;br /&gt;
&lt;br /&gt;
Other workarounds can be found at&lt;br /&gt;
* [[Workarounds: Survey behaviour]]&lt;br /&gt;
* [[Workarounds: Question design, layout and templating]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;lt;center&amp;gt;&amp;lt;br /&amp;gt;&#039;&#039;&#039;Please keep in mind that these workarounds are not official LimeSurvey extensions - they are solutions that users have created for themselves.&amp;lt;br /&amp;gt;&amp;lt;span style=&#039;color:#EE0000,#FFFFFF&#039;&amp;gt;Therefore LimeSurvey can&#039;t offer guarantees or support for these solutions.&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;If you have questions, please contact the users that, thankfully, shared their solutions with the community.&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/center&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note:  Version 1.92 implements many new features that make some existing workarounds obsolete.  You can continue to use existing workarounds, but may want to consider switching over to using the new features (since those new features are officially supported, and the workarounds are not).  Please review below for details of which are no longer needed.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Also Note:  Version 1.92&#039;s Expression Manager (EM) may cause some of these work-arounds to fail.  Any custom javascript included as a .js file will be fine.  However, if you in-line your JavaScript code, you must make sure that you have a space after every opening (left) curly brace, and a space before every closing (right) curly brace.  Otherwise, EM will think that the content between the curly braces is something it should parse and understand.  I have fixed all of the work-arounds below that can be fixed (many did not follow those rules).  However, some will continue to break.  If a work-around contains a regular expression which contains curly braces (to indicate a range of repeats of a sub-expression), EM will try to process those curly braces, and thus break your regular expression.  Strategies to continue to support that work-around functionality are discussed below.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;add&#039;&#039; a javascript workaround solution to this Wiki page?=&lt;br /&gt;
&lt;br /&gt;
Well, this is pretty easy. Click the edit icon and create your own headline within the javascript section starting with &amp;quot;&#039;&#039;&#039;!&#039;&#039;&#039;&amp;quot;. Then add a short note about the version you have used when creating your workaround, you can copy/paste this code snippet &amp;lt;nowiki&amp;gt;&#039;&#039;Tested with: (enter LimeSurvey version and maybe browser)&#039;&#039;&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Finally it&#039;s imported to mark all your code with code tags, other wise you might break this page.&lt;br /&gt;
*Start tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
*End tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;use&#039;&#039; Script (eg. JavaScript etc.) in LimeSurvey?=&lt;br /&gt;
&lt;br /&gt;
To use JavaScript within LimeSurvey, the XSS filter must be turned off and the code inserted in the source of a question or a group description.&lt;br /&gt;
*Go to Global settings --&amp;gt; Security and set &amp;quot;Filter HTML for XSS&amp;quot; to &amp;quot;Off&amp;quot;.&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=Adding+A+Question Add a new question]&lt;br /&gt;
* Edit the question and click the &amp;quot;Source&amp;quot; button in the editor toolbar:&lt;br /&gt;
&lt;br /&gt;
   [[File:editor_1.gif]]&lt;br /&gt;
* Enter your script after the question text:&lt;br /&gt;
&lt;br /&gt;
   [[File:editor_2.gif]]&lt;br /&gt;
* Save the question&lt;br /&gt;
&lt;br /&gt;
A simple test to see if JavaScript is enabled is to echo an alert. Use this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good practice to use the jQuery $(document).ready function to prevent the code from executing until the page is fully loaded:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is also good practice to use jslint.com to get a good layout and design (e.q. no cluttering of name space)&lt;br /&gt;
&lt;br /&gt;
=Sum up input values using Javascript=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the sum() function in [[Expression Manager|Expression Manager]].  See this [[Expression Manager HowTos#Calculate assessment values at runtime and store the results in the survey data|HowTo example]].&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Starting in  Version 1.92, you also do no longer need to use SGQA (e.g. 45251X1X5) identifiers. Instead the code &amp;lt;code&amp;gt;{SGQ}&amp;lt;/code&amp;gt; will automatically replaced by the current questions SGQA-codes.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is from a survey that is a invitation to a longer party, when the user clicks to the next page, the calculated results will be shown.&lt;br /&gt;
&lt;br /&gt;
If you wonder what the {INSERTANS:1X6X12} stuff is, look at [http://docs.limesurvey.org/tiki-index.php?page=SGQA+Identifier SGQA identifier] and [[Adding a question#Information from previous answers|Using information from previous answers]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: left&amp;quot;&amp;gt;These are your answers:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;script LANGUAGE=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
partyprice = 3;&lt;br /&gt;
&lt;br /&gt;
beadclothprice = 3;&lt;br /&gt;
&lt;br /&gt;
breakfastprice = 7;&lt;br /&gt;
&lt;br /&gt;
lunchprice = 8;&lt;br /&gt;
&lt;br /&gt;
dinnerprice = 10;&lt;br /&gt;
&lt;br /&gt;
foodtotal = 0;&lt;br /&gt;
&lt;br /&gt;
var isreallytrue = &amp;quot;Yes&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var noanswer = &amp;quot;No answer&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
document.write( &amp;quot;Can you come? = {INSERTANS:45251X1X1}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:45251X1X1}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X3}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X3}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
   partypeople = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   partytotal = partyprice * partypeople;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;It&#039;s {INSERTANS:45251X1X3} persons who will come = &amp;quot; + partytotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X4}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X4}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   beadcloths = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   beadclothtotal = beadclothprice * beadcloths;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;You want to borrow {INSERTANS:45251X1X4} beadcloths = &amp;quot; + beadclothtotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there thursday? = {INSERTANS:45251X1X5}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;On friday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X71}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X71}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   breakfastfriday = parseInt(answer) * breakfastprice;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X72}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X72}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   lunchfriday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X73}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X73}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   dinnerfriday = parseInt(answer)* dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnerfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   foodtotal = breakfastfriday + lunchfriday + dinnerfriday;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there saturday? = {INSERTANS:45251X1X8}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X8}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On saturday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X91}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X91}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       breakfastsaturday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write(&amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X92}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X92}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       lunchsaturday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X93}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X93}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       dinnersaturday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsaturday + lunchsaturday + dinnersaturday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there sunday? = {INSERTANS:45251X1X10}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X10}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On sunday you will have these meals: &amp;lt;br&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X111}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X111}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       breakfastsunday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot;  );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X112}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X112}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       lunchsunday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X113}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X113}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       dinnersunday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersunday + &amp;quot;&amp;amp;euro;&amp;lt;p&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsunday + lunchsunday + dinnersunday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   total = partytotal + beadclothtotal + foodtotal;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&amp;lt;h3&amp;gt;In total it will cost you &amp;quot; + total + &amp;quot;&amp;amp;euro;&amp;lt;/h3&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   Put that sum in this bank account 1234 5678 9012&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/SCRIPT&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Question Validation=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the min/max/equals_num_value attributes (to validate sums), or the em_validation_q function, which lets you refer to other variables when you validate the current question [[Expression Manager|Expression Manager]].  Such validations also work on the current page, and properly handle array_filter and cascading relevance.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround is in case you need to do some validation involving more than one question, it implies a very little JavaScript programming and the use of SGQA Identifiers; this should work on almost any version of LimeSurvey.&lt;br /&gt;
&lt;br /&gt;
Is easy to explain with an example, we need to do a survey of the percentage of males and females and we want to be sure that the sum is 100, to do this follow this steps (the necessary data that is not indicated in these instructions are not important i.e. question codes, etc.):&lt;br /&gt;
#Create a new survey of type &amp;quot;group by group&amp;quot;, set the &amp;quot;Show |&amp;lt;&amp;lt; Prev| button&amp;quot; to yes and note the SID.&lt;br /&gt;
#Add a new group called &amp;quot;Group 1&amp;quot; and note the GID.&lt;br /&gt;
#Add a new question &amp;quot;Percent of males&amp;quot; of type &amp;quot;numeric&amp;quot;, make it mandatory and note the QID (we will refer to this as QID1).&lt;br /&gt;
#Add a new question &amp;quot;Percent of females&amp;quot; of type &amp;quot;numeric&amp;quot;, make it mandatory and note the QID (we will refer to this as QID2).&lt;br /&gt;
#Add a new group called &amp;quot;Group 2&amp;quot;&lt;br /&gt;
#Add a new non mandatory question, here is the trick the question text has to be (be sure to replace the SID, GID, QID1 and QID2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function validation()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   if [[{INSERTANS:SIDXGIDXQID1}+{INSERTANS:SIDXGIDXQID2}) != 100)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     alert(&amp;quot;Your responses don&#039;t sum 100! Check them&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;movelast&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But this will show shortly the question and will jump to the end page, a little weird for the survey taker but works.&lt;br /&gt;
&lt;br /&gt;
This is a proof of concept, and may have some problems, please if you notice something or improve it send me an e-mail to leochaton-limesurvey at yahoo dot com.&lt;br /&gt;
&lt;br /&gt;
This will work for 2 questions that you want to be the same.  Works well for email and confirm email questions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function validation() {&lt;br /&gt;
&lt;br /&gt;
 if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; != &amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
    alert(&amp;quot;Your responses don&#039;t match Check them&amp;quot;); document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
    document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Alternate exit=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using the same idea of the previous post, you can implement an alternate exit of your survey.&lt;br /&gt;
&lt;br /&gt;
This script should be in the first question to be displayed in a next page after the question that should trigger the alternate exit. In this example the question that trigger the alternate exit is a Yes/No question, if the user chooses no, he is redirected to another page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; == &amp;quot;No&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  window.location=&amp;quot;http://www.limesurvey.org&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Custom onload function=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;All browsers&#039;, LimeSurvey 1.70 and up&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
&lt;br /&gt;
This simple workaround describes how to &#039;&#039;&#039;add a custom Javascript code&#039;&#039;&#039; that is triggered right after the page is loaded. It may have numerous applications, especially when you deal with a custom JS/HTML code. It may be used to hide form elements (&amp;lt;input&amp;gt;  tags), make them read-only, display alert messages, etc.&lt;br /&gt;
&lt;br /&gt;
To run any Javascript code right after page load use the Query ready() function. It will be executed when the page is being loaded. For example when you add the following code to one of your question definitions...:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
       alert(&#039;onload alert!&#039;);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...it will display a pop-up message immediately after the page has been loaded.&lt;br /&gt;
&lt;br /&gt;
Some of the applications of this trick I&#039;ve explored are:&lt;br /&gt;
&lt;br /&gt;
a) Hiding the form elements by calling in your Custom_On_Load:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: As of svn build 9755, you can now dynamically reference the questions input fields by using the {SGQ} keyword. You can rewrite the previous example like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer{SGQ}&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
this makes it a little easier when exporting surveys, so you don&#039;t have to worry about manually entering each questions SurveyGroupQuestion ID.&lt;br /&gt;
&lt;br /&gt;
b) Making the elements read only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).readOnly=true;&amp;lt;/syntaxhighlight&amp;gt; where the &amp;quot;answer73166X16X54&amp;quot; structure has been described in one of other workarounds above.&lt;br /&gt;
&lt;br /&gt;
c) For Hiding by a lot of elements by calling in your Customer_On_Load&lt;br /&gt;
&lt;br /&gt;
jQuery searchs in html document for input-fields with radio type, if his answer text empty then do the display css set to none.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
           function() {&lt;br /&gt;
&lt;br /&gt;
             jQuery(&#039;input:radio&#039;).each(&lt;br /&gt;
&lt;br /&gt;
               function() {&lt;br /&gt;
&lt;br /&gt;
                 var s = jQuery(this);&lt;br /&gt;
&lt;br /&gt;
                 var c = s.parent().children(&#039;.answertext&#039;);&lt;br /&gt;
&lt;br /&gt;
                 for(var i=0; i &amp;lt; c.length; i++) {&lt;br /&gt;
&lt;br /&gt;
                   var a = jQuery(c[i]]);&lt;br /&gt;
&lt;br /&gt;
                   if(this.id &amp;lt;/u&amp;gt; a.attr(&#039;for&#039;) &amp;amp;&amp;amp; a.text() == &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
                     s.css({ &#039;display&#039; : &#039;none&#039; });&lt;br /&gt;
&lt;br /&gt;
                     a.css({ &#039;display&#039; : &#039;none&#039; });&lt;br /&gt;
&lt;br /&gt;
                     break;&lt;br /&gt;
&lt;br /&gt;
                   }&lt;br /&gt;
&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
             )&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
         );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advanced usage==&lt;br /&gt;
&lt;br /&gt;
If you want to place global Javascript code using the above jQuery(document).ready function then the best place to do this is the template javascript file template.js. You can edit this file using the template editor. Please be aware that placing it in the template javascript file will make the function available to all surveys using that template. If needed just create a new template copy for your survey.&lt;br /&gt;
&lt;br /&gt;
Alternatively you can place the jQuery(document).ready function in the group description to make a Javascript function only available to a certain question group.&lt;br /&gt;
&lt;br /&gt;
==Language-specific Javascript code==&lt;br /&gt;
&lt;br /&gt;
There is an easy way to find out the current language and execute according Javascript using jQuery: The &amp;lt;html&amp;gt; tag of any survey pages contains an &#039;lang&#039; attribute which holds the current language code. You can read that language code by using the followin code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
       languagecode=$(&#039;html&#039;).attr(&#039;lang&#039;);&lt;br /&gt;
&lt;br /&gt;
       alert(&#039;This is the current language code: &#039;+languagecode);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an English survey the above code would show a messagebox with &amp;quot;This is the current language code: en&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Custom onload function in multi-language survey=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use custom onload functions, as above, in multi-language surveys you must define the functions in the question source for &#039;&#039;&#039;all&#039;&#039;&#039; languages.&lt;br /&gt;
&lt;br /&gt;
While this initially seems to be a bit tedious, it actually can be useful - you can alter your onload functions depending on the language in use. For example, you can dynamically display alerts or element contents in the current language.&lt;br /&gt;
&lt;br /&gt;
=Skipping the welcome page=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85 (second code snippet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: As of version 1.91, there is a survey option letting you skip the welcome page, so this workaround is not needed.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 1:&#039;&#039;&#039; Include this Javascript in your welcome template, in the file welcome.pstpl for all welcome page, or in the source of the welcome text for one survey:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function($) {&lt;br /&gt;
&lt;br /&gt;
document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
document.limesurvey.submit(); });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will reproduce the onclick event of the submit button and submit the form.&lt;br /&gt;
&lt;br /&gt;
Drawback of course is that users will see the page flashing up.&lt;br /&gt;
&lt;br /&gt;
Therefore, you may want to announce &amp;quot;... loading survey ...&amp;quot; as a description of your welcome page (in the admin interface when creating the survey), to pretend loading something big.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 2:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function custom_on_load(){&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
window.setTimeout( &#039;custom_on_load()&#039;,1);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Filter answers of a question with the answer of another=&lt;br /&gt;
&lt;br /&gt;
===Method 1===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.70 - 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the the array_filter attribute, or relevance equations in general.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to filter the answer of a question with another answer, you can use this workaround.&lt;br /&gt;
&lt;br /&gt;
First, use answer code like that: XX for the first question, and XXYYY for the second one.&lt;br /&gt;
&lt;br /&gt;
Answer of the second question filter if the 2 first letters are the answer of the first question.&lt;br /&gt;
&lt;br /&gt;
We use 1000X1X1 and 1000X1X2 for the example, question had to be on separate page (question by question for example).The second question had to be a dropdown list (we can do similar workaround, but droplis is the best). You can do this using JQuery.  It leaves the answer in the select box, but disables it.  You could also replace &amp;quot;disable&amp;quot; with &amp;quot;remove&amp;quot; to get rid of it altogether.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var previousQuestionAnswer = &amp;quot;{INSERTANS:1000X1X1}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var currentQuestionID = &amp;quot;#answer1000X1X1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // See if the answer for the previous question matches an answer in the current question&lt;br /&gt;
&lt;br /&gt;
   // (other than &#039;No Answer&#039;)&lt;br /&gt;
&lt;br /&gt;
   // If so, disable it.&lt;br /&gt;
&lt;br /&gt;
   if (previousQuestionAnswer!=&#039;No Answer&#039;) {&lt;br /&gt;
&lt;br /&gt;
       $(currentQuestionID).children().each(function(index, Element)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           if ($(this).attr(&#039;text&#039;) == previousQuestionAnswer)&lt;br /&gt;
&lt;br /&gt;
               { $(this).attr(&#039;disabled&#039;, true); }&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       );}&lt;br /&gt;
&lt;br /&gt;
}); // End of JQuery ready function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Method 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with 1.92 + Firefox 9.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you have a country, state, and city set of questions (or similar), you could code answer options as:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1 Country&#039;&#039;&#039; &#039;&#039;Single choice list (ratio, dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
X country#&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2 State&#039;&#039;&#039; &#039;&#039;Single choice list (dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
XY state#&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3 City&#039;&#039;&#039; &#039;&#039;Single choice list (dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
XYZZ city#&lt;br /&gt;
&lt;br /&gt;
Now you must put the following Javascript code in the source of question 2 (State):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Get the countryCode (first character of the country)&lt;br /&gt;
&lt;br /&gt;
       var countryCode = &#039;{INSERTANS:1000X1X1}&#039;.substr(0, 1).toUpperCase();&lt;br /&gt;
&lt;br /&gt;
       // Loop through all dropdown options and remove those with codes not starting with the countryCode&lt;br /&gt;
&lt;br /&gt;
       $(&#039;select[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;answer&amp;quot;] option&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
           if($(this).attr(&#039;value&#039;)  &amp;amp;&amp;amp; $(this).attr(&#039;value&#039;).substr(0, 1).toUpperCase() != countryCode) {&lt;br /&gt;
&lt;br /&gt;
               $(this).remove();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the following code in the source of question 3 (City):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Get the stateCode (two first characters of the state)&lt;br /&gt;
&lt;br /&gt;
       var stateCode = &#039;{INSERTANS:1000X1X2}&#039;.substr(0, 2).toUpperCase();&lt;br /&gt;
&lt;br /&gt;
       // Loop through all dropdown options and remove those with codes not starting with the stateCode&lt;br /&gt;
&lt;br /&gt;
       $(&#039;select[id&amp;lt;/div&amp;gt;=&amp;quot;answer&amp;quot;] option&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
           if($(this).attr(&#039;value&#039;)  &amp;amp;&amp;amp; $(this).attr(&#039;value&#039;).substr(0, 2).toUpperCase() != stateCode) {&lt;br /&gt;
&lt;br /&gt;
               $(this).remove();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each question must be in different pages of survey to work, i.e. in a question by question survey, or in diferent groups in a group by group survey.&lt;br /&gt;
&lt;br /&gt;
Note that if you choose a two characters answer option code in the State question, i.e. a XYY answer option code, you must change the &#039;&#039;substr(0, 2)&#039;&#039; part of code in question 3 to &#039;&#039;substr(0, 3)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Filter answers of a multiple numeric type question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the the array_filter attribute, or relevance equations in general.  In 1.92, array_filter works with all questions that have sub-questions (e.g. also works for multiple numeric and multiple short text).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to filter a question of type &amp;quot;multiple numeric&amp;quot;, you have to modify the workaround.&lt;br /&gt;
&lt;br /&gt;
Note that this workaround assumes that the code for each of the subquestions are a numeric sequence 1,2,3...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
   // Match elements with labels using htmlFor and a loop&lt;br /&gt;
&lt;br /&gt;
   var labels = document.getElementsByTagName(&#039;LABEL&#039;);&lt;br /&gt;
&lt;br /&gt;
   for (var i = 0; i &amp;lt; labels.length; i++) {&lt;br /&gt;
&lt;br /&gt;
       if (labels[i].htmlFor != &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
            var elem = document.getElementById(labels[i].htmlFor);&lt;br /&gt;
&lt;br /&gt;
            if (elem)&lt;br /&gt;
&lt;br /&gt;
               elem.label = labels[i];&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   var answerFilter=&amp;quot;{INSERTANS:96553X63X759}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   for (i=0; i&amp;lt;30; i++){&lt;br /&gt;
&lt;br /&gt;
     var iLabel = document.getElementById(&#039;answer96553X63X760&#039;+(i+1]].label.innerHTML;&lt;br /&gt;
&lt;br /&gt;
     if (answerFilter.search(iLabel) == -1){&lt;br /&gt;
&lt;br /&gt;
       // Hide element&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question760&#039;).find(&#039;li&#039;).eq(i).hide();&lt;br /&gt;
&lt;br /&gt;
       // Set value of hidden elements to zero&lt;br /&gt;
&lt;br /&gt;
       document.getElementById(&#039;answer96553X63X760&#039;+(i+1)).value = 0;&lt;br /&gt;
&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 });&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use an answer to prefill another question (default value)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;And tested with: 1.91+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the enhanced defaults feature, which lets you pre-fill most question types with default values.  In 1.91, you could set defaults for list and multiple choice questions.  In 1.92, you can set defaults for any text-entry question too.  Moreover, the defaults can be [[Expression Manager|Expression Manager]] compatible equations or tailored text.  Finally, with 1.92, defaults are properly managed even when set on the same page.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround gives you the ablility to use an answer to fill the default value for another question. It&#039;s explained for free text question type but can be adapted for another question type.&lt;br /&gt;
&lt;br /&gt;
We use SGQA identifier. For example, we use SGQA 1000X10X20 and 1000X10X21 to prefill 1000X11X30 and 1000X11X31. For the script to work, the question has to be on a different page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X11X30&#039;).val(&#039;{INSERTANS:1000X10X20}&#039;);&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X11X31&#039;).val(&#039;{INSERTANS:1000X10X21}&#039;);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want use two times the value of an integer input, you can also use this to prefill a question that you hide via CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X2X2&#039;).val(parseInt(&#039;{INSERTANS:1000X1X1}&#039;)*2);&lt;br /&gt;
&lt;br /&gt;
 $(&amp;quot;#question2&amp;quot;).hide();&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use {INSERTANS:1000X2X2} for giving you twice the value of the user input from question 1.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Sum=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do with [[Expression Manager|Expression Manager]] using the sum() function.  Not only will sums be dynamic, but they wille exclude irrelevant values, so you can array_filter a multiple numeric question and get the sum of just the answers that are visible.  This [[Expression Manager HowTos#Calculate assessment values at runtime and store the results in the survey data|HowTo example]] demonstrates the dynamic sum feature.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Also note, as of version 1.92, the following workaround will fail, since it includes a a regular expression containing curly braces.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script is used with a &amp;quot;Multiple Options&amp;quot; type question calculate a total price based on how which checkboxes are selected. The prices are listed as part of the answer. The answers are set up like this: &amp;quot;USB Mouse ($20)&amp;quot;. The script uses the number between the &amp;quot;($&amp;quot; and the &amp;quot;)&amp;quot; as the price for that item. You can adapt the script to if you need to change the currency or need to sum something other than money.&lt;br /&gt;
&lt;br /&gt;
This script works when used in a question-by-question format.  It does not work when there are more than one question on a page. I think it can be adapted to work, but I haven&#039;t done the coding yet.&lt;br /&gt;
&lt;br /&gt;
Put the following code into body of your question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script language=Javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// General definitions&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match the labels containing information about an answer&lt;br /&gt;
&lt;br /&gt;
// In LimeSurvey, these labels start with &amp;quot;answer...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
var answerRegex = /^answer/;&lt;br /&gt;
&lt;br /&gt;
// Find all answer checkboxes in the document and set their&lt;br /&gt;
&lt;br /&gt;
// onchange events to updatePrice&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   // Find all input elements&lt;br /&gt;
&lt;br /&gt;
   var inputList=document.getElementsByTagName(&amp;quot;input&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   // Loop through each, looking for checkboxes&lt;br /&gt;
&lt;br /&gt;
   var i;&lt;br /&gt;
&lt;br /&gt;
   for( i=0; i&amp;lt; inputList.length;i++ )&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // If input item does not have an ID, skip&lt;br /&gt;
&lt;br /&gt;
       if (! (inputList[i].id)) { continue; }&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if ID doesn&#039;t start with &amp;quot;answer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
       if (!answerRegex.test(inputList[i].id)) { continue; }&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if not a checkbox&lt;br /&gt;
&lt;br /&gt;
       if (inputList[i].type.toUpperCase()!=&#039;CHECKBOX&#039;)  { continue; }&lt;br /&gt;
&lt;br /&gt;
       // This is an answer checkbox!&lt;br /&gt;
&lt;br /&gt;
       // Setup onchange event&lt;br /&gt;
&lt;br /&gt;
       inputList[i].onclick = updatePrice;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Load initial sum&lt;br /&gt;
&lt;br /&gt;
   updatePrice();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function updatePrice()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
var labels=document.getElementsByTagName(&amp;quot;LABEL&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match a price inside parenthesis&lt;br /&gt;
&lt;br /&gt;
// For example: ($29) or ($29.54).&lt;br /&gt;
&lt;br /&gt;
// Set up&lt;br /&gt;
&lt;br /&gt;
priceRegex = /\(\$(\d*\.{0,1}\d+)\)/;&lt;br /&gt;
&lt;br /&gt;
// Loop through all the labels, looking for labels corresponding to&lt;br /&gt;
&lt;br /&gt;
// answers that have a price in them.&lt;br /&gt;
&lt;br /&gt;
var i;&lt;br /&gt;
&lt;br /&gt;
var total = 0;&lt;br /&gt;
&lt;br /&gt;
for( i=0; i&amp;lt;labels.length;i++ )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   var myArray;    // Define array used for regex matching&lt;br /&gt;
&lt;br /&gt;
   var inputID;    // Define field element&lt;br /&gt;
&lt;br /&gt;
   // Get the ID of the field corresponding to the label using the&lt;br /&gt;
&lt;br /&gt;
   // &amp;quot;htmlFor&amp;quot; attribute&lt;br /&gt;
&lt;br /&gt;
   // (FYI, there are some labels that will have to be screened out&lt;br /&gt;
&lt;br /&gt;
   // because they don&#039;t correspond to an answer)&lt;br /&gt;
&lt;br /&gt;
   // Does the label start with &amp;quot;answer&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
   // If not: exit.&lt;br /&gt;
&lt;br /&gt;
   if (!answerRegex.test(labels[i].htmlFor)) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // First make sure this element exists&lt;br /&gt;
&lt;br /&gt;
   // If it doesn&#039;t, go to the next element&lt;br /&gt;
&lt;br /&gt;
   // If it does, it will be defined in inputID&lt;br /&gt;
&lt;br /&gt;
   if (! (inputID = document.getElementById(labels[i].htmlFor)) ) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // See if the corresponding answer is a checkbox that is checked.&lt;br /&gt;
&lt;br /&gt;
   // If not, go to next label&lt;br /&gt;
&lt;br /&gt;
   if (inputID.type.toUpperCase()!=&#039;CHECKBOX&#039;)  { continue; }&lt;br /&gt;
&lt;br /&gt;
   if (!inputID.checked) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // This is label for an answer.&lt;br /&gt;
&lt;br /&gt;
   // The innerHTML will give us the text of the label&lt;br /&gt;
&lt;br /&gt;
   // The price information will be in the form ($XX.XX)&lt;br /&gt;
&lt;br /&gt;
   // which in contained in the label text.&lt;br /&gt;
&lt;br /&gt;
   // Find a match for a decimal number inside the pattern &amp;quot;($&amp;quot; and &amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   if [[myArray = priceRegex.exec(labels[i].innerHTML]] != null)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // Keep a running tally&lt;br /&gt;
&lt;br /&gt;
       total += parseFloat(myArray[1]);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // Update total price on form&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&amp;quot;totalPrice&amp;quot;).value = &amp;quot;$&amp;quot; + formatCurrency(total);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function formatCurrency(num) {&lt;br /&gt;
&lt;br /&gt;
  num = isNaN(num) || num &amp;lt;u&amp;gt; &#039;&#039; || num &amp;lt;/u&amp;gt; null ? 0.00 : num;&lt;br /&gt;
&lt;br /&gt;
  return parseFloat(num).toFixed(2);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put the following code in the help section (or wherever you want the sum to appear):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Total Cost for selected accessories: &amp;lt;input type=&amp;quot;readonly&amp;quot; value=&amp;quot;&amp;quot; id=&amp;quot;totalPrice&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Focus on the first Input field=&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: LimeSurvey 1.80 / IE6/7, Firefox 3, Safari, Opera, chrome&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.91, there is a built-in JavaScript function called  focusFirst() to focus on the first visible element.  It uses jQuery, so is more robust than this example.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again an onload Function is needed for this tasks. I have done it the DOM way with compatibility to IE6/7.&lt;br /&gt;
&lt;br /&gt;
Put the following code into the startpage.pstpl of your template, right before the &amp;lt;/head&amp;gt; closing tag:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   function focusFirst(Event)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       var i=0;&lt;br /&gt;
&lt;br /&gt;
       while(document.forms[0].elements[i].type == &amp;quot;hidden&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           i++;&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       document.forms[0].elements[i].focus();&lt;br /&gt;
&lt;br /&gt;
       return;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(ie)&lt;br /&gt;
&lt;br /&gt;
   { window.attachEvent(&amp;quot;onload&amp;quot;, focusFirst); }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   { document.addEventListener(&amp;quot;load&amp;quot;, focusFirst, true); }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; I am using this with version 1.80. As changes happened to the templates in the last release, you might need to add the following before the code, if your template is older than 1.80 stable and does not include this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   var ie = false;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will need this for the var ie to be set. Without this var, the function will not work with ie.&lt;br /&gt;
&lt;br /&gt;
=Answer questions by keypress=&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: IE7, Firefox 3&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
This workaround allow to answer the question on key 0-9 (0 is for the 10 answer).&lt;br /&gt;
&lt;br /&gt;
Follow issues are supported at the moment:&lt;br /&gt;
*Yes-No Questions&lt;br /&gt;
*List Questions (radio)&lt;br /&gt;
*other radio questions&lt;br /&gt;
&lt;br /&gt;
In lists the answer limit is ten.&lt;br /&gt;
&lt;br /&gt;
You supply the template &amp;quot;endpage&amp;quot; of your template with the following script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   jQuery(document).bind(&#039;keypress&#039;, function(e){&lt;br /&gt;
&lt;br /&gt;
       if (48 &amp;lt;= e.which &amp;amp;&amp;amp; e.which &amp;lt;= 57) {&lt;br /&gt;
&lt;br /&gt;
           jQuery(&#039;input:radio&#039;).each(function() {&lt;br /&gt;
&lt;br /&gt;
               var v = jQuery(this).val();&lt;br /&gt;
&lt;br /&gt;
               var c = (e.which &amp;lt;u&amp;gt; 48) ? 10 : e.which - 48;&lt;br /&gt;
&lt;br /&gt;
               if(v &amp;lt;/u&amp;gt; &#039;Y&#039; || v &amp;lt;u&amp;gt; &#039;N&#039;) {&lt;br /&gt;
&lt;br /&gt;
                   v = (v &amp;lt;/u&amp;gt; &#039;Y&#039;) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               if(v == c) {&lt;br /&gt;
&lt;br /&gt;
                   jQuery(this).click();&lt;br /&gt;
&lt;br /&gt;
                   jQuery(&#039;#limesurvey input:submit&#039;).click();&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   })&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Math notation in LimeSurvey=&lt;br /&gt;
#download the js file from [http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html AsciiMath script]&lt;br /&gt;
#copy it in the /scripts/ folder in your installation&lt;br /&gt;
#modify the startpage.psptl of the template you want to use adding the reference to the script (if you use an older version make sure that you copy the template folder first!) for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;ASCIIMathML.js&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the notation where you need it!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you use internet explorer or safari you will need to download the plugin as well, but firefox does the lot for you.&lt;br /&gt;
&lt;br /&gt;
Finally, if you are confident with the limesurvey structure you could add the editor which support math notation and change the reference to the editor you want to use in the configuration file. here is the [http://www.imathas.com/editordemo/demo.html link for a TinyMCE with math support].&lt;br /&gt;
&lt;br /&gt;
=Reverse array_filter (for pre-1.90)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Version 1.91 natively supports this functionality via the array_filter_exclude advanced quation option.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used to filter the answers of an array question to be displayed based on the answers of a multi option question that were &#039;&#039;&#039;NOT&#039;&#039;&#039; selected. A possible application would be to have a multi-option question asking which products were purchased, followed by 2 array questions - one asking to rate the purchased products and another asking why the remaining products were not purchased. Another would be to ask about sessions attended at a conference as in [http://www.limesurvey.org/en/forum/5-can-i-do-this-with-limesurvey/27970-reverse-of-arrayfilter.html this forum thread] and pictured below. There is a live [http://www.partnersinc.biz/surveys//index.php?sid=43358&amp;amp;newtest=Y&amp;amp;lang=en demo here]&lt;br /&gt;
&lt;br /&gt;
[[File:sessions_645x344.gif]]&lt;br /&gt;
&lt;br /&gt;
We&#039;ll use the above example to explain the process as follows:&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsAttended&#039;&#039; multi-options question&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsNotAttended&#039;&#039; multi-options question with identical answers as &#039;&#039;SessionsAttended&#039;&#039; and hide it with styles or conditions&lt;br /&gt;
#In group 2 - Create a &#039;&#039;RateSessionsAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsAttended&#039;&#039;&lt;br /&gt;
#In group 2 - Create a &#039;&#039;ReasonNotAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsNotAttended&#039;&#039;&lt;br /&gt;
#In group 1 - Place JavaScript/jQeury listeners on each of the checkboxes in &#039;&#039;SessionsAttended&#039;&#039; that would toggle the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
&lt;br /&gt;
The JavaScript/jQuery code used would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       // The toggle function&lt;br /&gt;
&lt;br /&gt;
   function toggle(q1, q2) {&lt;br /&gt;
&lt;br /&gt;
       if ($(q1).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       else {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Initialize the SessionNotAttended checkboxes to &amp;quot;checked&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   // The jQuery listeners on the SessionAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   // that toggle the SessionNotAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X331&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X332&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X333&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X334&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some notes about the code:&lt;br /&gt;
*The code is in an onload function defined in the first question of group 1 - see [[Workarounds#Custom_onload_function|here]]&lt;br /&gt;
*Both &#039;&#039;SessionsAttended&#039;&#039; and &#039;&#039;SessionsNotAttended&#039;&#039; must be in the same group for the toggling to work&lt;br /&gt;
*This case only uses 4 checkboxes but could be expanded as required&lt;br /&gt;
*In this case the survey ID is 11111, the group ID is 22, &#039;&#039;SessionsAttended&#039;&#039; ID is 33 and SessionsNotAttended ID is 44 - these would need to be modified for your survey&lt;br /&gt;
*The toggle function looks for the state of a checkbox in &#039;&#039;SessionsAttended&#039;&#039; and sets the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
*The &amp;quot;Initialize&amp;quot; section sets the state of &#039;&#039;SessionsNotAttended&#039;&#039; checkboxes whenever we navigate to the group&lt;br /&gt;
*The &amp;quot;Listener&amp;quot; section uses jQuery listeners to detect any change in the &#039;&#039;SessionsAttended&#039;&#039; checkboxes and then toggle the corresponding &#039;&#039;SessionsNotAttended&#039;&#039; checkbox&lt;br /&gt;
&lt;br /&gt;
Some general notes about the questions:&lt;br /&gt;
*CSS can be used to hide &#039;&#039;SessionsNotAttended&#039;&#039; (div#question44 { display: none; }) if you don&#039;t want to use conditions (because maybe you&#039;ve got [[Optional settings#Survey Behavior|$deletenonvalues set to 1]])&lt;br /&gt;
*&#039;&#039;RateSessionsAttended&#039;&#039; and &#039;&#039;ReasonNotAttended&#039;&#039; are another group to avoid things popping in and out of existence as &#039;&#039;SessionsAttended&#039;&#039; is answered&lt;br /&gt;
*[[Setting conditions|Conditions]] are used to ensure that &#039;&#039;RateSessionsAttended&#039;&#039; only appears if some sessions are selected and &#039;&#039;ReasonNotAttended&#039;&#039; only appears if no sessions are selected&lt;br /&gt;
&lt;br /&gt;
=Filter Ranking Question With Multiple-Options (pre 1.92)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90, IE 7/8, FireFox 3/4, Safari 5.0, Chrome 10.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, most of this is easier to do using the the array_filter attribute, or relevance equations in general.  They all work on the same page, and fully support cascading relevance.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround applies a filter to a ranking question based on the checked boxes of a previous multiple-options question. There are two methods - one for filter and ranking questions being on the same page and a slightly different one for the filter question being on a page before the ranking question.&lt;br /&gt;
&lt;br /&gt;
There is a [http://www.partnersinc.biz/surveys//index.php?sid=96314&amp;amp;newtest=Y&amp;amp;lang=en demo of both methods here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH METHODS:&#039;&#039;&#039;&lt;br /&gt;
*[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
*Place the following script in your template.js file. This function will be accessed by either method.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// A function to filter choices in a ranking question&lt;br /&gt;
function rankFilter(q1ID, q2ID, prevPage) {&lt;br /&gt;
&lt;br /&gt;
	// If filter question is on a previous page, hide Q1 and check all &amp;quot;visible&amp;quot; boxes&lt;br /&gt;
	if(prevPage == 1) {&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; li[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;javatbd&amp;quot;]:visible input.checkbox&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039;&#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	handleChecked(q1ID, q2ID);&lt;br /&gt;
	$(&#039;#question&#039;+q1ID+&#039; input.checkbox&#039;).click(function() {&lt;br /&gt;
		handleChecked(q1ID, q2ID);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	function handleChecked(q1ID, q2ID) {&lt;br /&gt;
	&lt;br /&gt;
		// Find the survey and group IDs&lt;br /&gt;
		if($( &#039;input#fieldnames&#039; ).length != 0) {&lt;br /&gt;
			var fieldNames = $( &#039;input#fieldnames&#039; ).attr(&#039;value&#039;);&lt;br /&gt;
			var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
			var sID = tmp[0];&lt;br /&gt;
			var gID = tmp[1];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Loop through all Q1 options&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.checkbox&#039;).each(function(i) {&lt;br /&gt;
		&lt;br /&gt;
			// Find the answer code and value&lt;br /&gt;
			var tmp2 = $(this).attr(&#039;id&#039;).split(&#039;X&#039;+gID+&#039;X&#039;+q1ID+&#039;&#039;);&lt;br /&gt;
			var ansCode = tmp2[1];&lt;br /&gt;
			var ansTxt = $(this).next(&#039;label&#039;).text();&lt;br /&gt;
			&lt;br /&gt;
			// If option is checked and not in rank choices or output, add it to the rank choices&lt;br /&gt;
			if($(this).attr(&#039;checked&#039;) == true&lt;br /&gt;
						  &amp;amp;&amp;amp; $(&#039;#question&#039;+q2ID+&#039; select.select option[value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).length == 0&lt;br /&gt;
						  &amp;amp;&amp;amp; $(&#039;#question&#039;+q2ID+&#039; .output input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;][value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).length == 0) {&lt;br /&gt;
				$(&#039;&amp;lt;option value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;&amp;gt;&#039;+ansTxt+&#039;&amp;lt;/option&amp;gt;&#039;).appendTo(&#039;#question&#039;+q2ID+&#039; select.select&#039;);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// If option is unchecked...&lt;br /&gt;
			else if($(this).attr(&#039;checked&#039;) == false) {&lt;br /&gt;
				// Remove it from the rank choices&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select option[value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).remove();&lt;br /&gt;
				// Remove it from the rank output and reset hidden values&lt;br /&gt;
$(&#039;#question&#039;+q2ID+&#039; .output input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;][value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).attr(&#039;value&#039;, &#039;&#039;).siblings(&#039;input.text&#039;).val(&#039;&#039;).siblings(&#039;img&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Clean up empty inputs in the rank output table&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr&#039;).each(function(i) {&lt;br /&gt;
			var nextRow = $(this).next(&#039;tr&#039;);&lt;br /&gt;
			if($(&#039;input.text&#039;, this).val() == &#039;&#039; &amp;amp;&amp;amp; $(&#039;input.text&#039;, nextRow).val() != &#039;&#039;) {&lt;br /&gt;
				$(&#039;input.text&#039;, this).val($(&#039;input.text&#039;, nextRow).val());&lt;br /&gt;
				$(&#039;input.text&#039;, nextRow).val(&#039;&#039;);&lt;br /&gt;
				$(&#039;input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, this).attr(&#039;value&#039;, $(&#039;input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, nextRow).attr(&#039;value&#039;));&lt;br /&gt;
				$(&#039;input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, nextRow).attr(&#039;value&#039;, &#039;&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Show the scissors for the last populated rank output row&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table img[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;cut_&amp;quot;]&#039;).hide();&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table input.text[value!=&amp;quot;&amp;quot;]:last&#039;).siblings(&#039;img[id&amp;lt;/div&amp;gt;=&amp;quot;cut_&amp;quot;]&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Hide extra rank output rows&lt;br /&gt;
		var optNum = $(&#039;#question&#039;+q1ID+&#039; input.checkbox:checked&#039;).length;&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr&#039;).hide();&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr:lt(&#039;+(optNum+1)+&#039;)&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Hide and clear the ranking question if there are less than 2 checked options in Q1&lt;br /&gt;
		if(optNum &amp;lt; 2) {&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039;&#039;).hide();&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039; input.text&#039;).val(&#039;&#039;);&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039; input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;).attr(&#039;value&#039;, &#039;&#039;);&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039;&#039;).show();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// A workaround for the built in max-answers function&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; td.output tr:visible&#039;).each(function(i) {&lt;br /&gt;
			if($(&#039;input.text&#039;, this).val() == &#039;&#039;) {&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// A listener to work around the built in max-answers function&lt;br /&gt;
	$(&#039;#question&#039;+q2ID+&#039; td.rank&#039;).click(function (event) {&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; td.item input.text&#039;).each(function(i) {&lt;br /&gt;
			if ($(this).val() == &#039;&#039;) {&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH FILTER AND RANKING QUESTIONS ON SAME PAGE:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question and a ranking question on the same page (in the same group).&lt;br /&gt;
*Both questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Place the following script in the source of one of the questions.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;RR&amp;quot; with the ID of the ranking question.&lt;br /&gt;
*The function will hide the ranking question unless at least two options are selected in the multiple options question, in which case, it will only show the options selected.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		rankFilter(MM, RR);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR FILTER AND RANKING QUESTIONS ON SEPARATE PAGES:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question on page 1.&lt;br /&gt;
*Create a multiple options question and a ranking question on page 2.&lt;br /&gt;
*All three questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Set the multiple options on page 2 to be filtered by the multiple options on page 1.&lt;br /&gt;
*Place the following script in the source of one of the questions on page 2.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;RR&amp;quot; with the ID of the ranking question. Do not modify the &amp;quot;1&amp;quot;.&lt;br /&gt;
*The function will hide the multiple options question. If at least 2 options were selected in the multiple options on page 1, the corresponding options will be checked in the hidden multiple options question which will then be used to control the display of the ranking question.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		rankFilter(MM, RR, 1);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Filter &amp;quot;Array by Column&amp;quot; Question With &amp;quot;Multiple-Options&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, FireFox 3/4, Safari 5.0, Chrome 10.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround applies a filter to an &amp;quot;Array by Column&amp;quot; question based on the checked boxes of a previous multiple-options question. There are two methods - one for filter and array questions being on the same page and a slightly different one for the filter question being on a page before the array question.&lt;br /&gt;
&lt;br /&gt;
There is a [http://www.partnersinc.biz/surveys//index.php?sid=74213&amp;amp;newtest=Y&amp;amp;lang=en demo of both methods here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH METHODS:&#039;&#039;&#039;&lt;br /&gt;
*[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
*Place the following scripts in your template.js file. These functions will be accessed by either method.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
	function filterArrByCol(qMultiOpt, qArray, prevPage) {&lt;br /&gt;
	&lt;br /&gt;
		// If filter question is on a previous page, hide Q1 and check all &amp;quot;visible&amp;quot; boxes&lt;br /&gt;
		if(prevPage == 1) {&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039; li[id&amp;lt;/div&amp;gt;=&amp;quot;javatbd&amp;quot;]:visible input.checkbox&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039;&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Assign classes to the answer cells&lt;br /&gt;
		$(&#039;#question&#039;+qArray+&#039; table.question tbody td&#039;).each(function(i){&lt;br /&gt;
			var classArr = $(this).attr(&#039;class&#039;).split(&#039;answer_cell_00&#039;);&lt;br /&gt;
			var ansCode = classArr[1];&lt;br /&gt;
			$(this).addClass(&#039;ans-&#039;+ansCode+&#039; filtered&#039;);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Assign classes to the answer label cells&lt;br /&gt;
		$(&#039;#question&#039;+qArray+&#039; table.question tbody tr:eq(0) td&#039;).each(function(i){&lt;br /&gt;
			var classArr2 = $(this).attr(&#039;class&#039;).split(&#039; ans-&#039;);&lt;br /&gt;
			var ansCode2 = classArr2[1];&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; table.question thead tr:eq(0) th:eq(&#039;+i+&#039;)&#039;).addClass(&#039;ans-&#039;+ansCode2+&#039;&#039;);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Fire the filter function on page load&lt;br /&gt;
		filterArr(qMultiOpt, qArray);&lt;br /&gt;
&lt;br /&gt;
		// Listener on multi-opt checkboxes to fire the filter function&lt;br /&gt;
		$(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox&#039;).click(function(){&lt;br /&gt;
			filterArr(qMultiOpt, qArray);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// On submit, clear all hidden radios of array&lt;br /&gt;
		$(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; td.filtered:hidden&#039;).each(function(i){&lt;br /&gt;
				$(&#039;input.radio&#039;, this).attr(&#039;checked&#039;, false);&lt;br /&gt;
			});&lt;br /&gt;
			return true;&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function filterArr(qMultiOpt, qArray) {&lt;br /&gt;
	&lt;br /&gt;
		if($(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox:checked&#039;).length &amp;lt; 1) {&lt;br /&gt;
			// Hide the array if no multi-opt options are checked&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039;&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039;&#039;).show();&lt;br /&gt;
			&lt;br /&gt;
			// Hide all columns of array&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; table.question tbody td, #question&#039;+qArray+&#039; table.question thead th&#039;).hide();&lt;br /&gt;
			&lt;br /&gt;
			// Loop through multi-opt checkboxes and, if checked, show corresponding column of array&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox&#039;).each(function(i){&lt;br /&gt;
				if($(this).attr(&#039;checked&#039;) == true) {&lt;br /&gt;
					var classArr3 = $(this).attr(&#039;id&#039;).split(&#039;X&#039;+qMultiOpt);&lt;br /&gt;
					var ansCode3 = classArr3[1];&lt;br /&gt;
					$(&#039;#question&#039;+qArray+&#039; .ans-&#039;+ansCode3+&#039;&#039;).show();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH FILTER AND ARRAY QUESTIONS ON SAME PAGE:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question and an array-by-column question on the same page (in the same group).&lt;br /&gt;
*Both questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Place the following script in the source of one of the questions.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;AA&amp;quot; with the ID of the ranking question.&lt;br /&gt;
*The function will hide the array question unless at least one option is selected in the multiple-options question, in which case, it will only show the corresponding array column(s).&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		filterArrByCol(MM, AA);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR FILTER AND ARRAY QUESTIONS ON SEPARATE PAGES:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question on page 1.&lt;br /&gt;
*Create a multiple options question and an array-by-column question on page 2.&lt;br /&gt;
*All three questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Set the multiple options on page 2 to be filtered by the multiple options on page 1.&lt;br /&gt;
*Place the following script in the source of one of the questions on page 2.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;AA&amp;quot; with the ID of the array question. Do not modify the &amp;quot;1&amp;quot;.&lt;br /&gt;
*The function will hide the multiple options question. If options were selected in the multiple options on page 1, the corresponding options will be checked in the hidden multiple options question which will then be used to control the display of the array columns.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		filterArrByCol(MM, AA, 1);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Auto-tabbing between text input fields=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a workaround to facilitate auto-tabbing between text input questions in a single group using a [http://plugins.jquery.com/project/autotab jQuery plugin by Mathachew] and the Maximum characters attribute of questions.&lt;br /&gt;
&lt;br /&gt;
The behaviour will be: When the maximum number of characters has been entered into an input field, the focus (cursor) will be automatically moved to the next input field. When the backspace key is used to remove all characters from a field, the focus will be moved to the previous field. It&#039;s very useful in surveys having many text input questions to avoid having to manually tab or click between fields.&lt;br /&gt;
&lt;br /&gt;
You can view a small demo survey [http://www.partnersinc.biz/surveys//index.php?sid=11327&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Visit [http://plugins.jquery.com/autotabs http://plugins.jquery.com/autotabs], download the plugin script and save it as &#039;&#039;jquery.autotab-1.1b.js&#039;&#039; in the template folder.&lt;br /&gt;
#Link to the script by placing &#039;&#039;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autotab-1.1b.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&#039;&#039; within the &#039;&#039;&amp;lt;head&amp;gt;&#039;&#039; tag of startpage.pstpl.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Create the text based questions that auto-tabbing is to be applied to. (All must be in the same group if you&#039;re using group by group presentation)&lt;br /&gt;
#Define a Maximum characters attribute for all questions that the autotab is applied to.&lt;br /&gt;
{{QS:maximum_chars}}  &lt;br /&gt;
#In the source of the first question of the group that contains the auto-tabbed questions, add the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXAA&#039;).focus(); //initially focus on the first input&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXAA&#039;).autotab({ target: &#039;answerSSSSSXGGXBB&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXBB&#039;).autotab({ previous: &#039;answerSSSSSXGGXAA&#039;, target: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXCC&#039;).autotab({ previous: &#039;answerSSSSSXGGXBB&#039;, target: &#039;answerSSSSSXGGXDD&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXDD&#039;).autotab({ previous: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example has 4 fields to be auto-tabbed between - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
*SSSSS -&amp;gt; Survey ID&lt;br /&gt;
*GG -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Last question&lt;br /&gt;
&lt;br /&gt;
[[File:ids_343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;target&#039;&#039; parameter defines where the next input is and the &#039;&#039;previous&#039;&#039; parameter defines (you guessed it) the previous input.&lt;br /&gt;
&lt;br /&gt;
This plugin also has limited capability of formatting the input text - see comments in the plugin script.&lt;br /&gt;
&lt;br /&gt;
=Custom response listeners=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Listeners can be used to perform functions when a change in an input is detected. There are many uses such as the [[Workarounds#Reverse_array_filter|Reverse array_filter]] but a simple one would be to warn a respondent if they enter a value that may be too high.&lt;br /&gt;
&lt;br /&gt;
We can use the [http://docs.jquery.com/Events/change jQuery change( ) event] to fire a function whenever there is a change to the input. The function will look for an input value higher than 10 and, if found, will warn the respondent.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the script below in the source of one of the questions on the page where:&lt;br /&gt;
**11111 is the survey ID&lt;br /&gt;
**22 is the group ID&lt;br /&gt;
**33 is the question ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer11111X22X33&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
			if ( $(&#039;#answer11111X22X33&#039;).val() &amp;gt; 10 ) {&lt;br /&gt;
				alert (&amp;quot;That&#039;s an awful lot. Are you sure?&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Text input masks=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number ((###) ###-####) or a Canadian postal code (A1A 1A1) The [http://plugins.jquery.com/project/meioMask jQuery meioMask plugin by fabiomcosta] can be used to do this.&lt;br /&gt;
&lt;br /&gt;
The plugin has several pre-defined masks and supports custom masks. It also allows for pasting of input, allows default values and can auto-focus the next form element when the current input is completely filled. See [http://www.meiocodigo.com/projects/meiomask/ http://www.meiocodigo.com/projects/meiomask/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
There is a small demo [http://www.partnersinc.biz/surveys//index.php?sid=36146&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo was as follows:&lt;br /&gt;
#Visit [http://www.meiocodigo.com/projects/meiomask/ http://www.meiocodigo.com/projects/meiomask/], download the latest plugin script and save it as jquery.meiomask.js in the template folder.&lt;br /&gt;
#Link to the script by placing &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.meiomask.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; within the &amp;lt;head&amp;gt; tag of startpage.pstpl.&lt;br /&gt;
#Turn off $filterxsshtml to allow insertion of JavaScript in the questions. ([http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects See documentation here])&lt;br /&gt;
#Create the text input questions that the masks are to be applied to&lt;br /&gt;
#In the source of the help section of the first question of the group that contains the masked inputs, add the following code. ([http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ See How to use script here]) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {	&lt;br /&gt;
						   &lt;br /&gt;
	// Define custom masks&lt;br /&gt;
	$.mask.masks = $.extend($.mask.masks,{&lt;br /&gt;
		customMask1:{ mask: &#039;a9a 9a9&#039; }, // Canadian postal code&lt;br /&gt;
		// Maximum input of 9,999.99, reverse input, default value of 0.00		&lt;br /&gt;
		customMask2:{ mask: &#039;99.999,9&#039;, type : &#039;reverse&#039;, defaultValue : &#039;000&#039; } &lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Set the &#039;alt&#039; attributes of the inputs&lt;br /&gt;
	$(&#039;#answer111111X22XAA&#039;).attr(&#039;alt&#039;, &#039;phone-us&#039;); // a pre-defined mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XBB&#039;).attr(&#039;alt&#039;, &#039;customMask1&#039;); // a custom mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XCC&#039;).attr(&#039;alt&#039;, &#039;customMask2&#039;); // a custom mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XDD&#039;).attr(&#039;alt&#039;, &#039;cc&#039;); // a pre-defined mask for credit card&lt;br /&gt;
	&lt;br /&gt;
	// Tell the plugin to apply masks to these inputs&lt;br /&gt;
	$(&#039;input:#answer111111X22XAA&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XBB&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XCC&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XDD&#039;).setMask();	&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first section defines two custom masks to be used - one for Canadian postal code with a format of A#A #A# and a second for a maximum amount of 9999.99 with reverse input (useful for cost inputs) and a default value of 0.00.&lt;br /&gt;
&lt;br /&gt;
The next section sets the &amp;quot;alt&amp;quot; attributes for the text inputs. This will tell meioMask which mask we will be applying to each input. By default meioMask looks at the alt attribute to find which mask to apply however this can be changed using the [http://www.meiocodigo.com/projects/meiomask/#mm_options mask options].&lt;br /&gt;
&lt;br /&gt;
In the final section we apply the masks to the inputs.&lt;br /&gt;
&lt;br /&gt;
This example has 4 inputs with masks on them - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
&lt;br /&gt;
*11111 -&amp;gt; Survey ID&lt;br /&gt;
*22 -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Fourth question&lt;br /&gt;
&lt;br /&gt;
[[File:Ids 343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
=Text input masks - second method=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91RC6+, FireFox 4.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number ((###) ###-####) or a US social security number (###-##-####). The jQuery meioMask plugin by fabiomcosta is no longer supported but an alternative exists. The DigitalBush Masked Input Plugin is updated and simple to implement in LimeSurvey. See [http://digitalbush.com/projects/masked-input-plugin/ http://digitalbush.com/projects/masked-input-plugin/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
Implementation as follows:&lt;br /&gt;
&lt;br /&gt;
#Visit [http://digitalbush.com/projects/masked-input-plugin/ http://digitalbush.com/projects/masked-input-plugin/], download the latest plugin script and save it as jquery.maskedinput.js in the template folder.&lt;br /&gt;
#Link to the script by placing &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.maskedinput.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; within the &amp;lt;head&amp;gt; tag of startpage.pstpl.&lt;br /&gt;
#Turn off $filterxsshtml to allow insertion of JavaScript in the questions. ([http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects See documentation here])&lt;br /&gt;
#Create the text input questions that the masks are to be applied to&lt;br /&gt;
#In the source of the help section of the first question of the group that contains the masked inputs, add the following code. ([http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ See How to use script here])  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function($) {	 &lt;br /&gt;
		$(&amp;quot;#answer55431X1X5&amp;quot;).mask(&amp;quot;999-99-9999&amp;quot;,{ placeholder:&amp;quot;#&amp;quot; });&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace the &amp;quot;#answer55431X1X5&amp;quot; with your survey ID, group ID, and question ID. You can change the mask format and change or eliminate the placeholder if you wish. If you have multiple questions in the same group, simply copy and paste the line that begins with &amp;quot;$&amp;quot; and change the code to what is needed for your application.&lt;br /&gt;
&lt;br /&gt;
=Select a random response to a &amp;quot;Multiple options&amp;quot; question for later use=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to randomly select one of the checked boxes in a &amp;quot;Multiple options&amp;quot; question and store it&#039;s label for later use in the survey. A possible use would be to have a question asking what products were purchased and then randomly selecting one of the products to ask further questions about.&lt;br /&gt;
&lt;br /&gt;
There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=81252&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Basically what we&#039;ve done here is to put listeners on all of the checkboxes. If a change of state is detected in any of them the &amp;quot;randomResponse&amp;quot; function is called which loops through all of the checkboxes and if it finds a checked state, that box&#039;s label is added to an array. Then a random item is pulled from the array and used to populate the hidden question. This hidden question can then be drawn upon later in the survey using [http://docs.limesurvey.org/tiki-index.php?page=Adding+a+Question#Information_from_previous_answers INSERTANS] or [http://docs.limesurvey.org/tiki-index.php?page=Setting+conditions&amp;amp;structure=English+Instructions+for+LimeSurvey Conditions].&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
#[http://docs.limesurvey.org/tiki-index.php?page=Workarounds%3A+Manipulating+a+survey+at+runtime+using+Javascript&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._in_LimeSurvey_ Set up your survey to use JavaScript].&lt;br /&gt;
#Create a &amp;quot;Multiple options&amp;quot; question that we&#039;re going to randomly pick a checked box from&lt;br /&gt;
#Create a text input question to store the label of the checked box in (we&#039;re going to hide this with JavaScript)&lt;br /&gt;
#Place the script below in the source of one of the questions on the page. &lt;br /&gt;
&lt;br /&gt;
The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
*EDIT HERE (1) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 44 -&amp;gt; hidden question ID.&lt;br /&gt;
*EDIT HERE (2) - 44 -&amp;gt; hidden question ID.&lt;br /&gt;
*EDIT HERE (3) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 33 -&amp;gt; multiple option question ID, A/B/C/D/E/F -&amp;gt; multiple option answer codes. Also add or remove CBs for more or less checkboxes.&lt;br /&gt;
*EDIT HERE (4) - add or remove CBs for more or less checkboxes.&lt;br /&gt;
*EDIT HERE (5) - add or remove CBs for more or less checkboxes. &lt;br /&gt;
&lt;br /&gt;
For more info on these IDs see [http://docs.limesurvey.org/tiki-index.php?page=SGQA+identifier&amp;amp;structure=English+Instructions+for+LimeSurvey SGQA identifier].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
				&lt;br /&gt;
		//// Identify the hidden question input&lt;br /&gt;
		//// EDIT HERE (1) - replace with your hidden question input ID&lt;br /&gt;
		var hiddenInput = &#039;#answer11111X22X44&#039;;&lt;br /&gt;
		&lt;br /&gt;
		//// Make the &amp;quot;hidden&amp;quot; question disappear&lt;br /&gt;
		//// EDIT HERE (2) - replace with your hidden question ID&lt;br /&gt;
		$(&#039;#question44&#039;).hide();&lt;br /&gt;
		&lt;br /&gt;
		//// Identify the checkboxes to be randomized&lt;br /&gt;
		//// EDIT HERE (3) - add or remove as required, &lt;br /&gt;
		//// replace with your checkbox IDs&lt;br /&gt;
		var CB1 = &#039;#answer11111X22X33A&#039;;&lt;br /&gt;
		var CB2 = &#039;#answer11111X22X33B&#039;;&lt;br /&gt;
		var CB3 = &#039;#answer11111X22X33C&#039;;&lt;br /&gt;
		var CB4 = &#039;#answer11111X22X33D&#039;;&lt;br /&gt;
		var CB5 = &#039;#answer11111X22X33E&#039;;&lt;br /&gt;
		var CB6 = &#039;#answer11111X22X33F&#039;;&lt;br /&gt;
		&lt;br /&gt;
		//// Create an array of all checkboxes to be randomized&lt;br /&gt;
		//// EDIT HERE (4) - add or remove CBs as required&lt;br /&gt;
		checkBoxes = new Array( CB1, CB2, CB3, CB4, CB5, CB6 );&lt;br /&gt;
		var checkBoxesLength = checkBoxes.length;&lt;br /&gt;
		&lt;br /&gt;
		//// The randomizing function - no editing required&lt;br /&gt;
		function randomResponse () {&lt;br /&gt;
			var boxLabels = new Array();&lt;br /&gt;
			&lt;br /&gt;
			// loop through all of the checkboxes and if they are checked, &lt;br /&gt;
			// add their label to the boxLabels array&lt;br /&gt;
			for( var i=0; i&amp;lt;checkBoxesLength; i++ ) {&lt;br /&gt;
				if ( $(checkBoxes[i]).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
					var cbid = checkBoxes[i].replace(&#039;#&#039;,&#039;&#039;);&lt;br /&gt;
					boxLabels.push( $( &#039;label[for=&#039; + cbid + &#039;]&#039; ).html() );&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// find a random index of the responses array&lt;br /&gt;
			var randomNum = Math.floor(Math.random() * boxLabels.length); &lt;br /&gt;
			&lt;br /&gt;
			// populate the hidden question input with the &lt;br /&gt;
			// random input value&lt;br /&gt;
			$(hiddenInput).val( boxLabels[randomNum] ); &lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		//// The listeners that will fire the randomize function if a &lt;br /&gt;
		//// change occurs in the checkboxes&lt;br /&gt;
		//// EDIT HERE (5) - add or remove CBs as required&lt;br /&gt;
		$(CB1).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB2).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB3).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB4).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB5).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB6).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});	&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Display secondary options in a &amp;quot;Multiple options&amp;quot; question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to display secondary options in a &amp;quot;Multiple options&amp;quot; question if a primary option is checked as in the images below.&lt;br /&gt;
&lt;br /&gt;
Primary option not selected:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Secondary_options_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Primary option selected:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Secondary_options_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=11491&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
We&#039;ve put a listener on the primary answer (&amp;quot;Option 1&amp;quot; in the demo) that shows or hides the secondary answers depending on the state of the primary.&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
#[http://docs.limesurvey.org/tiki-index.php?page=Workarounds%3A+Manipulating+a+survey+at+runtime+using+Javascript&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._in_LimeSurvey_ Set up your survey to use JavaScript].&lt;br /&gt;
#Create a &amp;quot;Multiple options&amp;quot; question including both the primary and secondary answers (in the order that you would like them displayed if all shown)&lt;br /&gt;
#Add the following script to the source of the question.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		&lt;br /&gt;
		/**** &lt;br /&gt;
		The following code puts a listener on an answer in a multiple options&lt;br /&gt;
		question (the primary answer) and if that answer is checked, a secondary &lt;br /&gt;
		level of answers is displayed.&lt;br /&gt;
		****/&lt;br /&gt;
		&lt;br /&gt;
		// --- 1 --- Indent the secondary answers a bit&lt;br /&gt;
		$( &#039;#questionQQ li:eq(1)&#039; ).css({ &#039;margin-left&#039;:&#039;2.5em&#039; });&lt;br /&gt;
		$( &#039;#questionQQ li:eq(2)&#039; ).css({ &#039;margin-left&#039;:&#039;2.5em&#039; });&lt;br /&gt;
		&lt;br /&gt;
		// --- 2 --- When the page loads, see if the primary answer is checked and if not, &lt;br /&gt;
                //hide and un-check all secondary answers&lt;br /&gt;
		if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
			&lt;br /&gt;
			$( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
			$( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
			&lt;br /&gt;
			$( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
			$( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// --- 3 --- Now put a listener on the primary answer to show or hide secondary answers &lt;br /&gt;
		// We need to use .click instead of .change cause IE won&#039;t cooperate&lt;br /&gt;
		$(&#039;#answerSSSSSXGGXQQAA&#039;).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Have a look at the primary answer and hide/show the secondary answers accordingly&lt;br /&gt;
			if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
			&lt;br /&gt;
				$( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
				$( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
				&lt;br /&gt;
				$( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
				$( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				&lt;br /&gt;
				$( &#039;#questionQQ li:eq(1)&#039; ).show();&lt;br /&gt;
				$( &#039;#questionQQ li:eq(2)&#039; ).show();&lt;br /&gt;
			} &lt;br /&gt;
			&lt;br /&gt;
			// The original functions of the click event&lt;br /&gt;
			cancelBubbleThis(event);&lt;br /&gt;
			checkconditions(this.value, this.name, this.type);&lt;br /&gt;
		  }&lt;br /&gt;
		);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 1:&#039;&#039;&#039;&lt;br /&gt;
*This section indents the secondary answers to give the look of a list in a list when they&#039;re shown&lt;br /&gt;
*&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID&lt;br /&gt;
*&#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; are the index positions of your secondary options. Modify or add as necessary for the number and placement of secondary options in your question. Note that the index starts at 0 so &#039;&#039;&#039;eq(1)&#039;&#039;&#039; actually affects the second option in the full list and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; affects the third. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 2:&#039;&#039;&#039;&lt;br /&gt;
*This section checks the state of the primary question when the page is loaded and if necessary hides the secondary questions. We need this in case users navigate away from and then back to the page.&lt;br /&gt;
*Modify &#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; as above.&lt;br /&gt;
*&#039;&#039;&#039;SSSSS&#039;&#039;&#039; is your survey ID.&lt;br /&gt;
*&#039;&#039;&#039;GG&#039;&#039;&#039; is your group ID.&lt;br /&gt;
*&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID.&lt;br /&gt;
*&#039;&#039;&#039;AA&#039;&#039;&#039; is your primary answer code.&lt;br /&gt;
*&#039;&#039;&#039;BB&#039;&#039;&#039; and &#039;&#039;&#039;CC&#039;&#039;&#039; are your secondary answer codes (add as necessary). &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 3:&#039;&#039;&#039;&lt;br /&gt;
*This is the section that &amp;quot;listens&amp;quot; to the primary answer and reacts accordingly.&lt;br /&gt;
*Edit as in section 2.&lt;br /&gt;
&lt;br /&gt;
For more info on these IDs see SGQA identifier(external link).&lt;br /&gt;
&lt;br /&gt;
This code could be tidied up and shortened a bit but I left it this way to make it easier to follow.&lt;br /&gt;
&lt;br /&gt;
=Minimum number of required answers in an array (pre 1.92)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92 all array style questions have the min_answers and max_answers options, so this script is obsolete.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to specify a &#039;&#039;&#039;minimum number&#039;&#039;&#039; of answers required in an array question. It is an alternative to the &amp;quot;Mandatory&amp;quot; parameter which specifies that &#039;&#039;&#039;all&#039;&#039;&#039; answers are required. It could also be easily modified to specify a maximum number of answers.&lt;br /&gt;
&lt;br /&gt;
We accomplish this by placing an onload function in the source of the array question. This function hides the Next/Submit button and displays a warning element until it detects a minimum number of responses. It then hides the warning and shows the Next/Submit button.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=97166&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Set up the template to use custom onload functions. (See the [[Workarounds#Custom onload function|workaround here]])&lt;br /&gt;
#In the source of the array question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Modify the &#039;&#039;SETTINGS&#039;&#039; section of the code as required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	// Wait until the document is fully loaded&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
	&lt;br /&gt;
		/********************** SETTINGS **********************/&lt;br /&gt;
		// The text to appear in the warning element&lt;br /&gt;
		var warningText = &#039;Please answer at least 4 to continue&#039;;&lt;br /&gt;
		// The question ID&lt;br /&gt;
		var questionId = 137;&lt;br /&gt;
		// The minimum number of answers required&lt;br /&gt;
		var minNumber = 4;&lt;br /&gt;
		/******************************************************/&lt;br /&gt;
		&lt;br /&gt;
		// Create the warning element and place it after the submit button&lt;br /&gt;
		var el = document.createElement(&#039;div&#039;);&lt;br /&gt;
		el.setAttribute(&#039;id&#039;,&#039;warning&#039;);&lt;br /&gt;
		document.body.appendChild(el);&lt;br /&gt;
		$( &#039;#warning&#039; ).css({&lt;br /&gt;
			&#039;border&#039;:&#039;1px solid #333333&#039;,&lt;br /&gt;
			&#039;width&#039;:&#039;200px&#039;,&lt;br /&gt;
			&#039;padding&#039;:&#039;3px&#039;,&lt;br /&gt;
			&#039;color&#039;:&#039;red&#039;&lt;br /&gt;
		});&lt;br /&gt;
		$(&#039;#warning&#039;).html(warningText);&lt;br /&gt;
		$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).after($(&#039;#warning&#039;));&lt;br /&gt;
		&lt;br /&gt;
		// Detect the initial number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
		var inputInitCount = 0;&lt;br /&gt;
		$(&#039;#question&#039; + questionId + &#039; input&#039;).each(function(i) {&lt;br /&gt;
			if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
				inputInitCount++;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		if (inputInitCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
			$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
			$(&#039;#warning&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#warning&#039;).show();&lt;br /&gt;
			$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Listener to detect number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
		$(&#039;#question&#039; + questionId + &#039; input.radio, #question&#039;+questionId+&#039; tbody[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;javatbd&amp;quot;] td&#039;).click(function() {&lt;br /&gt;
			var inputCount = 0;&lt;br /&gt;
			$(&#039;#question&#039; + questionId + &#039; input.radio&#039;).each(function(i) {&lt;br /&gt;
				if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
					inputCount++;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
			if (inputCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
				$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
				$(&#039;#warning&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;#warning&#039;).show();&lt;br /&gt;
				$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// The original functions of the click event&lt;br /&gt;
			checkconditions(this.value, this.name, this.type);&lt;br /&gt;
		});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Minimum elapsed time before moving forward in survey=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, Firefox 7.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround interrupts the Next/Submit function and checks the amount of time elapsed since the page loaded. If the time is less than the minimum dictated, the respondent is alerted and not allowed to proceed. It is useful if you want to enforce a minimum amount of time spent viewing a page.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the script below in the source of one of the questions on the page, replacing &amp;quot;TT&amp;quot; with the minimum number of seconds required before advancing is allowed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		minTime(TT);&lt;br /&gt;
&lt;br /&gt;
		function minTime(minTime) {&lt;br /&gt;
&lt;br /&gt;
			var startTime = new Date();&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
				var endTime = new Date();&lt;br /&gt;
&lt;br /&gt;
				if((endTime - startTime)/1000 &amp;lt;= minTime) {&lt;br /&gt;
					alert (&#039;You must spend at least &#039;+minTime+&#039; seconds on the question.&#039;);&lt;br /&gt;
					return false;&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					return true;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Minimum number of characters in Long free text or Huge free text questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, Firefox 7.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.91, you can use regular expression masks (validation) to specify the minimum number of required characters.  However, even if the question is mandatory, it can still be blank.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version  1.92, if you make the question mandatory and use a validation mask to specify the minimum number of characters, then the user will be forced to answer the question.  Note that unlike 1.91, they can submit their current answers, even if partially invalid (so they are stored in the database), but they will not ber able to proceed to the next page until they have passed all mandatory and validity checks.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround interrupts the Next/Submit function and checks the number of characters entered in a Long free text or Huge free text question. If the number is less than the minimum dictated, the respondent is alerted and not allowed to proceed.&lt;br /&gt;
&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
&lt;br /&gt;
#Place the script below in the source of one of the questions on the page, replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;CC&amp;quot; with the minimum number of characters required before advancing is allowed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       minChar(QQ, CC);&lt;br /&gt;
&lt;br /&gt;
       function minChar(qID, minChars) {&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               if($(&#039;#question&#039;+qID+&#039; textarea&#039;).val().replace(/ /g,&#039;&#039;).length &amp;lt; minChars) {&lt;br /&gt;
&lt;br /&gt;
                   alert (&#039;You must enter at least &#039;+minChars+&#039; characters.&#039;);&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Variable Length Array (Multi Flexible Text) question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows a respondent to add or remove rows of an Array (Multi Flexible Text) question. It&#039;s useful to avoid the page being cluttered with unnecessary array rows.&lt;br /&gt;
&lt;br /&gt;
A function is placed in the template.js file of your template (use template editor). This function hides all of the array rows except the first and inserts two elements that when clicked show or hide rows accordingly.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=53132&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
It must be noted that you can not make this question Mandatory as the respondent will have no way to complete hidden fields. If you want the displayed fields to be mandatory you will need to validate them in another function or modify this function to only allow the addition of rows if all fields in the last row are completed and then disable those fields - that, however, is a little over the top for this example.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
#Set up your survey to use JavaScript (See instructions [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|here]])&lt;br /&gt;
&lt;br /&gt;
#Add the following script to your &#039;&#039;template.js&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end with the question ID.&lt;br /&gt;
&lt;br /&gt;
#Create one or more Array (Multi Flexible Text) questions&lt;br /&gt;
&lt;br /&gt;
#If you want to apply it to more arrays on the same page simply add more calls with the appropriate question IDs. (eg. varLengthArray(1); varLengthArray(2);...)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // A function to add or remove rows of an Array (Multi Flexible)(Text) question&lt;br /&gt;
	function varLengthArray(qID) {&lt;br /&gt;
&lt;br /&gt;
		if ($(&#039;#question&#039;+qID+&#039;&#039;).length &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
			// The HTML content of the Add/Remove elements - modify as you wish&lt;br /&gt;
			var addContent = &#039;[+]&#039;;&lt;br /&gt;
			var removeContent = &#039;[-]&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Create the Add and Remove elements &amp;amp; insert them&lt;br /&gt;
			var el1 = document.createElement(&#039;div&#039;);&lt;br /&gt;
			el1.setAttribute(&#039;id&#039;,&#039;addButton&#039;+qID);&lt;br /&gt;
			document.body.appendChild(el1);&lt;br /&gt;
			var el2 = document.createElement(&#039;div&#039;);&lt;br /&gt;
			el2.setAttribute(&#039;id&#039;,&#039;removeButton&#039;+qID);&lt;br /&gt;
			document.body.appendChild(el2);&lt;br /&gt;
&lt;br /&gt;
			// Move them to after the array&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).appendTo($( &#039;#question&#039; + qID + &#039; table.question&#039; ).parent());&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).appendTo($( &#039;#question&#039; + qID + &#039; table.question&#039; ).parent());&lt;br /&gt;
&lt;br /&gt;
			// Insert their HTML&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).html( addContent );&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).html( removeContent );&lt;br /&gt;
&lt;br /&gt;
			// Style the elements - you can modify here if you wish&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).css({&lt;br /&gt;
				&#039;margin&#039;:&#039;10px 0 0 10px&#039;,&lt;br /&gt;
				&#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
				&#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
				&#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
				&#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
				&#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
				&#039;float&#039;:&#039;left&#039;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).css({&lt;br /&gt;
				&#039;margin&#039;:&#039;10px 0 0 10px&#039;,&lt;br /&gt;
				&#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
				&#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
				&#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
				&#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
				&#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
				&#039;float&#039;:&#039;left&#039;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Initially hide the Remove element&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).hide();&lt;br /&gt;
&lt;br /&gt;
			// Call the functions below when clicked&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).click(function (event) {&lt;br /&gt;
				addRow(qID);&lt;br /&gt;
			});&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).click(function (event) {&lt;br /&gt;
				removeRow(qID);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Function to add a row, also shows the Remove element and hides the&lt;br /&gt;
			//Add element if all rows are shown&lt;br /&gt;
			function addRow(qID) {&lt;br /&gt;
				var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
				var rowCount = $( arrayRow ).size() - 1;&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
				$( &#039;div#removeButton&#039;+qID ).show();&lt;br /&gt;
				if ( $( arrayRow + &#039;:eq(&#039; + rowCount + &#039;)&#039; ).attr(&#039;name&#039;) == &#039;visible&#039; )  {&lt;br /&gt;
					$( &#039;div#addButton&#039;+qID ).hide();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Function to remove a row, also clears the contents of the removed row,&lt;br /&gt;
			// shows the Add element if the last row is hidden and hides the Remove&lt;br /&gt;
			// element if only the first row is shown&lt;br /&gt;
			function removeRow(qID) {&lt;br /&gt;
				var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
				var rowCount = $( arrayRow ).size() - 1;&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last input[type=&amp;quot;text&amp;quot;]&#039; ).val(&#039;&#039;);&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last&#039; ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
				$( &#039;div#addButton&#039;+qID ).show();&lt;br /&gt;
				if ( $( arrayRow + &#039;:eq(1)&#039; ).attr(&#039;name&#039;) == &#039;hidden&#039; )  {&lt;br /&gt;
					$( &#039;div#removeButton&#039;+qID ).hide();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Just some initialization stuff&lt;br /&gt;
			var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
			var rowCount = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Initially hide all except first row or any rows with populated inputs&lt;br /&gt;
			$( arrayRow ).each(function(i) {&lt;br /&gt;
				if ( i &amp;gt; 0 ) {&lt;br /&gt;
					// We also need to give the hidden rows a name cause IE doesn&#039;t&lt;br /&gt;
					// recognize jQuery :visible selector consistently&lt;br /&gt;
					$( this ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
					$(&#039;input[type=text]&#039;, this).each(function(i) {&lt;br /&gt;
						if ($(this).attr(&#039;value&#039;) != &#039;&#039;) {&lt;br /&gt;
							$(this).parents(&#039;tbody:eq(0)&#039;).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
							$( &#039;div#removeButton&#039;+qID ).show();&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
					rowCount = i;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Call the function with a question ID&lt;br /&gt;
	varLengthArray(QQ);&lt;br /&gt;
&lt;br /&gt;
});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expandable Array=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to present an array question incrementally. That is to say that initially only the first option (row) in the array is shown. When that option is answered the next is shown and so-on.&lt;br /&gt;
&lt;br /&gt;
A JavaScript function is placed in the source of the array question. This function hides all of the array rows except the first and then displays them as options are answered.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=94958&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
The workaround supports following question types:&lt;br /&gt;
*Array (flexible labels)&lt;br /&gt;
*Array (flexible labels) by column&lt;br /&gt;
*Array (Yes/No/Uncertain)&lt;br /&gt;
*Array (Increase, Same, Decrease)&lt;br /&gt;
*Array (Flexible Labels) dual scale&lt;br /&gt;
*Array (10 point choice)&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Set up your survey to use JavaScript. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|documentation here]])&lt;br /&gt;
#Create one or more Array questions&lt;br /&gt;
#In the source of the first array question add the following script.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end of the script with the question ID of the array you would like to manipulate.&lt;br /&gt;
#If you want to apply it to more arrays on the same page, simply add more calls with the appropriate question IDs. (eg. expandingArray(1); expandingArray(2);...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// A function to show subsequent rows of an array as options are checked&lt;br /&gt;
		function expandingArray(qID) {&lt;br /&gt;
&lt;br /&gt;
			// Build an array of the question rows&lt;br /&gt;
			var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody tr&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Initially hide all rows unless an input was previously checked&lt;br /&gt;
			$( arrayRow ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
				if ( $( arrayRow  + &#039;:eq(&#039; + i + &#039;) input.radio:checked&#039; ).length != 0 ) {&lt;br /&gt;
					$(this).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					$(this).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Now show the first hidden row&lt;br /&gt;
			addRow();&lt;br /&gt;
&lt;br /&gt;
			// Add another row when an option is checked for the first time&lt;br /&gt;
			$( &#039;#question&#039; + qID + &#039; td.answer input.radio&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
				if ($(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;) != &#039;clickedRow&#039;) {&lt;br /&gt;
					addRow();&lt;br /&gt;
					$(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				// The original function of the click event&lt;br /&gt;
				checkconditions(this.value, this.name, this.type);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Add another row when an table cell is clicked for the first time&lt;br /&gt;
			$( &#039;#question&#039; + qID + &#039; table.question tbody td&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
				if ($(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;) != &#039;clickedRow&#039;) {&lt;br /&gt;
					addRow();&lt;br /&gt;
					$(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Function to add a row&lt;br /&gt;
			function addRow() {&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with a question ID&lt;br /&gt;
		expandingArray(QQ);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions - ENHANCED=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping as many answers at the end of the list as specified by the var insertitems=n, where n is the number of answers you want left unrandomized. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the 5th to 7th displayed last as in the image below (assuming you assigned the number 3 to insertitems):&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [[Optional settings#Survey Behavior|$shownoanswer option]] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Set var insertitems=n (n = the number of items you want un-randomized)&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
Onload code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Function to allow randomization of all answers except the last one in Multiple options and List/radio questions&lt;br /&gt;
&lt;br /&gt;
       function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
           //var to define how many lists to be added at the end&lt;br /&gt;
&lt;br /&gt;
           var insertitems=3;&lt;br /&gt;
&lt;br /&gt;
           // Find the number of answers&lt;br /&gt;
&lt;br /&gt;
           var ansCount = &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
           lastitems=new Array();&lt;br /&gt;
&lt;br /&gt;
           var liid=new Array();&lt;br /&gt;
&lt;br /&gt;
           var $ul;&lt;br /&gt;
&lt;br /&gt;
           var j=0;&lt;br /&gt;
&lt;br /&gt;
           $( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                           ansCount = (i + 1);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                           if(i&amp;gt;ansCount-(insertitems+1)){&lt;br /&gt;
&lt;br /&gt;
                             lastitems[j]=$(this).html();&lt;br /&gt;
&lt;br /&gt;
                             liid[j]=$(this).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                             j++;&lt;br /&gt;
&lt;br /&gt;
                             $(this).remove();&lt;br /&gt;
&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
// get current ul&lt;br /&gt;
&lt;br /&gt;
$ul = $(this).parent();&lt;br /&gt;
&lt;br /&gt;
// get array of list items in current ul&lt;br /&gt;
&lt;br /&gt;
var $liArr = $ul.children(&#039;li&#039;);&lt;br /&gt;
&lt;br /&gt;
// sort array of list items in current ul randomly&lt;br /&gt;
&lt;br /&gt;
$liArr.sort(function(a,b){&lt;br /&gt;
&lt;br /&gt;
// Get a random number between 0 and 100&lt;br /&gt;
&lt;br /&gt;
var temp = parseInt( Math.random()*100 );&lt;br /&gt;
&lt;br /&gt;
// Get 1 or 0, whether temp is odd or even&lt;br /&gt;
&lt;br /&gt;
var isOddOrEven = temp%2;&lt;br /&gt;
&lt;br /&gt;
// Get +1 or -1, whether temp greater or smaller than 5&lt;br /&gt;
&lt;br /&gt;
var isPosOrNeg = temp&amp;gt;5 ? 1 : -1;&lt;br /&gt;
&lt;br /&gt;
// Return -1, 0, or +1&lt;br /&gt;
&lt;br /&gt;
return( isOddOrEven*isPosOrNeg );&lt;br /&gt;
&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
// append list items to ul&lt;br /&gt;
&lt;br /&gt;
.appendTo($ul);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$.each(lastitems,function(i){&lt;br /&gt;
&lt;br /&gt;
$( $ul ).append(&amp;quot;&amp;lt;li id=&amp;quot;+liid[i]+&amp;quot;&amp;gt;&amp;quot;+this+&amp;quot;&amp;lt;/li&amp;gt;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Call the function with the SID, GID and QID&lt;br /&gt;
&lt;br /&gt;
       partRand(SSSSS, GG, QQ);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last as in the image below:&lt;br /&gt;
&lt;br /&gt;
[[File:random_336x179gif.gif]]&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [[Optional settings#Survey Behavior|$shownoanswer option]] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [[Advanced question settings#random_order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers except the last one in Multiple options and List/radio questions&lt;br /&gt;
		function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = (i + 1);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list&lt;br /&gt;
			$( &#039;input#answer&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).parent().appendTo($( &#039;#question&#039; + qID + &#039; td.answer ul&#039; ));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
			partRand(SSSSS, GG, QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - List (dropdown) questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the one above, allows the answers of List (dropdown) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more List (dropdown) questions with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers&lt;br /&gt;
		//except the last one in List/dropdown questions&lt;br /&gt;
		function partRandDD(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; select option&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = i;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list&lt;br /&gt;
			$( &#039;option[value=&amp;quot;&#039; + ansCount + &#039;&amp;quot;]&#039; ).appendTo($( &#039;div#question&#039; + qID + &#039; select&#039; ));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
		partRandDD(89344, 72, 244);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple numerical input=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, Safari 5.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the ones above, allows the answers of Multiple numerical input questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple numerical input question with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers except the last one in multiple numeric input questions&lt;br /&gt;
		function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; div.answers li&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = (i - 1);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list - but before the first helping sum&lt;br /&gt;
			$( &#039;li#javatbd&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).insertBefore($( &#039;div#question&#039; + qID + &#039; div.answers li.multiplenumerichelp&#039; ).first());&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
		partRand(SID, GID, QID);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using this solution for Multiple numerical input questions might be a bit more complicated than for other question types. All answers are organized in an unordered list (&amp;lt;nowiki&amp;gt;&amp;lt;ul&amp;gt;&amp;lt;/nowiki&amp;gt;) structure. However, if advanced question settings like &#039;&#039;Equals sum value&#039;&#039; are used, LimeSurvey adds helping information (e.g. sum of all entries and remainder) to the same unordered list using the class &#039;&#039;multiplenumerichelp&#039;&#039; for these additional list items. The above example  assumes that at least one of these list items is present and moves the last answer to the position right above the first helper item. Without such advanced settings, the code will most certainly need adaptation.&lt;br /&gt;
&lt;br /&gt;
=Making one (or more) rows of an array mandatory=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, Firefox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to define one or more rows of an array question as mandatory (instead of all of them which the &amp;quot;Mandatory&amp;quot; question setting does). It is [http://www.partnersinc.biz/surveys//index.php?sid=26842&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
A JavaScript function interrupts the submit function and checks if the inputs in the mandatory row(s) are populated. If not, an alert is popped up, the offending inputs are turned pink and the submit is aborted. Otherwise the submit goes ahead.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions (see [[Optional settings#Security|documentation here]]).&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following script (see [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]]).&lt;br /&gt;
#Modify the warningText (line10)as required.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; (lines 13 and 14)  with the question ID and add calls as necessary for more rows - the example code renders rows 1 and 3 mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function () {&lt;br /&gt;
&lt;br /&gt;
		// Interrupt the submit function&lt;br /&gt;
		$(&#039;form#limesurvey&#039;).submit(function () {&lt;br /&gt;
&lt;br /&gt;
			// Override the built-in &amp;quot;disable navigation buttons&amp;quot; feature&lt;br /&gt;
			$(&#039;#moveprevbtn, #movenextbtn, #movesubmitbtn&#039;).attr(&#039;disabled&#039;, &#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
			var empty = 0;&lt;br /&gt;
			var warningText = &#039;Please complete the highlighted inputs.&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Call the mandatory row function with question IDs and row numbers&lt;br /&gt;
			mandatoryRow(QQ, 1);&lt;br /&gt;
			mandatoryRow(QQ, 3);&lt;br /&gt;
&lt;br /&gt;
			// A function to render rows of an array mandatory&lt;br /&gt;
			function mandatoryRow(qID, rowNum) {&lt;br /&gt;
&lt;br /&gt;
				$(&#039;div#question&#039; + qID + &#039; table.question tbody[id&amp;lt;/div&amp;gt;=&amp;quot;javatbd&amp;quot;]:eq(&#039; + Number(rowNum - 1) + &#039;) input[type=&amp;quot;text&amp;quot;]&#039;).each(function (i) {&lt;br /&gt;
&lt;br /&gt;
					if ($(this).val() == &#039;&#039;) {&lt;br /&gt;
						$(this).css(&#039;background-color&#039;, &#039;pink&#039;);&lt;br /&gt;
						empty = 1;&lt;br /&gt;
					} &lt;br /&gt;
					else {&lt;br /&gt;
						$(this).css(&#039;background-color&#039;, &#039;#FFFFFF&#039;);&lt;br /&gt;
					}&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (empty == 1) {&lt;br /&gt;
				alert(warningText);&lt;br /&gt;
				return false;&lt;br /&gt;
			} &lt;br /&gt;
			else {&lt;br /&gt;
				return true;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Randomly displaying one of a few YouTube videos, and recording which was displayed=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland has created and documented a method to randomly display one of a number of youtube videos in a single question, and save which one was displayed.&lt;br /&gt;
&lt;br /&gt;
http://www.aptigence.com.au/home/archives/23-Random-display-of-videos-in-a-question-2-YouTube.html&lt;br /&gt;
&lt;br /&gt;
=Randomly displaying one of a few pictures, and recording which was displayed=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.91+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The following steps allow you to randomly display one of a few pictures and record in the dataset which picture was displayed. We use four pictures in this example, but you can easily adapt these scripts according to your needs.&lt;br /&gt;
&lt;br /&gt;
1. Create a new sub-directory &#039;&#039;&#039;pic&#039;&#039;&#039; in your LimeSurvey folder.&lt;br /&gt;
&lt;br /&gt;
2. Copy four pictures (named &#039;&#039;1.jpg&#039;&#039;, &#039;&#039;2.jpg&#039;&#039;, &#039;&#039;3.jpg&#039;&#039;, and &#039;&#039;4.jpg&#039;&#039;) in this pic sub-directory.&lt;br /&gt;
&lt;br /&gt;
3. Deactivate the &#039;&#039;Filter HTML for XSS&#039;&#039; function in LimeSurvey&#039;s &#039;&#039;Global Settings&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
4. Create a &#039;&#039;&#039;Short free text&#039;&#039;&#039; question where you want these pictures to be displayed.&lt;br /&gt;
&lt;br /&gt;
5. Figure out the [[SGQA identifier|SGQA Identifier]] of this question (e.g., 12345X67X89).&lt;br /&gt;
&lt;br /&gt;
6. Paste the following code as question text after activating the editor&#039;s &#039;&#039;Source&#039;&#039; view and replace both SSSSSXGGXQQ strings with your SGQA identifier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please have a look at this picture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(&lt;br /&gt;
&lt;br /&gt;
function(){&lt;br /&gt;
&lt;br /&gt;
// Find a random number (here between 1 and 4)&lt;br /&gt;
&lt;br /&gt;
var randNumber = Math.floor(Math.random()*4 + 1);&lt;br /&gt;
&lt;br /&gt;
// Save the number as answer of this question&lt;br /&gt;
&lt;br /&gt;
$(&#039;input#answerSSSSSXGGXQQ&#039;).val(randNumber);&lt;br /&gt;
&lt;br /&gt;
// Hide this answer field&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&amp;quot;answerSSSSSXGGXQQ&amp;quot;).style.display=&#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
// Show the picture&lt;br /&gt;
&lt;br /&gt;
picString = &#039;&amp;lt;img src=&amp;quot;pic/&#039; + String(randNumber) + &#039;.jpg&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;pic&#039;).innerHTML = picString;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
);&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;pic&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to display the number of this picture in a later question, use the following code as question text (don&#039;t forget to replace the SSSSSXGGXQQ string acordingly):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You saw picture number {INSERTANS:SSSSSXGGXQQ}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perhaps you want to display the same picture again in a later question, but a little bit smaller (100px width, 100px height)? Just paste the following code as question text after activating the editor&#039;s &#039;&#039;Source&#039;&#039; view, and replace the SSSSSXGGXQQ string acordingly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here you see the picture again: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(&lt;br /&gt;
&lt;br /&gt;
function(){&lt;br /&gt;
&lt;br /&gt;
// Get the picture number from previous question&lt;br /&gt;
&lt;br /&gt;
var randNumber = &amp;quot;{INSERTANS:SSSSSXGGXQQ}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Show picture&lt;br /&gt;
&lt;br /&gt;
picString = &#039;&amp;lt;img width=&amp;quot;100&amp;quot; height=&amp;quot;100&amp;quot; src=&amp;quot;pic/&#039; + String(randNumber) + &#039;.jpg&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;pic&#039;).innerHTML = picString;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
);&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;pic&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple numerical input with max_num_value defined in token (personalized limit)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, max_num_value can be an experession, so you can simply enter the {TOKEN} or other variable in that question attribute.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make personalized survey with multiple numerical input when max_num_value (Maximum sum value) is different for each user and is loaded from the token use following tricks:&lt;br /&gt;
*Create 1st group with numerical input field (1000X10X11). &amp;quot;Limit&amp;quot;&lt;br /&gt;
*Add java script into this question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&#039;answer1000X10X11&#039;).value=&#039;{TOKEN:ATTRIBUTE_1}&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&#039;answer1000X10X11&#039;).readOnly=1;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
TOKEN:ATTRIBUTE_1 is individual limit defined in token.&lt;br /&gt;
&lt;br /&gt;
readOnly=1 // user shouldn&#039;t change it.&lt;br /&gt;
*Create 2nd group with multiple numerical input and add &amp;quot;Max value from SGQA&amp;quot; with 1000X10X11 as argument.&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t want to show first field with numerical input (and show definied limit in different way) you can add 2 lines to above script to hide whole question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;question85&#039;).style.display=&#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;display85&#039;).value=&#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
question85 and display85 are field names.&lt;br /&gt;
&lt;br /&gt;
Note: It&#039;s no possible to create it into one group, because all SGQA references can only refer to data on a previous page because when clicking next the answer is stored at the DB and the SGQA is replaced by querying the database.&lt;br /&gt;
&lt;br /&gt;
=Default values in array questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.87+ (7557), IE 6/7, Firefox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of Version 1.92, many more question types support default values.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to allow you to pre-check default answers in all sub-questions of an array type question. You can select a column of the array to be checked as the page loads. The script first checks to see if a sub-question has already been answered and, if not, checks the default answer.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use script]].&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following script.&lt;br /&gt;
#Replace&amp;quot;QQ&amp;quot; with the question ID and &amp;quot;CC&amp;quot; with the column number to be checked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // A function to pre-check a column of an array&lt;br /&gt;
&lt;br /&gt;
       function checkedDefault(qID, column) {&lt;br /&gt;
&lt;br /&gt;
           var checkedCol = column - 1;&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039; + qID + &#039; table.question tbody tr&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
               if ($(&#039;input.radio[checked=true]&#039;, this).length == 0) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;input.radio:eq(&#039; + checkedCol + &#039;)&#039;, this).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       // Call the function with a question ID and column number&lt;br /&gt;
&lt;br /&gt;
       checkedDefault(QQ, CC);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Record group view time=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.87+ (8518), IE 6/7, Firefox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, group view time is accurately recorded in the timings table if you choose the Record Timings survey option.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to populate a hidden question with the total time that a respondent views a group. If used in a group with only one question, it could be used to track the amount of time required to answer the question.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#In the group, create a short-text question. We will hide this later with JavaScript and populate it with the elapsed time.&lt;br /&gt;
#Place the following script in the source of the short-text question.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in line 6 with the ID of the short-text question.&lt;br /&gt;
&lt;br /&gt;
The script populates the hidden question with the elapsed time since the group was opened. If a respondent leaves the group and then returns, the timer continues up from the elapsed time of the last visit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
       // call the functions with the hidden timer question ID&lt;br /&gt;
&lt;br /&gt;
       runTimer(QQ);&lt;br /&gt;
&lt;br /&gt;
       function runTimer(timeQID) {&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+timeQID).hide();&lt;br /&gt;
&lt;br /&gt;
           var initSec = &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
           // Check for elapsed time from previous visits&lt;br /&gt;
&lt;br /&gt;
           if ($(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val()) {&lt;br /&gt;
&lt;br /&gt;
               var initTime = $(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               initTimeArr = initTime.split(&#039;:&#039;);&lt;br /&gt;
&lt;br /&gt;
               initSec = Number[[initTimeArr[0]*3600]]+Number[[initTimeArr[1]*60]]+Number(initTimeArr[2]);&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Run the timer update function&lt;br /&gt;
&lt;br /&gt;
           recordTime(initSec, timeQID);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Timer update function&lt;br /&gt;
&lt;br /&gt;
   function recordTime(elapsedSec, timeQID){&lt;br /&gt;
&lt;br /&gt;
       elapsedSec++;&lt;br /&gt;
&lt;br /&gt;
       var h = Math.floor(elapsedSec / 3600);&lt;br /&gt;
&lt;br /&gt;
       var m = Math.floor(elapsedSec % 3600 / 60);&lt;br /&gt;
&lt;br /&gt;
       var s = Math.floor(elapsedSec % 3600 % 60);&lt;br /&gt;
&lt;br /&gt;
       var elapsedTime = [[h &amp;gt; 0 ? h + &amp;quot;:&amp;quot; : &amp;quot;00:&amp;quot;) + (m &amp;gt; 0 ? (m &amp;lt; 10 ? &amp;quot;0&amp;quot; : &amp;quot;&amp;quot;) + m + &amp;quot;:&amp;quot; : &amp;quot;00:&amp;quot;) + (s &amp;lt; 10 ? &amp;quot;0&amp;quot; : &amp;quot;&amp;quot;) + s);&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val(elapsedTime);&lt;br /&gt;
&lt;br /&gt;
        // Run the timer update function every second&lt;br /&gt;
&lt;br /&gt;
        setTimeout(&#039;recordTime(&#039;+elapsedSec+&#039;, &#039;+timeQID+&#039;)&#039;,1000);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Toggle visibility of groups=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to toggle the visibility of groups in an &amp;quot;all in one&amp;quot; survey. Initially the groups are hidden and there are links inserted to display the groups. It&#039;s useful to avoid the page being cluttered with many groups and lets the respondent focus on one at a time.&lt;br /&gt;
&lt;br /&gt;
It&#039;s [http://www.partnersinc.biz/surveys//index.php?sid=33613&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Set the survey to run in &amp;quot;all in one&amp;quot; mode.&lt;br /&gt;
#Add your groups and questions.&lt;br /&gt;
#Place the following script in the source of one of the questions in the first group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The comments in the script are pretty self-explanatory but it does the following:&lt;br /&gt;
&lt;br /&gt;
#initially hides all of the groups&lt;br /&gt;
#inserts a link above each one to toggle its display&lt;br /&gt;
#some styles are added to the clickable links but these could be done in template.css instead&lt;br /&gt;
#shows any groups that have an unanswered mandatory after a submit attempt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
		// Insert show/hide divs before all group wrapper divs&lt;br /&gt;
		$(&#039;&amp;lt;div class=&amp;quot;groupToggler&amp;quot;&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;).insertBefore(&#039;div[id^=&amp;quot;group-&amp;quot;]&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Add some text to the show/hide divs&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).each(function(i) {&lt;br /&gt;
			($( this ).text(&#039;Show/Hide Group &#039;+(i+1)+&#039;&#039;));&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Add some styles to the show/hide divs&lt;br /&gt;
		$(&#039;.groupToggler&#039;).css({&lt;br /&gt;
			&#039;padding&#039;:&#039;5px 0 10px 0&#039;,&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).css({&lt;br /&gt;
			&#039;text-decoration&#039;:&#039;underline&#039;,			&lt;br /&gt;
			&#039;cursor&#039;:&#039;pointer&#039;&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Add some hover effects to the show/hide divs&lt;br /&gt;
		$(&amp;quot;.groupToggler span&amp;quot;).hover(&lt;br /&gt;
			function () {&lt;br /&gt;
				$(this).css({&lt;br /&gt;
					&#039;text-decoration&#039;:&#039;none&#039;,&lt;br /&gt;
					&#039;font-weight&#039;:&#039;bold&#039;&lt;br /&gt;
				});&lt;br /&gt;
			}, &lt;br /&gt;
			function () {&lt;br /&gt;
				$(this).css({&lt;br /&gt;
					&#039;text-decoration&#039;:&#039;underline&#039;,&lt;br /&gt;
					&#039;font-weight&#039;:&#039;normal&#039;&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
		);&lt;br /&gt;
		&lt;br /&gt;
		// Initially hide all of the groups&lt;br /&gt;
		// Toggle their visibility when the show/hide is clicked&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).click(function() {&lt;br /&gt;
			$(this).parent().next().toggle();&lt;br /&gt;
			return false;&lt;br /&gt;
		}).parent().next().hide();&lt;br /&gt;
		&lt;br /&gt;
		// Display any groups that have unanswered mandatories&lt;br /&gt;
		$(&#039;.errormandatory&#039;).parents(&#039;div[id^=&amp;quot;group-&amp;quot;]&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Some tidying up&lt;br /&gt;
		$(&#039;h1&#039;).next().next().hide();&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).css({&#039;margin-bottom&#039;:&#039;10px&#039;});&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).next().hide();&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).next().next().hide();&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use jQuery Autocomplete plugin to suggest answers for text inputs=&lt;br /&gt;
&lt;br /&gt;
== 1.90 and previous versions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://docs.jquery.com/Plugins/Autocomplete jQuery Autocomplete] plugin to provide a respondent a list of suggested answers that the they can select from as they type in a text input.&lt;br /&gt;
&lt;br /&gt;
Although the plugin allows for much more complex applications, the two that I use most frequently are outlined below. The first method uses a relatively small list of suggestions that is stored in an array locally. The second is a little more complex - it uses a remote CSV file of suggestions that is accessed through AJAX an PHP.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve put together a small demonstration [http://www.partnersinc.biz/surveys//index.php?sid=78611&amp;amp;newtest=Y&amp;amp;lang=en here] and implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Both methods:&#039;&#039;&#039;&lt;br /&gt;
*[http://docs.jquery.com/Plugins/Autocomplete Download the plugin]&lt;br /&gt;
*Place the files &#039;&#039;jquery.autocomplete.css&#039;&#039; and &#039;&#039;jquery.autocomplete.js&#039;&#039; in your template directory&lt;br /&gt;
*Add the following code inside the &amp;lt;head&amp;gt; element of startpage.pstpl&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autocomplete.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;{TEMPLATEURL}jquery.autocomplete.css&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 1 (&amp;quot;States&amp;quot; question in the demo):&#039;&#039;&#039;&lt;br /&gt;
*Create a text input question&lt;br /&gt;
*Add the following script to the source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace the states with your list of suggestions (comma separated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var q1ID = QQ;&lt;br /&gt;
&lt;br /&gt;
		var states = &amp;quot;Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware, District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky, Louisiana,Maine,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York, North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Maryland,Massachusetts,Michigan, Minnesota,Mississippi,Missouri,Pennsylvania,Rhode Island,South Carolina,South Dakota, Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming&amp;quot;.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.text&#039;).autocomplete(states, {&lt;br /&gt;
			matchContains: true,&lt;br /&gt;
			minChars: 0&lt;br /&gt;
		});&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 2 (&amp;quot;Countries&amp;quot; question in the demo):&#039;&#039;&#039;&lt;br /&gt;
*Place the CSV file of suggestions in your template directory. &lt;br /&gt;
*Place a PHP file containing the code below in your template directory&lt;br /&gt;
*Replace &amp;quot;countries2.csv&amp;quot; with your CSV filename (you could make this more universal by passing the filename in the URL)&lt;br /&gt;
*This file will grab the contents of the CSV and encode them in JSON format that the JavaScript can use&lt;br /&gt;
*Place the JavaScript code below in ths source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace &amp;quot;templates/yourTemplate/countries.php&amp;quot; with the path to the PHP file (from LimeSurvey root)&lt;br /&gt;
*This script will grab the jsonized data from the PHP file and load it into an array that the plugin can use&lt;br /&gt;
&lt;br /&gt;
PHP code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
	$countriesArr = array();&lt;br /&gt;
&lt;br /&gt;
	$file_handle = fopen(&amp;quot;countries2.csv&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	while (!feof($file_handle) ) {&lt;br /&gt;
		$line_of_text = fgetcsv($file_handle);&lt;br /&gt;
		array_push($countriesArr, $line_of_text[0]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose($file_handle);&lt;br /&gt;
&lt;br /&gt;
	echo json_encode($countriesArr);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qID = QQ;&lt;br /&gt;
		var url = &amp;quot;templates/yourTemplate/countries.php&amp;quot;;&lt;br /&gt;
		var countriesArr = new Array();&lt;br /&gt;
&lt;br /&gt;
		$.getJSON(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			$(data).each(function(i, item){&lt;br /&gt;
				countriesArr.push(item);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#question&#039;+qID+&#039; input.text&#039;).autocomplete(countriesArr, {&lt;br /&gt;
				matchContains: true,&lt;br /&gt;
				minChars: 0&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.91 and later versions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://jqueryui.com/demos/autocomplete/ Autocomplete widget] included with jQuery UI to provide a respondent a list of suggested answers that the they can select from as they type in a text input.&lt;br /&gt;
&lt;br /&gt;
Although the plugin allows for much more complex applications, the two that I use most frequently are outlined below. The first method uses a relatively small list of suggestions that is stored in an array locally. The second is a little more complex - it uses a remote CSV file of suggestions that is accessed through AJAX an PHP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Both methods:&#039;&#039;&#039;&lt;br /&gt;
*Add the following styles to the end of your &#039;template.css&#039; file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;/* Autocomplete styles */&lt;br /&gt;
&lt;br /&gt;
ul.ui-autocomplete {&lt;br /&gt;
	width: 250px !important;&lt;br /&gt;
	padding: 5px 10px;&lt;br /&gt;
	list-style: none;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 1 (use local JavaScript array for data):&#039;&#039;&#039;&lt;br /&gt;
*Create a text input question&lt;br /&gt;
*Add the following script to the source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace the states with your list of suggestions (comma separated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var q1ID = QQ;&lt;br /&gt;
&lt;br /&gt;
		var states = &amp;quot;Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware, District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky, Louisiana,Maine,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York, North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Maryland,Massachusetts,Michigan, Minnesota,Mississippi,Missouri,Pennsylvania,Rhode Island,South Carolina,South Dakota, Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming&amp;quot;.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
			source: states&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 2 (use remote CSV file for data):&#039;&#039;&#039;&lt;br /&gt;
*Place the CSV file of suggestions in your template directory&lt;br /&gt;
*Place a PHP file containing the code below in your template directory&lt;br /&gt;
*Replace &amp;quot;countries2.csv&amp;quot; with your CSV filename (you could make this more universal by passing the filename in the URL)&lt;br /&gt;
*This file will grab the contents of the CSV and encode them in JSON format that the JavaScript can use&lt;br /&gt;
*Place the JavaScript code below in ths source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace &amp;quot;templates/yourTemplate/countries.php&amp;quot; with the path to the PHP file (from LimeSurvey root)&lt;br /&gt;
*This script will grab the jsonized data from the PHP file and load it into an array that the plugin can use&lt;br /&gt;
&lt;br /&gt;
PHP code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
	$countriesArr = array();&lt;br /&gt;
&lt;br /&gt;
	$file_handle = fopen(&amp;quot;countries2.csv&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	while (!feof($file_handle) ) {&lt;br /&gt;
		$line_of_text = fgetcsv($file_handle);&lt;br /&gt;
		array_push($countriesArr, $line_of_text[0]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose($file_handle);&lt;br /&gt;
&lt;br /&gt;
	echo json_encode($countriesArr);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qID = QQ;&lt;br /&gt;
		var url = &amp;quot;templates/yourTemplate/countries.php&amp;quot;;&lt;br /&gt;
		var dataArr = [];&lt;br /&gt;
&lt;br /&gt;
		$.getJSON(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			$.each(data,function(i, item){&lt;br /&gt;
				dataArr.push(item);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#question&#039;+qID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
				source: dataArr&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Use autocomplete to populate several fields==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, IE 7/8/9, Firefox 18&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://jqueryui.com/demos/autocomplete/ Autocomplete widget] included with jQuery UI and the [https://code.google.com/p/jquery-csv/source/browse/jquery.csv.js?r=f13189b2550a770ccaa777f1d747bc860b943fe7 jquery.csv.js] plugin to provide a respondent with a list of suggested answers as they type in a text input and then to automatically populate other fields depending on the selection.&lt;br /&gt;
&lt;br /&gt;
For example, if you have 3 questions - &amp;quot;Name&amp;quot;, &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; - you can use this workaround to autocomplete the &amp;quot;Name&amp;quot; question and then the &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; questions can be automatically populated with values associated with the selected name.&lt;br /&gt;
*Download the [https://code.google.com/p/jquery-csv/source/browse/jquery.csv.js?r=f13189b2550a770ccaa777f1d747bc860b943fe7 jquery.csv.js] plugin and place it in your template folder&lt;br /&gt;
*If using LimeSurvey 1.9x, add the following line to your startpage.pstpl BEFORE the tag for template.js, if using 2.x, add it AFTER the {TEMPLATEJS} placeholder&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.csv.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Create your CSV file with 3 columns (name, ID, email) as in this example and place it in your template folder&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Bob,    Bob&#039;s ID,    Bob&#039;s email&lt;br /&gt;
&lt;br /&gt;
Andy,    Andy&#039;s ID,    Andy&#039;s email&lt;br /&gt;
&lt;br /&gt;
Sam,    Sam&#039;s ID,    Sam&#039;s email&lt;br /&gt;
&lt;br /&gt;
Tony,    Tony&#039;s ID,    Tony&#039;s email&lt;br /&gt;
&lt;br /&gt;
Fred,    Fred&#039;s ID,    Fred&#039;s email&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Create your 3 questions - &amp;quot;Name&amp;quot;, &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot;. They must be in the same group/page.&lt;br /&gt;
*Add the following styles to the end of your &#039;template.css&#039; file&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;/* Autocomplete styles */&lt;br /&gt;
&lt;br /&gt;
ul.ui-autocomplete {&lt;br /&gt;
&lt;br /&gt;
   width: 250px !important;&lt;br /&gt;
&lt;br /&gt;
   padding: 5px 10px;&lt;br /&gt;
&lt;br /&gt;
   list-style: none;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Add the following script to the source of one of the questions&lt;br /&gt;
*Replace:&lt;br /&gt;
**&amp;quot;NN&amp;quot; with the &amp;quot;Name&amp;quot; question ID&lt;br /&gt;
**&amp;quot;II&amp;quot; with the &amp;quot;ID&amp;quot; question ID&lt;br /&gt;
**&amp;quot;EE&amp;quot; with the &amp;quot;Email&amp;quot; question ID&lt;br /&gt;
*Modify the path to your CSV file&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qNameID = NN;&lt;br /&gt;
&lt;br /&gt;
		var qIDID = II;&lt;br /&gt;
&lt;br /&gt;
		var qEmailID = EE;&lt;br /&gt;
&lt;br /&gt;
		var url = &amp;quot;upload/templates/yourTemplate/yourCsvFile.csv&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		// Create an array to hold the names&lt;br /&gt;
		var namesArr = new Array();&lt;br /&gt;
&lt;br /&gt;
		// Grab the CSV contents&lt;br /&gt;
		$.get(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			// Convert CSV contents to an array of arrays&lt;br /&gt;
			fullArray = $.csv.toArrays(data);&lt;br /&gt;
&lt;br /&gt;
			// Load the names array&lt;br /&gt;
			$(fullArray).each(function(i, item){&lt;br /&gt;
				namesArr.push(item[0]);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Initialise the autocomplete plugin&lt;br /&gt;
			$(&#039;#question&#039;+qNameID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
				source: namesArr,&lt;br /&gt;
				// Event fired when a selection is made (ui.item.value refers to the selected item)&lt;br /&gt;
				select: function(event, ui) {&lt;br /&gt;
					// Find the &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; values associated with the selected name value and load those questions&lt;br /&gt;
					$(fullArray).each(function(i, item){&lt;br /&gt;
						if(item[0] == ui.item.value) {&lt;br /&gt;
							// The value from column 2 of the CSV&lt;br /&gt;
							$(&#039;#question&#039;+qIDID+&#039; input.text&#039;).val(item[1]);&lt;br /&gt;
							// The value from column 3 of the CSV&lt;br /&gt;
							$(&#039;#question&#039;+qEmailID+&#039; input.text&#039;).val(item[2]);&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Drag and Drop Rankings {{Deprecated|2.0}} =&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }} &lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking - Version 1.90 to 1.92==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+ &amp;amp; 1.91RC4, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }} &lt;br /&gt;
&lt;br /&gt;
This workaround is a modification of the workaround below and also uses [http://jqueryui.com/demos/sortable/#connect-lists JQuery connected sortables]. Thanks to the author of that workaround.&lt;br /&gt;
&lt;br /&gt;
[[File:Untitled-12.png]]&lt;br /&gt;
&lt;br /&gt;
Modifications include:&lt;br /&gt;
*Allow for multiple drag-n-drop ranking questions on a page&lt;br /&gt;
*Handle minimum and maximum answers settings&lt;br /&gt;
*Allow double clicking of items to add or remove them from the ranking list&lt;br /&gt;
*Work with the new shipped jQuery UI&lt;br /&gt;
&lt;br /&gt;
There is a &#039;&#039;&#039;[http://www.partnersinc.biz/surveys//index.php?sid=36981&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the large script below in your template.js file.&lt;br /&gt;
#Place the small script below in the source a ranking question, (this applies the &amp;quot;dragDropRank&amp;quot; function to the question). Replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID].&lt;br /&gt;
**Note: the LimeSurvey translations will be automatically used for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; header labels but can be overridden with custom labels - see the example calls below.&lt;br /&gt;
#Insert the CSS below at the end of template.css (these styles are for the default template).&lt;br /&gt;
&lt;br /&gt;
NOTE: I have not tested this workaround with conditions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code for template.js:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
function dragDropRank(qID, choiceText, rankText) {&lt;br /&gt;
&lt;br /&gt;
	if(!choiceText) {&lt;br /&gt;
		choiceText = $(&#039;#question&#039;+qID+&#039; td.label label&#039;).text();&lt;br /&gt;
	}&lt;br /&gt;
	if(!rankText) {&lt;br /&gt;
		rankText = $(&#039;#question&#039;+qID+&#039; td.output tr:first td:eq(1)&#039;).text();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Add a class to the question&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039;&#039;).addClass(&#039;dragDropRanking&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Hide the original question in LimeSurvey (so that we can replace with drag and drop)&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; .rank, #question&#039;+qID+&#039; .questionhelp&#039;).hide();&lt;br /&gt;
	&lt;br /&gt;
	// Turn off display of question (to override error checking built into LimeSurvey ranking question)&lt;br /&gt;
	//$(&#039;#display&#039;+qID).val(&#039;off&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Add connected sortables elements to the question&lt;br /&gt;
	var htmlCode = &#039;&amp;lt;table class=&amp;quot;dragDropTable&amp;quot;&amp;gt; \&lt;br /&gt;
		&amp;lt;tbody&amp;gt; \&lt;br /&gt;
			&amp;lt;tr&amp;gt; \&lt;br /&gt;
				&amp;lt;td&amp;gt; \&lt;br /&gt;
					&amp;lt;span class=&amp;quot;dragDropHeader choicesLabel&amp;quot;&amp;gt;&#039;+choiceText+&#039;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt; \&lt;br /&gt;
					&amp;lt;div class=&amp;quot;ui-state-highlight dragDropChoices&amp;quot;&amp;gt; \&lt;br /&gt;
						&amp;lt;ul id=&amp;quot;sortable1&#039;+qID+&#039;&amp;quot; class=&amp;quot;connectedSortable&#039;+qID+&#039; dragDropChoiceList&amp;quot;&amp;gt; \&lt;br /&gt;
							&amp;lt;li&amp;gt;Choices&amp;lt;/li&amp;gt; \&lt;br /&gt;
						&amp;lt;/ul&amp;gt; \&lt;br /&gt;
					&amp;lt;/div&amp;gt; \&lt;br /&gt;
				&amp;lt;/td&amp;gt; \&lt;br /&gt;
				&amp;lt;td&amp;gt; \&lt;br /&gt;
					&amp;lt;span class=&amp;quot;dragDropHeader rankingLabel&amp;quot;&amp;gt;&#039;+rankText+&#039;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt; \&lt;br /&gt;
					&amp;lt;div class=&amp;quot;ui-state-highlight dragDropRanks&amp;quot;&amp;gt; \&lt;br /&gt;
						&amp;lt;ol id=&amp;quot;sortable2&#039;+qID+&#039;&amp;quot; class=&amp;quot;connectedSortable&#039;+qID+&#039; dragDropRankList&amp;quot;&amp;gt; \&lt;br /&gt;
							&amp;lt;li&amp;gt;Ranks&amp;lt;/li&amp;gt; \&lt;br /&gt;
						&amp;lt;/ol&amp;gt; \&lt;br /&gt;
					&amp;lt;/div&amp;gt; \&lt;br /&gt;
				&amp;lt;/td&amp;gt; \&lt;br /&gt;
			&amp;lt;/tr&amp;gt; \&lt;br /&gt;
		&amp;lt;/tbody&amp;gt; \&lt;br /&gt;
					&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
	$(htmlCode).insertAfter(&#039;#question&#039;+qID+&#039; table.rank&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Remove placeholder list items (have to have one item so that LimeSurvey doesn&amp;quot;t remove the &amp;lt;ul&amp;gt;)&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li, #sortable2&#039;+qID+&#039; li&#039;).remove();&lt;br /&gt;
	&lt;br /&gt;
	// Load any previously-set values&lt;br /&gt;
	loadDragDropRank(qID);&lt;br /&gt;
	&lt;br /&gt;
	// Find the number of LimeSurvey ranking inputs (&amp;quot;Maximum answers&amp;quot;)&lt;br /&gt;
	var maxAnswer = $(&#039;#question&#039;+qID+&#039; td.output input.text&#039;).length;&lt;br /&gt;
	&lt;br /&gt;
	// Set up the connected sortable&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039;, #sortable2&#039;+qID+&#039;&#039;).sortable({&lt;br /&gt;
		connectWith: &#039;.connectedSortable&#039;+qID+&#039;&#039;,&lt;br /&gt;
		placeholder: &#039;ui-sortable-placeholder&#039;,&lt;br /&gt;
		helper: &#039;clone&#039;,&lt;br /&gt;
		revert: 50,&lt;br /&gt;
		receive: function(event, ui) {&lt;br /&gt;
			if($(&#039;#sortable2&#039;+qID+&#039; li&#039;).length &amp;gt; maxAnswer) {&lt;br /&gt;
				alert (&#039;You can only rank a maximum of &#039;+maxAnswer+&#039; choices.&#039;);&lt;br /&gt;
				$(ui.sender).sortable(&#039;cancel&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		stop: function(event, ui) {&lt;br /&gt;
			$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			updateDragDropRank(qID);&lt;br /&gt;
		}&lt;br /&gt;
	}).disableSelection();&lt;br /&gt;
	&lt;br /&gt;
	// Get the list of choices from the LimeSurvey question and copy them as items into the sortable choices list&lt;br /&gt;
	$(&#039;#CHOICES_&#039; + qID).children().each(function(index, Element) {&lt;br /&gt;
		var liCode = &#039;&amp;lt;li class=&amp;quot;ui-state-default&amp;quot; id=&amp;quot;choice_&#039; + $(this).attr(&amp;quot;value&amp;quot;) + &#039;&amp;quot;&amp;gt;&#039; + this.text + &#039;&amp;lt;/li&amp;gt;&#039;&lt;br /&gt;
		$(liCode).appendTo(&#039;#sortable1&#039;+qID+&#039;&#039;);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Allow users to double click to move to selections from list to list&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li&#039;).live(&#039;dblclick&#039;, function() {&lt;br /&gt;
		if($(&#039;#sortable2&#039;+qID+&#039; li&#039;).length == maxAnswer) {&lt;br /&gt;
			alert (&#039;You can only rank a maximum of &#039;+maxAnswer+&#039; choices.&#039;);&lt;br /&gt;
			return false;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(this).appendTo(&#039;#sortable2&#039;+qID+&#039;&#039;);&lt;br /&gt;
			$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			updateDragDropRank(qID);&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	$(&#039;#sortable2&#039;+qID+&#039; li&#039;).live(&#039;dblclick&#039;, function() {&lt;br /&gt;
		$(this).appendTo(&#039;#sortable1&#039;+qID+&#039;&#039;);&lt;br /&gt;
		$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
		$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
		updateDragDropRank(qID);&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function copies the drag and drop sortable data into the LimeSurvey ranking list.&lt;br /&gt;
function updateDragDropRank(qID) {&lt;br /&gt;
&lt;br /&gt;
	// Reload the LimeSurvey choices select element&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	$(&#039;#sortable2&#039;+qID+&#039; li&#039;).each(function(index) {&lt;br /&gt;
		$(this).attr(&#039;value&#039;, index+1);&lt;br /&gt;
		&lt;br /&gt;
		// Get value of ranked item&lt;br /&gt;
		var liID = $(this).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Save to an array&lt;br /&gt;
		rankees[rankees.length] = { &amp;quot;r_name&amp;quot;:$(this).text(),&amp;quot;r_value&amp;quot;:liIDArray[1] };&lt;br /&gt;
	});&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
		if (rankees.length &amp;gt; index) {&lt;br /&gt;
			$(this).val(rankees[index].r_name);&lt;br /&gt;
			$(this).next(&#039;input&#039;).attr(&#039;value&#039;, rankees[index].r_value);&lt;br /&gt;
		} else {&lt;br /&gt;
			$(this).val(&#039;&#039;);&lt;br /&gt;
			$(this).next().val(&#039;&#039;);&lt;br /&gt;
		}&lt;br /&gt;
	 });&lt;br /&gt;
	 &lt;br /&gt;
	// Reload the LimeSurvey choices select element (we need this for &amp;quot;Minimum answers&amp;quot; code)&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; td.label select option&#039;).remove();&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li&#039;).each(function(index) {&lt;br /&gt;
		var liText = $(this).text();&lt;br /&gt;
		var liID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		var optionCode = &#039;&amp;lt;option value=&amp;quot;&#039;+liIDArray[1]+&#039;&amp;quot;&amp;gt;&#039;+liText+&#039;&amp;lt;/option&amp;gt;&#039;;&lt;br /&gt;
		$(optionCode).appendTo(&#039;#question&#039;+qID+&#039; td.label select&#039;);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Hack for IE6&lt;br /&gt;
	if ($.browser.msie &amp;amp;&amp;amp; $.browser.version.substr(0,1)&amp;lt;7) {&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; select&#039;).show();&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; select&#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function is called on page load to see if there are any items already ranked (from a previous visit&lt;br /&gt;
// or cached due to a page change.  If so, the already-ranked items are loaded into the sortable list&lt;br /&gt;
function loadDragDropRank(qID) {&lt;br /&gt;
&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	&lt;br /&gt;
	// Loop through each item in the built-in LimeSurvey ranking list looking for non-empty values&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;/div&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
	&lt;br /&gt;
		// Check to see if the current item has a value&lt;br /&gt;
		if ($(this).val()) {&lt;br /&gt;
		&lt;br /&gt;
			// Item has a value - save to the array&lt;br /&gt;
			// Use this element to contain the name and the next for the value (numeric)&lt;br /&gt;
			rankees[rankees.length] = { &amp;quot;r_name&amp;quot;:$(this).val(),&amp;quot;r_value&amp;quot;:$(this).next().val() };&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Now that we have a list of all the pre-ranked items, populate the sortable list&lt;br /&gt;
	// Note that the items *won&amp;quot;t* appear in the main list because LimeSurvey has removed them.&lt;br /&gt;
	$.each(rankees, function(index, value) {&lt;br /&gt;
	&lt;br /&gt;
		// Create the items in the sortable&lt;br /&gt;
		var liCode = &#039;&amp;lt;li class=&amp;quot;ui-state-default&amp;quot; id=&amp;quot;choice_&#039; + value.r_value + &#039;&amp;quot;&amp;gt;&#039; + value.r_name + &#039;&amp;lt;/li&amp;gt;&#039;;&lt;br /&gt;
		$(liCode).appendTo(&#039;#sortable2&#039;+qID+&#039;&#039;);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s) using the LimeSurvey translations for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; element header labels&#039;&#039;&#039; (replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRank(QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix for later versions of 1.91+&#039;&#039;&#039;&lt;br /&gt;
In my version of LimeSurvey 1.91+, build 11026, this drag-n-drop workaround was not saving the selections properly. I&#039;m not sure if that&#039;s because of my template, or other jquery uses, but I fixed it by making the following modifications to the above code placed into template.js.&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having problems (and it&#039;s definitely worth testing that the rankings are actually saving into your response table before proceeding with the survey) give this a try.&lt;br /&gt;
&lt;br /&gt;
In the &#039;updateDragDropRank(qID)&#039; function, replace the line:&lt;br /&gt;
&amp;lt;syntaxhighlight  lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name^=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the &#039;loadDragDropRank(qID) function, replace the line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;/div&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name^=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s) using custom text for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; element header labels&#039;&#039;&#039; (replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRank(QQ, &#039;Custom Choices Label&#039;, &#039;Custom Rankings Label&#039;);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Styles for template.css:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
/* Drag-n-drop ranking styles */&lt;br /&gt;
.dragDropTable {&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable td {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	width: 50%;&lt;br /&gt;
	padding-right: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropHeader {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoices,&lt;br /&gt;
.dragDropTable .dragDropRanks {&lt;br /&gt;
	margin: 5px 0 0 0;&lt;br /&gt;
	background: transparent none;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoiceList,&lt;br /&gt;
.dragDropTable .dragDropRankList {&lt;br /&gt;
	float: left;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	min-height: 2.4em;&lt;br /&gt;
	_height: 2.4em; /* IE6 and below hack */&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	list-style-type: none;&lt;br /&gt;
	background: #FBFBFB none;&lt;br /&gt;
	border: 1px solid #CCCCCC;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoiceList li,&lt;br /&gt;
.dragDropTable .dragDropRankList li {&lt;br /&gt;
	margin: 3px;&lt;br /&gt;
	*margin-left: -13px; /* IE7 and below */&lt;br /&gt;
	padding: 3px;&lt;br /&gt;
	min-height: 1.3em;&lt;br /&gt;
	_height: 1.3em; /* IE6 and below hack */&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	cursor: move;&lt;br /&gt;
	display: block; /* Force the li to full width */&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking using Images - Version 1.90 to 1.92==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+ &amp;amp; 1.91RC4, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }}&lt;br /&gt;
&lt;br /&gt;
This workaround works in conjunction with the above workaround to allow ranking of images.&lt;br /&gt;
&lt;br /&gt;
[[File:Untitled-11.png]]&lt;br /&gt;
&lt;br /&gt;
There is a &#039;&#039;&#039;[http://www.partnersinc.biz/surveys//index.php?sid=36981&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
1) Follow the above workaround to get basic drag-n-drop functionality in your ranking question.&lt;br /&gt;
&lt;br /&gt;
2) Insert your images in the ranking question text or help section after any text that you wish to have there (we&#039;ll move them later with JavaScript).&lt;br /&gt;
&lt;br /&gt;
3) Give the images &#039;&#039;&#039;EXACTLY&#039;&#039;&#039; the same IDs as the answer code you would like them to be associated with:[[File:Untitled-8.png]]&lt;br /&gt;
&lt;br /&gt;
4) Place the first script below in your template.js file.&lt;br /&gt;
&lt;br /&gt;
5) Place the second script below in the source the ranking question &#039;&#039;&#039;AFTER&#039;&#039;&#039; the initial call for the dragDropRank function from the workaround above. Replace &amp;quot;QQ&amp;quot; with the ID of the ranking question (this applies the &amp;quot;dragDropRankImages&amp;quot; function to the question).&lt;br /&gt;
&lt;br /&gt;
6) Insert the CSS below at the end of template.css. Replace &amp;quot;11&amp;quot; with your question ID. These styles are for the default template using 50x50px images (as in the demo) and may need to be modified for other templates or image sizes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code for template.js:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function dragDropRankImages(qID) {&lt;br /&gt;
&lt;br /&gt;
	$(&#039;.connectedSortable&#039;+qID+&#039; li&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
		// Remove any text in the sortable choice or rank items&lt;br /&gt;
		$(this).text(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Move the images into the appropriate sortable list item&lt;br /&gt;
		var liID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; img#&#039;+liIDArray[1]+&#039;&#039;).appendTo(this);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRankImages(QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Styles for template.css:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Drag-n-drop for ranking images */&lt;br /&gt;
#question11 .dragDropTable {&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable .dragDropChoiceList,&lt;br /&gt;
#question11 .dragDropTable .dragDropRankList {&lt;br /&gt;
	min-height: 60px;&lt;br /&gt;
	_height: 60px; /* IE6 and below hack */&lt;br /&gt;
	width: auto;&lt;br /&gt;
	min-width: 60px;&lt;br /&gt;
	_width: 60px; /* IE6 and below hack */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable li {&lt;br /&gt;
	background: 0 none;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
	height: 50px;&lt;br /&gt;
	width: 50px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable li img {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking for iPad - Version 1.91 and newer==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LimeSurvey 1.91, iPad 2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround extends the above workarounds to work with the touch interface on iPads.&lt;br /&gt;
&lt;br /&gt;
1) Follow the [[Workarounds: Manipulating a survey at runtime using Javascript#Drag and Drop Ranking - Version 1.90 and newer|Drag and Drop Ranking - Version 1.90 and newer]] workaround above to get basic drag-n-drop functionality in your ranking question.&lt;br /&gt;
&lt;br /&gt;
2) Download the [https://github.com/furf/jquery-ui-touch-punch jQuery.ui.touch-punch.js plugin] and save it in your template directory.&lt;br /&gt;
&lt;br /&gt;
3) Replace this line in your startpage.pstpl:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}template.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;With this:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.ui.touch-punch.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}template.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking - Version 1.86==&lt;br /&gt;
&lt;br /&gt;
Tested with 1.86 on IE 7,8, FireFox 3, Chrome, and Safari 4&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }}&lt;br /&gt;
&lt;br /&gt;
This workaround uses [http://jqueryui.com/demos/sortable/#connect-lists JQuery connected sortables] to modify a ranking question and allow the survey taker to drag and drop choices instead of clicking.  The nice thing is that the choices can be easily re-arranged or removed from the ranking, all by drag and drop.&lt;br /&gt;
&lt;br /&gt;
I used it for a voting application and some of the element names reflect that use.&lt;br /&gt;
&lt;br /&gt;
It looks best when some CSS is added to control the appearance of the boxers around each choice.&lt;br /&gt;
&lt;br /&gt;
[[File:drag-n-drop.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
	// Question ID global variable&lt;br /&gt;
	var questionID;&lt;br /&gt;
	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
	&lt;br /&gt;
		// Grab the question ID[[File:drag-n-drop.png]]&lt;br /&gt;
		// This is something with a class of &amp;quot;ranking&amp;quot; and an ID that starts with &amp;quot;questionXXXXX&amp;quot;.  The X&#039;s represent the question ID&lt;br /&gt;
		var entire_questionID = $(&amp;quot;.ranking[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&#039;question&#039;]&amp;quot;).attr(&#039;id&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Get just the question number (ID)&lt;br /&gt;
		var patt=/\d+$/;&lt;br /&gt;
		questionID=patt.exec(entire_questionID);&lt;br /&gt;
		&lt;br /&gt;
		// Hide the original quetion in LimeSurvey (so that we can replace with drag and drop)&lt;br /&gt;
		$(&amp;quot;.rank, .questionhelp&amp;quot;).hide();&lt;br /&gt;
		&lt;br /&gt;
		// Turn off display of question (to override error checking built into LimeSurvey ranking question)&lt;br /&gt;
		$(&amp;quot;#display&amp;quot;+questionID).val(&amp;quot;off&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Add connected sortables to the question&lt;br /&gt;
		var html_code = &amp;quot;&amp;lt;table style=&#039;border: medium none ; width: 770px; margin-left: auto; \&lt;br /&gt;
								margin-right: auto;&#039;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&#039;width: 590px; vertical-align: top;&#039;&amp;gt;&amp;lt;h3&amp;gt;List of Candidates:&amp;lt;/h3&amp;gt; \&lt;br /&gt;
								&amp;lt;div class=&#039;ui-state-highlight&#039; style=&#039;margin: 5px; float: left;&#039; id=&#039;ballot_list&#039;&amp;gt; \&lt;br /&gt;
								&amp;lt;ul id=&#039;sortable1&#039; class=&#039;connectedSortable&#039;&amp;gt;&amp;lt;li&amp;gt;Candidates&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt; \&lt;br /&gt;
								&amp;lt;td style=&#039;vertical-align: top;&#039;&amp;gt;&amp;lt;h3&amp;gt;Your selections:&amp;lt;/h3&amp;gt;&amp;lt;div class=&#039;ui-state-highlight&#039; \&lt;br /&gt;
								style=&#039;margin: 5px; float: left;&#039; id=&#039;voting_selections&#039;&amp;gt;&amp;lt;ol id=&#039;sortable2&#039; class=&#039;connectedSortable&#039;&amp;gt; \&lt;br /&gt;
								&amp;lt;li&amp;gt;Voting Area&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;;&lt;br /&gt;
		$(html_code).appendTo(&amp;quot;#question&amp;quot; + questionID);&lt;br /&gt;
		&lt;br /&gt;
		// Remove list items (have to have one item so that LimeSurvey doesn&#039;t remove the &amp;lt;ul&amp;gt;)&lt;br /&gt;
		$(&amp;quot;#sortable1 li, #sortable2 li&amp;quot;).remove();&lt;br /&gt;
		&lt;br /&gt;
		// Load any previously-set values&lt;br /&gt;
		loadRanking();&lt;br /&gt;
		&lt;br /&gt;
		// Load jQuery UI&lt;br /&gt;
		$.getScript(&amp;quot;/scripts/jquery/jquery-ui.js&amp;quot;, function() {&lt;br /&gt;
		&lt;br /&gt;
			// After JQuery UI finishes loading, set up the connected sortable.&lt;br /&gt;
			$(&amp;quot;#sortable1, #sortable2&amp;quot;).sortable({&lt;br /&gt;
				connectWith: &#039;.connectedSortable&#039;,&lt;br /&gt;
				placeholder: &#039;ui-sortable-placeholder&#039;,&lt;br /&gt;
				stop: function(event, ui) {&lt;br /&gt;
					$(&amp;quot;#sortable1&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
					$(&amp;quot;#sortable2&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
					updateRanking();&lt;br /&gt;
					}&lt;br /&gt;
			}).disableSelection();&lt;br /&gt;
			&lt;br /&gt;
			// Get the list of candidates from the built-in LimeSurvey question and copy them as items in sortable1&lt;br /&gt;
			$(&amp;quot;#CHOICES_&amp;quot; + questionID).children().each(function(index, Element) {&lt;br /&gt;
				li_tag = &amp;quot;&amp;lt;li class=&#039;ui-state-default&#039; id=&#039;choice_&amp;quot; + $(this).attr(&#039;value&#039;) + &amp;quot;&#039;&amp;gt;&amp;quot; + this.text + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;&lt;br /&gt;
				$(li_tag).appendTo(&amp;quot;#sortable1&amp;quot;); }	);&lt;br /&gt;
				&lt;br /&gt;
			// Make sure the submit button is showing&lt;br /&gt;
			$(&amp;quot;:submit[value|=&#039; Submit&#039;]&amp;quot;).show();&lt;br /&gt;
			&lt;br /&gt;
			// Show a confirmation alert upon submit&lt;br /&gt;
			$(&amp;quot;form&amp;quot;).submit(function() {&lt;br /&gt;
			&lt;br /&gt;
				// Override the built-in &amp;quot;disable navigation buttons&amp;quot; feature&lt;br /&gt;
				$(&#039;#moveprevbtn, #movenextbtn, #movesubmitbtn&#039;).attr(&#039;disabled&#039;, &#039;&#039;);&lt;br /&gt;
				var validated = confirm(&amp;quot;Cast your ballot now?&amp;quot;);&lt;br /&gt;
				if (validated) { return true; } else { return false; }&lt;br /&gt;
			});&lt;br /&gt;
			&lt;br /&gt;
			// Allow users to double click to move to selection list&lt;br /&gt;
			$(&amp;quot;#sortable1 li&amp;quot;).assignDblClick();&lt;br /&gt;
		});  // End of JQuery UI loading&lt;br /&gt;
		&lt;br /&gt;
	}); // End of JQuery ready function&lt;br /&gt;
	&lt;br /&gt;
// Define the actions when an item is double clicked&lt;br /&gt;
$.fn.assignDblClick = function() {&lt;br /&gt;
	$(this).dblclick(function(){&lt;br /&gt;
		$(this).appendTo(&#039;#sortable2&#039;);&lt;br /&gt;
		$(&amp;quot;#sortable1&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
		$(&amp;quot;#sortable2&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
		updateRanking();&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function copies the drag and drop sortable data into the standard LimeSurvey ranking structure.&lt;br /&gt;
function updateRanking() {&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	$(&#039;#sortable2 li&#039;).each(function(index) {&lt;br /&gt;
	$(this).attr(&amp;quot;value&amp;quot;, index+1);&lt;br /&gt;
	&lt;br /&gt;
		// Get value of person&lt;br /&gt;
		li_tag = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		li_tag_array = li_tag.split(&amp;quot;_&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Save to an array&lt;br /&gt;
		rankees[rankees.length] = { &#039;r_name&#039;:$(this).text(),&#039;r_value&#039;:li_tag_array[1] };&lt;br /&gt;
	});&lt;br /&gt;
	$(&amp;quot;input[name&amp;lt;/div&amp;gt;=&#039;RANK_&#039;]&amp;quot;).each(function(index) {&lt;br /&gt;
		if (rankees.length &amp;gt; index) {&lt;br /&gt;
			$(this).val(rankees[index].r_name);&lt;br /&gt;
			$(this).next().val(rankees[index].r_value);&lt;br /&gt;
		} else {&lt;br /&gt;
			$(this).val(&amp;quot;&amp;quot;);&lt;br /&gt;
			$(this).next().val(&amp;quot;&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	 });&lt;br /&gt;
	 &lt;br /&gt;
	// Re-assign double click action to first list items and remove&lt;br /&gt;
	// double click action from section list items&lt;br /&gt;
	$(&#039;#sortable1 li&#039;).unbind(&#039;dblclick&#039;).assignDblClick();&lt;br /&gt;
	$(&#039;#sortable2 li&#039;).unbind(&#039;dblclick&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function is called on page load to see if there are any items already ranked (from a previous visit&lt;br /&gt;
// or cached due to a page change.  If so, the already-ranked items are loaded into the sortable list&lt;br /&gt;
function loadRanking() {&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	&lt;br /&gt;
	// Loop through each item in the built-in LimeSurvey ranking list looking for non-empty values&lt;br /&gt;
	$(&amp;quot;input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&#039;RANK_&#039;]&amp;quot;).each(function(index) {&lt;br /&gt;
	&lt;br /&gt;
		// Check to see if the current item has a value&lt;br /&gt;
		if ($(this).val()) {&lt;br /&gt;
			// Item has a value - save to the array&lt;br /&gt;
			// Use this element to contain the name and the next for the value (numeric)&lt;br /&gt;
			rankees[rankees.length] = { &#039;r_name&#039;:$(this).val(),&#039;r_value&#039;:$(this).next().val() };&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Now that we have a list of all the pre-ranked items, populate the sortable list&lt;br /&gt;
	// Note that the items *won&#039;t* appear in the main list because LimeSurvey has removed them.&lt;br /&gt;
	$.each(rankees, function(index, value) {&lt;br /&gt;
		// Create the items in the sortable&lt;br /&gt;
		li_tag = &amp;quot;&amp;lt;li class=&#039;ui-state-default&#039; id=&#039;choice_&amp;quot; + value.r_value + &amp;quot;&#039;&amp;gt;&amp;quot; + value.r_name + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
		$(li_tag).appendTo(&amp;quot;#sortable2&amp;quot;);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Create MaxDiff question type=&lt;br /&gt;
&lt;br /&gt;
See the [[Workarounds: Question design, layout and templating|Question design, layout and templating]] section for a workaround that uses JavaScript to convert an &#039;&#039;&#039;&#039;&#039;Array (flexible labels) by column&#039;&#039;&#039;&#039;&#039; question into a [http://en.wikipedia.org/wiki/MaxDiff MaxDiff] question type.&lt;br /&gt;
&lt;br /&gt;
[[File:max_diff_596x253.gif]]&lt;br /&gt;
&lt;br /&gt;
=In a checkbox matrix, have the &#039;none&#039; option in a row disable all other columns in that row=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LimeSurvey 1.90+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The questionId parameter is the base ID of the question matrix (multiflexible).&lt;br /&gt;
&lt;br /&gt;
numColumns and numRows speak for themselves&lt;br /&gt;
&lt;br /&gt;
specialColumns is an array of the columns that have the special ability that when one of them&lt;br /&gt;
&lt;br /&gt;
is checked, none of the others can be checked. E.g., a &#039;none of these&#039; and/or a &#039;do now know&#039; option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
numColumns=13;&lt;br /&gt;
&lt;br /&gt;
numRows=18;&lt;br /&gt;
&lt;br /&gt;
questionId=&#039;28417X2X24&#039;;&lt;br /&gt;
&lt;br /&gt;
specialColumns=[1,12,13];&lt;br /&gt;
&lt;br /&gt;
function action(obj){&lt;br /&gt;
&lt;br /&gt;
   locator=obj.id.replace(&#039;cbox_&#039;+questionId, &#039;&#039;).split(&#039;_&#039;);&lt;br /&gt;
&lt;br /&gt;
   row=locator[0];&lt;br /&gt;
&lt;br /&gt;
   column=locator[1];&lt;br /&gt;
&lt;br /&gt;
   //alert(&#039;Action for row,column=&#039;+row+&#039;,&#039;+column);&lt;br /&gt;
&lt;br /&gt;
   my_id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+column+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   if($(my_id).attr(&#039;checked&#039;) == false) {&lt;br /&gt;
&lt;br /&gt;
       for( var i=1; i&amp;lt;=numColumns; i++ ) {&lt;br /&gt;
&lt;br /&gt;
           if(i==column) continue;&lt;br /&gt;
&lt;br /&gt;
           id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;disabled&#039;,false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   } else {&lt;br /&gt;
&lt;br /&gt;
       for( var i=1; i&amp;lt;=numColumns; i++ ) {&lt;br /&gt;
&lt;br /&gt;
           if(i==column) continue;&lt;br /&gt;
&lt;br /&gt;
           id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           aid=&#039;#answer&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           $(aid).val(0);&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;checked&#039;,false);&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;disabled&#039;,true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function customOnLoad(){&lt;br /&gt;
&lt;br /&gt;
   for( var row=1; row&amp;lt;=numRows; row++ ) {&lt;br /&gt;
&lt;br /&gt;
       for( var k=0; k&amp;lt;specialColumns.length; k++ )&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           column=specialColumns[k];&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+column).change(function() {&lt;br /&gt;
&lt;br /&gt;
               action(this);&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
   customOnLoad();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Last Option In Array (Numbers) (Checkboxes) Row Excludes All Others=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 2.05, IE 7-10, Firefox&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to make the last option of each Array (Numbers) (Checkboxes) row exclude all other options in the same row.&lt;br /&gt;
&lt;br /&gt;
The script will uncheck all options in a row if the last option is checked and uncheck the last option in a row if any other options are checked.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following script in the source of the array question.&lt;br /&gt;
&lt;br /&gt;
NOTE: Care should be taken when using this script and conditional questions on the same page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Call the exclude function using question ID&lt;br /&gt;
		excludeOpt ({QID});&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// A function to make the last option in each array row exclusive&lt;br /&gt;
	function excludeOpt (qID) {&lt;br /&gt;
		&lt;br /&gt;
		var thisQuestion = $(&#039;#question&#039;+qID)&lt;br /&gt;
&lt;br /&gt;
		// Add some classes to the checkbox cells&lt;br /&gt;
		$(&#039;table.question tbody td&#039;, thisQuestion).addClass(&#039;normalOpt&#039;);&lt;br /&gt;
		$(&#039;table.question tbody tr&#039;, thisQuestion).each(function(i) {&lt;br /&gt;
			$(&#039;.normalOpt:last&#039;, this).removeClass(&#039;normalOpt&#039;).addClass(&#039;exlusiveOpt&#039;)&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// A listener on the checkbox cells&lt;br /&gt;
		$(&#039;table.question tbody td&#039;, thisQuestion).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Set some vars&lt;br /&gt;
			var thisRow = $(this).closest(&#039;tr&#039;);&lt;br /&gt;
&lt;br /&gt;
			// Uncheck the appropriate boxes in a row&lt;br /&gt;
			if ($(this).hasClass(&#039;normalOpt&#039;)) {&lt;br /&gt;
				$(&#039;.exlusiveOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;.normalOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// A listener on the checkboxes&lt;br /&gt;
		$(&#039;table.question tbody td input[type=checkbox]&#039;, thisQuestion).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Set some vars&lt;br /&gt;
			var thisRow = $(this).closest(&#039;tr&#039;);&lt;br /&gt;
			var thisCell = $(this).closest(&#039;td&#039;);&lt;br /&gt;
&lt;br /&gt;
			// Uncheck the appropriate boxes in a row&lt;br /&gt;
			if ($(thisCell).hasClass(&#039;normalOpt&#039;)) {&lt;br /&gt;
				$(&#039;.exlusiveOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;.normalOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Add Navigation Buttons (Next and Previous) To Top Of Page=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add the following to the end of template.js. It will insert a new div after the progress bar and then insert clones of the nav buttons in the new div.&lt;br /&gt;
&lt;br /&gt;
This example is for the default template in 1.90 or 1.91. The placement of the new div may need to be modified for other templates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Insert a new div after the progress bar&lt;br /&gt;
		$(&#039;&amp;lt;div id=&amp;quot;navigator2&amp;quot; /&amp;gt;&#039;).insertAfter(&#039;#progress-wrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Style the new div&lt;br /&gt;
		$(&#039;#navigator2&#039;).css({&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// Insert clones of the nav buttons in the new div&lt;br /&gt;
		$(&#039;input.submit:eq(0)&#039;).clone().appendTo(&#039;#navigator2&#039;);&lt;br /&gt;
		$(&#039;input.submit:eq(2)&#039;).clone().appendTo(&#039;#navigator2&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Give the new buttons some new IDs&lt;br /&gt;
		$(&#039;#navigator2 input.submit&#039;).each(function(i) {&lt;br /&gt;
			var oldID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
			var newID = oldID + &#039;2&#039;;&lt;br /&gt;
			$(this).attr(&#039;id&#039;, newID)&lt;br /&gt;
		});&lt;br /&gt;
	});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:extra_buttons.png]]&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;add&#039;&#039; an opt out link to your survey=&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.91+, Firefox 5.0&lt;br /&gt;
&lt;br /&gt;
This javascript inserts a link to opt out of the survey above the progress bar.&lt;br /&gt;
&lt;br /&gt;
[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]]&lt;br /&gt;
&lt;br /&gt;
Then insert the following code into to the source of a group description or a question. I used the group description.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt; &amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Find the survey ID&lt;br /&gt;
		if($(&#039;input#fieldnames&#039;).length != 0) {&lt;br /&gt;
			var fieldNames = $(&#039;input#fieldnames&#039;).attr(&#039;value&#039;);&lt;br /&gt;
			var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
			var sID = tmp[0];&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Insert a new div after the progress bar&lt;br /&gt;
		$(&#039;&amp;lt;div id=&amp;quot;optOutLink&amp;quot; /&amp;gt;&#039;).insertBefore(&#039;#progress-wrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Style the new div&lt;br /&gt;
		$(&#039;#optOutLink&#039;).css({&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// Insert opt out url in the new div&lt;br /&gt;
		$(&#039;#optOutLink&#039;).html(&#039;&amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;optout.php?lang=en&amp;amp;sid;=&#039;+sID+&#039;&amp;amp;token;={TOKEN}&amp;quot;&amp;gt;Click here to opt out of this survey.&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;br&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Anonymously track respondents answers across multiple surveys=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+ and 1.92+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to enable tracking of respondents across multiple surveys ensuring anonymity (it does not use tokens).&lt;br /&gt;
&lt;br /&gt;
To do this you have to use this question in all the surveys you want to link respondents answers.&lt;br /&gt;
&lt;br /&gt;
This workaround create an ID by asking some partial personal information (like initials, birth month ...). The ID will be encrypted using a one-way function (in this case SHA-1) and stored in a short text answer.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following code in the source of a short text question.&lt;br /&gt;
#Optional: you can also add other select field to avoid collisions (e.g. for large population sample)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This answers are used to generate your ID. These information will be encrypted, it will not be possible in any case to identify you neither from your answers nor from your ID.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;Initial of your name&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select id=&amp;quot;field1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;A&amp;quot;&amp;gt;A&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;B&amp;quot;&amp;gt;B&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;C&amp;quot;&amp;gt;C&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;D&amp;quot;&amp;gt;D&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;E&amp;quot;&amp;gt;E&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;F&amp;quot;&amp;gt;F&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;G&amp;quot;&amp;gt;G&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;H&amp;quot;&amp;gt;H&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;I&amp;quot;&amp;gt;I&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;J&amp;quot;&amp;gt;J&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;K&amp;quot;&amp;gt;K&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;L&amp;quot;&amp;gt;L&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;M&amp;quot;&amp;gt;M&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;N&amp;quot;&amp;gt;N&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;O&amp;quot;&amp;gt;O&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;P&amp;quot;&amp;gt;P&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Q&amp;quot;&amp;gt;Q&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;R&amp;quot;&amp;gt;R&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;S&amp;quot;&amp;gt;S&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;T&amp;quot;&amp;gt;T&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;U&amp;quot;&amp;gt;U&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;V&amp;quot;&amp;gt;V&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;W&amp;quot;&amp;gt;W&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;X&amp;quot;&amp;gt;X&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Y&amp;quot;&amp;gt;Y&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Z&amp;quot;&amp;gt;Z&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;Your birth month&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select id=&amp;quot;field2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;01&amp;quot;&amp;gt;January&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;02&amp;quot;&amp;gt;February&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;03&amp;quot;&amp;gt;March&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;04&amp;quot;&amp;gt;April&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;05&amp;quot;&amp;gt;May&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;06&amp;quot;&amp;gt;June&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;07&amp;quot;&amp;gt;July&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;08&amp;quot;&amp;gt;August&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;09&amp;quot;&amp;gt;September&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;10&amp;quot;&amp;gt;October&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;11&amp;quot;&amp;gt;November&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;12&amp;quot;&amp;gt;December&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/sha1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   $(&amp;quot;#answer{SGQ}&amp;quot;).attr(&#039;readonly&#039;, &#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
   //$(&amp;quot;#answer{SGQ}&amp;quot;).css(&#039;display&#039;, &#039;none&#039;); //uncomment this line for not displaying the code&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(&#039;#field1, #field2&#039;).bind(&#039;change keyup&#039;, function() {&lt;br /&gt;
&lt;br /&gt;
   if ($(&amp;quot;#field1&amp;quot;).val()==&#039;&#039; || $(&amp;quot;#field2&amp;quot;).val()==&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;#answer{SGQ}&amp;quot;).val(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
   else {&lt;br /&gt;
&lt;br /&gt;
       var sha1 = CryptoJS.algo.SHA1.create();&lt;br /&gt;
&lt;br /&gt;
       sha1.update($(&amp;quot;#field1&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       sha1.update($(&amp;quot;#field2&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       // sha1.update($(&amp;quot;#otherfield&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       var hash = sha1.finalize();&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;#answer{SGQ}&amp;quot;).val(hash);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Check validity of international phone number in subquestion=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, Firefox 8, Chrome 15&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As of version 1.92, you can use the core Validation querstion option to validate multiple short text and array text questions. Any question that fails that validation check will have its background color changed to red.&lt;br /&gt;
&lt;br /&gt;
Note, the below workaround will fail in version 1.92 because it contains a regular expression with curly braces.  However, as described above, support for this feature is now built-in to version 1.92&lt;br /&gt;
&lt;br /&gt;
This workaround uses javascript to check the validity of an international phone number in a subquestion of multiple short text.&lt;br /&gt;
&lt;br /&gt;
Add the following code to the source of your question.&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;NN&amp;quot; with the row number that you want to validate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the phone function with the question ID and the row number&lt;br /&gt;
&lt;br /&gt;
       phoneTest(QQ, NN);&lt;br /&gt;
&lt;br /&gt;
       function phoneTest(qID, inputNum) {&lt;br /&gt;
&lt;br /&gt;
           // Interrupt next/submit function&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               // Some vars - modify as required&lt;br /&gt;
&lt;br /&gt;
               var phoneMatch = /^[0-9,+,(), ,]{1,}(,[0-9]+){0,}$/;&lt;br /&gt;
&lt;br /&gt;
               var msg1 = &#039;Please enter a valid phone number.&#039;;&lt;br /&gt;
&lt;br /&gt;
               // Test the input&lt;br /&gt;
&lt;br /&gt;
               var phoneInput = $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               if(phoneInput != &#039;&#039; &amp;amp;&amp;amp; !phoneMatch.test(phoneInput)) {&lt;br /&gt;
&lt;br /&gt;
                   alert(msg1);&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;pink&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The regex is from: [http://www.regexlib.com/REDetails.aspx?regexp_id=1136 regexlib.com blank]&lt;br /&gt;
&lt;br /&gt;
=Check validity of email address in subquestion=&lt;br /&gt;
&lt;br /&gt;
&#039;Tested with: 1.91+, Firefox 8, Chrome 15&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, you can use the core Validation querstion option to validate multiple short text and array text questions. Any question that fails that validation check will have its background color changed to red.&amp;lt;br /&amp;gt;Note, the below workaround will fail in version 1.92 because it contains a regular expression with curly braces.  However, as described above, support for this feature is now built-in to version 1.92&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses javascript to check the validity of an email address in a subquestion of multiple short text.&lt;br /&gt;
&lt;br /&gt;
Add the following code to the source of your question.&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;NN&amp;quot; with the row number that you want to validate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the email function with the question ID and the row number&lt;br /&gt;
&lt;br /&gt;
       emailTest(QQ, NN);&lt;br /&gt;
&lt;br /&gt;
       function emailTest(qID, inputNum) {&lt;br /&gt;
&lt;br /&gt;
           // Interrupt next/submit function&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               // Some vars - modify as required&lt;br /&gt;
&lt;br /&gt;
               var emailMatch = /^[a-zA-Z0-9\_\-]+[a-zA-Z0-9\.\_\-]*@([a-zA-Z0-9\_\-]+\.)+([a-zA-Z]{2,4}|travel|museum)$/;&lt;br /&gt;
&lt;br /&gt;
               var msg1 = &#039;Please enter a valid email address.&#039;;&lt;br /&gt;
&lt;br /&gt;
               // Test the input&lt;br /&gt;
&lt;br /&gt;
               var emailInput = $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               if(emailInput != &#039;&#039; &amp;amp;&amp;amp; !emailMatch.test(emailInput)) {&lt;br /&gt;
&lt;br /&gt;
                   alert(msg1);&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;pink&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The regex is from: [http://www.regexlib.com/REDetails.aspx?regexp_id=1653 regexlib.com blank]&lt;br /&gt;
&lt;br /&gt;
=Hiding the help-text when it&#039;s empty=&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.91+&lt;br /&gt;
&lt;br /&gt;
I had made a style in my template putting a border around my help-text. To avoid empty help-text to show up (and have lines instead of just &#039;nothing&#039; when there was no help text, I used this piece of code in question.pstpl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                   var questionhelp=&amp;quot;{QUESTIONHELP}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
                   if (questionhelp==&amp;quot;&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
                          document.write(&amp;quot;&amp;quot;);}&lt;br /&gt;
&lt;br /&gt;
                   else {&lt;br /&gt;
&lt;br /&gt;
                   document.write(&#039;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;survey-question-help&amp;quot;&amp;gt;&#039;+ questionhelp +&#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;);}&lt;br /&gt;
&lt;br /&gt;
               &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
it can probably be optimized but it worked for me&lt;br /&gt;
&lt;br /&gt;
=Disable or hide selected fields in a matrix question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+, IE 7/8/9, FireFox 12/13&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
TASK&lt;br /&gt;
&lt;br /&gt;
Hide or disable selected fields in a Matrix, so that users cannot make any input.&lt;br /&gt;
&lt;br /&gt;
(See example, where users should not make input into red framed fields)&lt;br /&gt;
&lt;br /&gt;
[[File:snap035.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Prevent users from input into first two fields (as an example)&lt;br /&gt;
&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
First find the name of the fields you want to hide / disable. In my case I used Firebug with firefox to figure that out.&lt;br /&gt;
&lt;br /&gt;
[[File:snap037.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 2: Figure out the name(s) of the field(s)&lt;br /&gt;
&lt;br /&gt;
Then put the following script-code into the HTML-source code as described above:&lt;br /&gt;
&lt;br /&gt;
Note: you have to change the code to match the names of your fields!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;input[name=&amp;quot;69965X2X10SQ001_SQ001&amp;quot;]&#039;).attr(&#039;disabled&#039;, &#039;disabled&#039;);&lt;br /&gt;
&lt;br /&gt;
       $(&#039;input[name=&amp;quot;69965X2X10SQ001_SQ002&amp;quot;]&#039;).attr(&#039;hidden&#039;, &#039;hidden&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:snap039.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 3: Result: first field is diabled (&amp;quot;greyed out&amp;quot;), second one is completely hidden&lt;br /&gt;
&lt;br /&gt;
I think this way one can apply many other attributes to a field like color etc. But did not try that myself.&lt;br /&gt;
&lt;br /&gt;
Thanks to roB2009 for the input in the forum!&lt;br /&gt;
&lt;br /&gt;
=Add prefix or suffix to question type &amp;quot;Array (Texts)&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
TASK&lt;br /&gt;
&lt;br /&gt;
Add a prefix or suffix to the text fields in questions of the &amp;quot;Array (Texts)&amp;quot; type.&lt;br /&gt;
&lt;br /&gt;
[[File:suffix.png]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Suffix&lt;br /&gt;
&lt;br /&gt;
[[File:prefix.png]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Prefix&lt;br /&gt;
&lt;br /&gt;
SOLUTION&lt;br /&gt;
*Set up your survey to use JavaScript.&lt;br /&gt;
*Add the following script to the source of the array. Replace &amp;quot;12345&amp;quot; with the array question ID and modify the suffixes/prefixes as required.&lt;br /&gt;
*The function call must consist of a question ID followed by the suffixes for each column. Suffixes/Prefixes must be enclosed in quotes and comma separated.&lt;br /&gt;
*In this example question ID 12345 will get an &amp;quot;in &amp;amp;euro;&amp;quot; suffix in the first column and an &amp;quot;in %&amp;quot; in the next 3 columns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the function with the question ID followed by a comma-separated list of suffixes&lt;br /&gt;
&lt;br /&gt;
       addSuffix(12345, &#039;in &amp;amp;euro;&#039;, &#039;in %&#039;, &#039;in %&#039;, &#039;in %&#039;);&lt;br /&gt;
&lt;br /&gt;
       function addSuffix() {&lt;br /&gt;
&lt;br /&gt;
           var qID = $(arguments)[0];&lt;br /&gt;
&lt;br /&gt;
           // Assign some column-specific classes&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+qID+&#039; table.question tbody tr&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
               $(&#039;td&#039;, this).each(function(i){&lt;br /&gt;
&lt;br /&gt;
                   $(this).addClass(&#039;answerCol-&#039;+(i+1)+&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
               });&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Some styling&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+qID+&#039; table.question tbody input[type=&amp;quot;text&amp;quot;]&#039;).css({&lt;br /&gt;
&lt;br /&gt;
               &#039;width&#039;: &#039;50%&#039;&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Insert the suffixes&lt;br /&gt;
&lt;br /&gt;
           $(arguments).each(function(i, val){&lt;br /&gt;
&lt;br /&gt;
               if(i &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).append(val);&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For adding a prefix you need to substitute the following line in the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).append(val);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).prepend(val);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Time question (Date question-like)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to build a Time question just like to the Date one.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Download the file at [http://trentrichardson.com/examples/timepicker/jquery-ui-timepicker-addon.js trentrichardson.com/examples/timepicker/jquery-ui-timepicker-addon.js] and upload it to your survey.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following code in the source of a short text question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;/upload/surveys/{SID}/jquery-ui-timepicker-addon.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer{SGQ}&#039;).timepicker({&lt;br /&gt;
			timeText: &#039;Time&#039;, //here translation&lt;br /&gt;
			hourText: &#039;hour&#039;, //here translation&lt;br /&gt;
			minuteText: &#039;minute&#039;, //here translation&lt;br /&gt;
			closeText: &#039;Done&#039; //here translation&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer{SGQ}&#039;).attr(&#039;readonly&#039;, &#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
		$( &amp;quot;&amp;lt;style&amp;gt;&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-widget-header, .ui-datepicker-current { display:none; }&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }&amp;quot;&lt;br /&gt;
		+&amp;quot; }&amp;quot;&lt;br /&gt;
		+&amp;quot;&amp;lt;/style&amp;gt;&amp;quot;).appendTo( &amp;quot;head&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Calculating date difference=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+ Build 120909&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround explains how calculate difference between two dates (in: days, weeks, months and years) and is based on this [http://ditio.net/2010/05/02/javascript-date-difference-calculation/ resource external].&lt;br /&gt;
&lt;br /&gt;
Requieres 2 groups and &#039;group by group&#039; or &#039;question by question&#039; presentation.&lt;br /&gt;
&lt;br /&gt;
Group 1 (2 date questions)&lt;br /&gt;
*1st question - Question code: &amp;quot;DD&amp;quot;&lt;br /&gt;
*2nd question - Question code: &amp;quot;D2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Group 2&lt;br /&gt;
*1 numerical input question.&lt;br /&gt;
&lt;br /&gt;
This question retrieves the number of days between the 2 dates, and check if D2 is posterior than DD.&lt;br /&gt;
&lt;br /&gt;
All the requiered code have to be added in the source of this numerical question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
Adapted from http://ditio.net/2010/05/02/javascript-date-difference-calculation/&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var DateDiff = {&lt;br /&gt;
&lt;br /&gt;
   inDays: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var t2 = d2.getTime();&lt;br /&gt;
&lt;br /&gt;
       var t1 = d1.getTime();&lt;br /&gt;
&lt;br /&gt;
       return parseInt[[t2-t1)/(24*3600*1000]];&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inWeeks: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var t2 = d2.getTime();&lt;br /&gt;
&lt;br /&gt;
       var t1 = d1.getTime();&lt;br /&gt;
&lt;br /&gt;
       return parseInt[[t2-t1)/(24*3600*1000*7]];&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inMonths: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var d1Y = d1.getFullYear();&lt;br /&gt;
&lt;br /&gt;
       var d2Y = d2.getFullYear();&lt;br /&gt;
&lt;br /&gt;
       var d1M = d1.getMonth();&lt;br /&gt;
&lt;br /&gt;
       var d2M = d2.getMonth();&lt;br /&gt;
&lt;br /&gt;
       return (d2M+12*d2Y)-(d1M+12*d1Y);&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inYears: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       return d2.getFullYear()-d1.getFullYear();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
d1 = new Date({substr(DD,0,4)}, {substr(DD,5,2)}, {substr(DD,8,2)});&lt;br /&gt;
&lt;br /&gt;
d2 = new Date({substr(D2,0,4)}, {substr(D2,5,2)}, {substr(D2,8,2)});&lt;br /&gt;
&lt;br /&gt;
// Displays result&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;days&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inDays(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;weeks&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inWeeks(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;months&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inMonths(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;years&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inYears(d1, d2));&lt;br /&gt;
&lt;br /&gt;
// filled the numerical input with number of days (or nights)&lt;br /&gt;
&lt;br /&gt;
var nDays = +DateDiff.inDays(d1, d2);&lt;br /&gt;
&lt;br /&gt;
    jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;.numeric:eq(0) input.text&amp;quot;).val(nDays);&lt;br /&gt;
&lt;br /&gt;
               $(&amp;quot;.numeric:eq(0) input.text&amp;quot;).attr(&#039;readonly&#039;,&#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
// check if d2 &amp;gt; d1&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#movenextbtn&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#movesubmitbtn&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               if(nDays &amp;gt;= 0){&lt;br /&gt;
&lt;br /&gt;
       // automatic submit (uncomment if needed)&lt;br /&gt;
&lt;br /&gt;
               // document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
               // $(&#039;body&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
               else alert(&amp;quot;Check out date must be posterior than Check in\nPlease return to the previous page and edit your answers&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How to set minDate/maxDate based on other Datequestions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039; tested with Version 2.00+ Build 130708&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
QQ1 and QQ2 are the question identifiers. QQ2 gets as maxDate today and as minDate the date set in QQ1. The onClose event is needed because on document.ready the value of QQ1 is not yet known, although the value of today is.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        &#039;use strict&#039;;&lt;br /&gt;
        var qID1 = QQ1,&lt;br /&gt;
            qID2 = QQ2,&lt;br /&gt;
            q1 = $(&#039;#question&#039; + &#039;QQ1&#039; + &#039; .popupdate&#039;), &lt;br /&gt;
            q2 = $(&#039;#question&#039; + &#039;QQ2&#039; + &#039; .popupdate&#039;);&lt;br /&gt;
	&lt;br /&gt;
        //if q1 loses focus, its value is taken and used as minDate in q2   &lt;br /&gt;
        q1.datepicker(&amp;quot;option&amp;quot;, &amp;quot;onClose&amp;quot;, function (datum){&lt;br /&gt;
            q2.datepicker( &amp;quot;option&amp;quot;, &amp;quot;minDate&amp;quot;, datum );&lt;br /&gt;
        });&lt;br /&gt;
        //q2 gets today as its maxDate&lt;br /&gt;
        q2.datepicker( &#039;option&#039;, &#039;maxDate&#039;, new Date() );&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Remove Question Help if empty=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Version 2.00+ Build 130513&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Change your question.pstpl in your Template Editor so that the line looks like below. I&#039;ve added the ID tag help_{question_number}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;survey-question-help&amp;quot; id=help_{QUESTION_NUMBER}&amp;gt;{QUESTIONHELP}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add the following javascript at the end of question.pstpl. If the contents of the help tag is empty then hide the element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
$(document).ready(function(){&lt;br /&gt;
  if($(&#039;#help_{QUESTION_NUMBER}&#039;).is(&#039;:empty&#039;)){&lt;br /&gt;
  $(&#039;#help_{QUESTION_NUMBER}&#039;).hide();&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Implicit Association Test (IAT)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 2.0, IE 7-10, Firefox, Chrome, iPad&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to insert an IAT interface into an Array (Texts) question. The workaround prompts respondents to assign words or phrases using the &amp;quot;E&amp;quot; or &amp;quot;I&amp;quot; keys. In mobile devices, &amp;quot;E&amp;quot; and &amp;quot;I&amp;quot; buttons are provided.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Iat_1.png]]&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download a [[Media:Demo_IAT_Concept.zip|working template]] and [[Media:Demo_iat_concept.lss|working survey]].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
1) [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
&lt;br /&gt;
2) Create your Array (Texts) with sub-questions as follows:&amp;lt;br /&amp;gt;&lt;br /&gt;
- Y scale - all of your &amp;quot;attribut&amp;quot; words or phrases&amp;lt;br /&amp;gt;&lt;br /&gt;
- X scale - &amp;quot;Key Pressed&amp;quot; and &amp;quot;Elapsed Time (ms)&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Iat_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
3) Insert your association terms and the other text elements for the interface into the Question Help section as depicted below. The text strings must be separated with &amp;quot;double pipes&amp;quot; (||) and you will need to place them in the following order:&amp;lt;br /&amp;gt;&lt;br /&gt;
- Left association term&amp;lt;br /&amp;gt;&lt;br /&gt;
- Right association term&amp;lt;br /&amp;gt;&lt;br /&gt;
- Instructional text&amp;lt;br /&amp;gt;&lt;br /&gt;
- Finished text&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Iat_3.png]]&lt;br /&gt;
&lt;br /&gt;
4) Add the following to the end of template.js:&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// A plugin to insert an IAT interface&lt;br /&gt;
function implicitAssociation(el, showAnswers) {&lt;br /&gt;
		&lt;br /&gt;
	$(el).each(function() {&lt;br /&gt;
			&lt;br /&gt;
		var thisQuestion = $(this);&lt;br /&gt;
		var thisQuestionHelp = $(&#039;img[src$=&amp;quot;help.gif&amp;quot;]&#039;, thisQuestion).parent();&lt;br /&gt;
		var thisQuestionAnswers = $(&#039;table.question&#039;, thisQuestion).parent();&lt;br /&gt;
		var startTime = &#039;&#039;;&lt;br /&gt;
		var endTime = &#039;&#039;;	&lt;br /&gt;
		var agent = navigator.userAgent.toLowerCase();&lt;br /&gt;
		var mobile = false;&lt;br /&gt;
		if( /android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent) ) { // Mobile devices&lt;br /&gt;
			mobile = true;&lt;br /&gt;
		}&lt;br /&gt;
		mobile = true;&lt;br /&gt;
		&lt;br /&gt;
		// Some classes&lt;br /&gt;
		$(thisQuestion).addClass(&#039;iatQuestion&#039;);&lt;br /&gt;
		$(&#039;.subquestion-list&#039;).addClass(&#039;unanswered&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Hide the question help element&lt;br /&gt;
		$(thisQuestionHelp).hide();&lt;br /&gt;
		&lt;br /&gt;
		// Hide the answers&lt;br /&gt;
		if(showAnswers != true) {&lt;br /&gt;
			$(&#039;table.question&#039;, thisQuestion).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Insert IAT display&lt;br /&gt;
		var iatTexts = $(thisQuestionHelp).text().split(&#039;||&#039;);&lt;br /&gt;
		var iatDisplayHTML = &#039;&amp;lt;div class=&amp;quot;iatWrapper&amp;quot;&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatLeftLabel&amp;quot;&amp;gt;&#039;+iatTexts[0]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatRightLabel&amp;quot;&amp;gt;&#039;+iatTexts[1]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatWord&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatInstructions&amp;quot;&amp;gt;&#039;+iatTexts[2]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;div class=&amp;quot;iatMobileButtonWrapper&amp;quot;&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatButton iatLeftButton&amp;quot;&amp;gt;E&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatButton iatRightButton&amp;quot;&amp;gt;I&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div style=&amp;quot;width:100%; clear:both;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
		$(thisQuestionAnswers).prepend(iatDisplayHTML);&lt;br /&gt;
		&lt;br /&gt;
		// Show a word&lt;br /&gt;
		function iatShowWord() {&lt;br /&gt;
			$(&#039;div.iatWord&#039;, thisQuestion).text($(&#039;.subquestion-list.unanswered:first .answertext&#039;, thisQuestion).text());&lt;br /&gt;
			startTime = new Date();&lt;br /&gt;
			&lt;br /&gt;
			$(document).bind(&#039;keypress.iatKeypress&#039;, function(e) {&lt;br /&gt;
				if(e.which == 101 || e.which == 105) {&lt;br /&gt;
					var thisRow = $(&#039;.subquestion-list.unanswered:eq(0)&#039;, thisQuestion);&lt;br /&gt;
					$(thisRow).removeClass(&#039;unanswered&#039;);&lt;br /&gt;
					endTime = new Date();&lt;br /&gt;
					$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(1)&#039;, thisRow).val(endTime.valueOf() - startTime.valueOf());&lt;br /&gt;
					if(e.which == 101) {&lt;br /&gt;
						$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val(&#039;E&#039;);&lt;br /&gt;
					}&lt;br /&gt;
					else {&lt;br /&gt;
						$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val(&#039;I&#039;);&lt;br /&gt;
					}&lt;br /&gt;
					$(document).unbind(&#039;keypress.iatKeypress&#039;);&lt;br /&gt;
					if($(&#039;.subquestion-list.unanswered&#039;, thisQuestion).length &amp;gt; 0) {&lt;br /&gt;
						iatShowWord();&lt;br /&gt;
					}&lt;br /&gt;
					else {&lt;br /&gt;
						$(&#039;.iatLeftLabel, .iatWord, .iatRightLabel, .iatInstructions&#039;, thisQuestion).fadeOut(&#039;slow&#039;, function() {&lt;br /&gt;
							$(&#039;div.iatWord&#039;, thisQuestion).text(iatTexts[3]);&lt;br /&gt;
							$(&#039;.iatWord&#039;, thisQuestion).addClass(&#039;done&#039;).fadeIn(&#039;slow&#039;);&lt;br /&gt;
						});&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		function iatShowWordMobile() {&lt;br /&gt;
			$(&#039;div.iatWord&#039;, thisQuestion).text($(&#039;.subquestion-list.unanswered:first .answertext&#039;, thisQuestion).text());&lt;br /&gt;
			startTime = new Date();&lt;br /&gt;
			&lt;br /&gt;
			$(&#039;.iatButton&#039;, thisQuestion).bind(&#039;click.iatButtonClick&#039;, function(e) {&lt;br /&gt;
				var thisRow = $(&#039;.subquestion-list.unanswered:eq(0)&#039;, thisQuestion);&lt;br /&gt;
				$(thisRow).removeClass(&#039;unanswered&#039;);&lt;br /&gt;
				endTime = new Date();&lt;br /&gt;
				$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(1)&#039;, thisRow).val(endTime.valueOf() - startTime.valueOf());&lt;br /&gt;
				$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val($(this).text());&lt;br /&gt;
				$(&#039;.iatButton&#039;, thisQuestion).unbind(&#039;click.iatButtonClick&#039;);&lt;br /&gt;
				if($(&#039;.subquestion-list.unanswered&#039;, thisQuestion).length &amp;gt; 0) {&lt;br /&gt;
					iatShowWordMobile();&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					$(&#039;.iatLeftLabel, .iatWord, .iatRightLabel, .iatInstructions, .iatMobileButtonWrapper&#039;, thisQuestion).fadeOut(&#039;slow&#039;, function() {&lt;br /&gt;
						$(&#039;div.iatWord&#039;, thisQuestion).text(iatTexts[3]);&lt;br /&gt;
						$(&#039;.iatWord&#039;, thisQuestion).addClass(&#039;done&#039;).fadeIn(&#039;slow&#039;);&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Start the IAT display&lt;br /&gt;
		if(mobile == true) { // Mobile devices&lt;br /&gt;
			$(&#039;.iatMobileButtonWrapper&#039;, thisQuestion).show();&lt;br /&gt;
			$(&#039;.iatButton&#039;, thisQuestion).bind(&#039;click.iatStartMobile&#039;, function(e) {&lt;br /&gt;
				$(&#039;.iatButton&#039;, thisQuestion).unbind(&#039;click.iatStartMobile&#039;);&lt;br /&gt;
				iatShowWordMobile();&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(document).bind(&#039;keypress.iatStart&#039;, function(e) { // Non-mobile devices&lt;br /&gt;
				if(e.which == 101 || e.which == 105) {&lt;br /&gt;
					$(document).unbind(&#039;keypress.iatStart&#039;);&lt;br /&gt;
					iatShowWord();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;5) Add the following to the end of template.css:&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
/* IAT questions */&lt;br /&gt;
&lt;br /&gt;
.iatWrapper {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	width: 600px;&lt;br /&gt;
	height: 300px;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
	background-color: #000000;&lt;br /&gt;
	font-size: 21px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatLeftLabel {&lt;br /&gt;
	float: left;&lt;br /&gt;
	padding: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatRightLabel {&lt;br /&gt;
	float: right;&lt;br /&gt;
	padding: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatWord {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	top: 35%;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	font-size: 36px;&lt;br /&gt;
	color:#0F0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatWord.done {&lt;br /&gt;
	color:#FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatInstructions {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	bottom: 0px;&lt;br /&gt;
	padding-bottom: 10px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatMobileButtonWrapper {&lt;br /&gt;
	display: none;&lt;br /&gt;
	position: relative;&lt;br /&gt;
	width: 600px;&lt;br /&gt;
	font-size: 36px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatButton {&lt;br /&gt;
	float: left;&lt;br /&gt;
	margin: 20px;&lt;br /&gt;
	width: 100px;&lt;br /&gt;
	padding: 2px 0 5px 0;&lt;br /&gt;
	border: 5px solid #999;&lt;br /&gt;
	-moz-border-radius: 10px;&lt;br /&gt;
	-webkit-border-radius: 10px;&lt;br /&gt;
	-khtml-border-radius: 10px;&lt;br /&gt;
	border-radius: 10px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	line-height: normal;&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatLeftButton {&lt;br /&gt;
	float: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatRightButton {&lt;br /&gt;
	float: right;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;6) To apply the plugin, add one of the two scripts below to the question source:&amp;lt;br /&amp;gt;&lt;br /&gt;
- With hidden answer table (for normally activated survey)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Apply the IAT plugin to this question&lt;br /&gt;
		implicitAssociation(&#039;#question{QID}&#039;);&lt;br /&gt;
	});	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
- With visible answer table (for testing purposes)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Apply the IAT plugin to this question&lt;br /&gt;
		implicitAssociation(&#039;#question{QID}&#039;, true);&lt;br /&gt;
	});	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Make multiple choice easier=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with Version 2.00 in Chrome, FF, Safar, IE&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The problem:&lt;br /&gt;
We often have multiple choice question, where the user has to select 4 elements out of 78 possible answers or 3 out of 25 and so on.&lt;br /&gt;
If we use pen and paper version for this questions, we noticed that the participants go through the whole list and if an answer doesn&#039;t suit on the first sight, they cross it out.&lt;br /&gt;
&lt;br /&gt;
The solution:&lt;br /&gt;
The script gives the participant the possibility to cross out this answers in a digital way. The script adds a small &amp;quot;X&amp;quot; before the checkbox. When it is clicked, the label text of the checkbox turns grey.&lt;br /&gt;
(see the attached screenshot for an example)&lt;br /&gt;
&lt;br /&gt;
Here is the script, just add it to help text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
* Small script that adds a &amp;quot;X&amp;quot; before a checkbox. &lt;br /&gt;
* On click the text color of the label of the checkbox turns grey&lt;br /&gt;
* If the user has to choose some answers from many options, he can &amp;quot;delete&amp;quot; answers, that on first sight looks wrong&lt;br /&gt;
* Add the script to the question in Limesurvey (for example within the source code of the help text)&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
//Define the X (standard is a X in capitals)&lt;br /&gt;
var x = &amp;quot;X&amp;quot;;&lt;br /&gt;
css_class = &amp;quot;x&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
/*&lt;br /&gt;
* Define the style of the X&lt;br /&gt;
* Of course you can define the style in the stylesheet - if so, the script ignores the following settings&lt;br /&gt;
* If there is a style, than set style var to 1&lt;br /&gt;
*/&lt;br /&gt;
var style = 0;&lt;br /&gt;
var size = &amp;quot;12px&amp;quot;;&lt;br /&gt;
var weight = &amp;quot;bold&amp;quot;;&lt;br /&gt;
var color = &amp;quot;red&amp;quot;;&lt;br /&gt;
var cursor = &amp;quot;pointer&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
//element type - standard is a span element&lt;br /&gt;
var type = &amp;quot;span&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
//Define the new font color of the checkbox label&lt;br /&gt;
label_color = &amp;quot;#bfbfbf&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
//End of configuration - start of the function&lt;br /&gt;
 &lt;br /&gt;
//Define the element that is added&lt;br /&gt;
if(style == 1) {&lt;br /&gt;
	ele = &amp;quot;&amp;lt;&amp;quot;+type+&amp;quot; class=&#039;&amp;quot;+css_class+&amp;quot;&#039;&amp;gt;&amp;quot;+x+&amp;quot;&amp;lt;/&amp;quot;+type+&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
	ele = &amp;quot;&amp;lt;&amp;quot;+type+&amp;quot; class=&#039;&amp;quot;+css_class+&amp;quot;&#039; style=&#039;font-size:&amp;quot;+size+&amp;quot;; font-weight:&amp;quot;+weight+&amp;quot;; color:&amp;quot;+color+&amp;quot;; cursor:&amp;quot;+cursor+&amp;quot;;&#039;&amp;gt;&amp;quot;+x+&amp;quot;&amp;lt;/&amp;quot;+type+&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
//Get the standard font-color of the used style&lt;br /&gt;
st_color = $(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
//insert the X before the checkboxes&lt;br /&gt;
$(document).ready(function() { &lt;br /&gt;
	$(&amp;quot;li&amp;quot;).each(function(){&lt;br /&gt;
		$(this).prepend(ele);&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
//bind an eventhandler on the X (delegate is used, because Limesurvey uses an old jQuery version)&lt;br /&gt;
var css_class_c = &amp;quot;.&amp;quot;+css_class;&lt;br /&gt;
$(document).delegate(css_class_c,&amp;quot;click&amp;quot;,function() {&lt;br /&gt;
	var color_check = $(this).siblings(&amp;quot;label&amp;quot;).data(&amp;quot;color&amp;quot;);&lt;br /&gt;
	if(color_check != &amp;quot;true&amp;quot;) {&lt;br /&gt;
    	$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,label_color).data(&amp;quot;color&amp;quot;,&amp;quot;true&amp;quot;);&lt;br /&gt;
    	$(this).siblings(&#039;input&#039;).attr(&#039;checked&#039;, false);&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,st_color).data(&amp;quot;color&amp;quot;,&amp;quot;false&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
$(&amp;quot;.checkbox&amp;quot;).click(function () {&lt;br /&gt;
	$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,st_color).data(&amp;quot;color&amp;quot;,&amp;quot;false&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Workarounds:_Manipulating_a_survey_at_runtime_using_Javascript&amp;diff=59824</id>
		<title>Workarounds: Manipulating a survey at runtime using Javascript</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Workarounds:_Manipulating_a_survey_at_runtime_using_Javascript&amp;diff=59824"/>
		<updated>2014-01-16T03:57:00Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: /* Drag and Drop Ranking - Version 1.90 to 1.92 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Often you want to manipulate certain elements of a survey at runtime. The only solution without touching the source code is to use JavaScript or jQuery which is shipped with LimeSurvey. Here are some examples to hide and style elements, validate user input or do calculations at runtime.&lt;br /&gt;
&lt;br /&gt;
Other workarounds can be found at&lt;br /&gt;
* [[Workarounds: Survey behaviour]]&lt;br /&gt;
* [[Workarounds: Question design, layout and templating]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;lt;center&amp;gt;&amp;lt;br /&amp;gt;&#039;&#039;&#039;Please keep in mind that these workarounds are not official LimeSurvey extensions - they are solutions that users have created for themselves.&amp;lt;br /&amp;gt;&amp;lt;span style=&#039;color:#EE0000,#FFFFFF&#039;&amp;gt;Therefore LimeSurvey can&#039;t offer guarantees or support for these solutions.&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;If you have questions, please contact the users that, thankfully, shared their solutions with the community.&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/center&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note:  Version 1.92 implements many new features that make some existing workarounds obsolete.  You can continue to use existing workarounds, but may want to consider switching over to using the new features (since those new features are officially supported, and the workarounds are not).  Please review below for details of which are no longer needed.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Also Note:  Version 1.92&#039;s Expression Manager (EM) may cause some of these work-arounds to fail.  Any custom javascript included as a .js file will be fine.  However, if you in-line your JavaScript code, you must make sure that you have a space after every opening (left) curly brace, and a space before every closing (right) curly brace.  Otherwise, EM will think that the content between the curly braces is something it should parse and understand.  I have fixed all of the work-arounds below that can be fixed (many did not follow those rules).  However, some will continue to break.  If a work-around contains a regular expression which contains curly braces (to indicate a range of repeats of a sub-expression), EM will try to process those curly braces, and thus break your regular expression.  Strategies to continue to support that work-around functionality are discussed below.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;add&#039;&#039; a javascript workaround solution to this Wiki page?=&lt;br /&gt;
&lt;br /&gt;
Well, this is pretty easy. Click the edit icon and create your own headline within the javascript section starting with &amp;quot;&#039;&#039;&#039;!&#039;&#039;&#039;&amp;quot;. Then add a short note about the version you have used when creating your workaround, you can copy/paste this code snippet &amp;lt;nowiki&amp;gt;&#039;&#039;Tested with: (enter LimeSurvey version and maybe browser)&#039;&#039;&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Finally it&#039;s imported to mark all your code with code tags, other wise you might break this page.&lt;br /&gt;
*Start tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
*End tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;use&#039;&#039; Script (eg. JavaScript etc.) in LimeSurvey?=&lt;br /&gt;
&lt;br /&gt;
To use JavaScript within LimeSurvey, the XSS filter must be turned off and the code inserted in the source of a question or a group description.&lt;br /&gt;
*Go to Global settings --&amp;gt; Security and set &amp;quot;Filter HTML for XSS&amp;quot; to &amp;quot;Off&amp;quot;.&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=Adding+A+Question Add a new question]&lt;br /&gt;
* Edit the question and click the &amp;quot;Source&amp;quot; button in the editor toolbar:&lt;br /&gt;
&lt;br /&gt;
   [[File:editor_1.gif]]&lt;br /&gt;
* Enter your script after the question text:&lt;br /&gt;
&lt;br /&gt;
   [[File:editor_2.gif]]&lt;br /&gt;
* Save the question&lt;br /&gt;
&lt;br /&gt;
A simple test to see if JavaScript is enabled is to echo an alert. Use this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good practice to use the jQuery $(document).ready function to prevent the code from executing until the page is fully loaded:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is also good practice to use jslint.com to get a good layout and design (e.q. no cluttering of name space)&lt;br /&gt;
&lt;br /&gt;
=Sum up input values using Javascript=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the sum() function in [[Expression Manager|Expression Manager]].  See this [[Expression Manager HowTos#Calculate assessment values at runtime and store the results in the survey data|HowTo example]].&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Starting in  Version 1.92, you also do no longer need to use SGQA (e.g. 45251X1X5) identifiers. Instead the code &amp;lt;code&amp;gt;{SGQ}&amp;lt;/code&amp;gt; will automatically replaced by the current questions SGQA-codes.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is from a survey that is a invitation to a longer party, when the user clicks to the next page, the calculated results will be shown.&lt;br /&gt;
&lt;br /&gt;
If you wonder what the {INSERTANS:1X6X12} stuff is, look at [http://docs.limesurvey.org/tiki-index.php?page=SGQA+Identifier SGQA identifier] and [[Adding a question#Information from previous answers|Using information from previous answers]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: left&amp;quot;&amp;gt;These are your answers:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;script LANGUAGE=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
partyprice = 3;&lt;br /&gt;
&lt;br /&gt;
beadclothprice = 3;&lt;br /&gt;
&lt;br /&gt;
breakfastprice = 7;&lt;br /&gt;
&lt;br /&gt;
lunchprice = 8;&lt;br /&gt;
&lt;br /&gt;
dinnerprice = 10;&lt;br /&gt;
&lt;br /&gt;
foodtotal = 0;&lt;br /&gt;
&lt;br /&gt;
var isreallytrue = &amp;quot;Yes&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var noanswer = &amp;quot;No answer&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
document.write( &amp;quot;Can you come? = {INSERTANS:45251X1X1}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:45251X1X1}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X3}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X3}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
   partypeople = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   partytotal = partyprice * partypeople;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;It&#039;s {INSERTANS:45251X1X3} persons who will come = &amp;quot; + partytotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X4}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X4}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   beadcloths = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   beadclothtotal = beadclothprice * beadcloths;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;You want to borrow {INSERTANS:45251X1X4} beadcloths = &amp;quot; + beadclothtotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there thursday? = {INSERTANS:45251X1X5}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;On friday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X71}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X71}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   breakfastfriday = parseInt(answer) * breakfastprice;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X72}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X72}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   lunchfriday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X73}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X73}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   dinnerfriday = parseInt(answer)* dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnerfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   foodtotal = breakfastfriday + lunchfriday + dinnerfriday;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there saturday? = {INSERTANS:45251X1X8}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X8}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On saturday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X91}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X91}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       breakfastsaturday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write(&amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X92}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X92}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       lunchsaturday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X93}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X93}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       dinnersaturday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsaturday + lunchsaturday + dinnersaturday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there sunday? = {INSERTANS:45251X1X10}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X10}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On sunday you will have these meals: &amp;lt;br&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X111}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X111}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       breakfastsunday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot;  );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X112}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X112}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       lunchsunday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X113}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X113}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       dinnersunday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersunday + &amp;quot;&amp;amp;euro;&amp;lt;p&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsunday + lunchsunday + dinnersunday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   total = partytotal + beadclothtotal + foodtotal;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&amp;lt;h3&amp;gt;In total it will cost you &amp;quot; + total + &amp;quot;&amp;amp;euro;&amp;lt;/h3&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   Put that sum in this bank account 1234 5678 9012&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/SCRIPT&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Question Validation=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the min/max/equals_num_value attributes (to validate sums), or the em_validation_q function, which lets you refer to other variables when you validate the current question [[Expression Manager|Expression Manager]].  Such validations also work on the current page, and properly handle array_filter and cascading relevance.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround is in case you need to do some validation involving more than one question, it implies a very little JavaScript programming and the use of SGQA Identifiers; this should work on almost any version of LimeSurvey.&lt;br /&gt;
&lt;br /&gt;
Is easy to explain with an example, we need to do a survey of the percentage of males and females and we want to be sure that the sum is 100, to do this follow this steps (the necessary data that is not indicated in these instructions are not important i.e. question codes, etc.):&lt;br /&gt;
#Create a new survey of type &amp;quot;group by group&amp;quot;, set the &amp;quot;Show |&amp;lt;&amp;lt; Prev| button&amp;quot; to yes and note the SID.&lt;br /&gt;
#Add a new group called &amp;quot;Group 1&amp;quot; and note the GID.&lt;br /&gt;
#Add a new question &amp;quot;Percent of males&amp;quot; of type &amp;quot;numeric&amp;quot;, make it mandatory and note the QID (we will refer to this as QID1).&lt;br /&gt;
#Add a new question &amp;quot;Percent of females&amp;quot; of type &amp;quot;numeric&amp;quot;, make it mandatory and note the QID (we will refer to this as QID2).&lt;br /&gt;
#Add a new group called &amp;quot;Group 2&amp;quot;&lt;br /&gt;
#Add a new non mandatory question, here is the trick the question text has to be (be sure to replace the SID, GID, QID1 and QID2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function validation()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   if [[{INSERTANS:SIDXGIDXQID1}+{INSERTANS:SIDXGIDXQID2}) != 100)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     alert(&amp;quot;Your responses don&#039;t sum 100! Check them&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;movelast&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But this will show shortly the question and will jump to the end page, a little weird for the survey taker but works.&lt;br /&gt;
&lt;br /&gt;
This is a proof of concept, and may have some problems, please if you notice something or improve it send me an e-mail to leochaton-limesurvey at yahoo dot com.&lt;br /&gt;
&lt;br /&gt;
This will work for 2 questions that you want to be the same.  Works well for email and confirm email questions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function validation() {&lt;br /&gt;
&lt;br /&gt;
 if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; != &amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
    alert(&amp;quot;Your responses don&#039;t match Check them&amp;quot;); document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
    document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Alternate exit=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using the same idea of the previous post, you can implement an alternate exit of your survey.&lt;br /&gt;
&lt;br /&gt;
This script should be in the first question to be displayed in a next page after the question that should trigger the alternate exit. In this example the question that trigger the alternate exit is a Yes/No question, if the user chooses no, he is redirected to another page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; == &amp;quot;No&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  window.location=&amp;quot;http://www.limesurvey.org&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Custom onload function=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;All browsers&#039;, LimeSurvey 1.70 and up&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
&lt;br /&gt;
This simple workaround describes how to &#039;&#039;&#039;add a custom Javascript code&#039;&#039;&#039; that is triggered right after the page is loaded. It may have numerous applications, especially when you deal with a custom JS/HTML code. It may be used to hide form elements (&amp;lt;input&amp;gt;  tags), make them read-only, display alert messages, etc.&lt;br /&gt;
&lt;br /&gt;
To run any Javascript code right after page load use the Query ready() function. It will be executed when the page is being loaded. For example when you add the following code to one of your question definitions...:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
       alert(&#039;onload alert!&#039;);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...it will display a pop-up message immediately after the page has been loaded.&lt;br /&gt;
&lt;br /&gt;
Some of the applications of this trick I&#039;ve explored are:&lt;br /&gt;
&lt;br /&gt;
a) Hiding the form elements by calling in your Custom_On_Load:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: As of svn build 9755, you can now dynamically reference the questions input fields by using the {SGQ} keyword. You can rewrite the previous example like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer{SGQ}&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
this makes it a little easier when exporting surveys, so you don&#039;t have to worry about manually entering each questions SurveyGroupQuestion ID.&lt;br /&gt;
&lt;br /&gt;
b) Making the elements read only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).readOnly=true;&amp;lt;/syntaxhighlight&amp;gt; where the &amp;quot;answer73166X16X54&amp;quot; structure has been described in one of other workarounds above.&lt;br /&gt;
&lt;br /&gt;
c) For Hiding by a lot of elements by calling in your Customer_On_Load&lt;br /&gt;
&lt;br /&gt;
jQuery searchs in html document for input-fields with radio type, if his answer text empty then do the display css set to none.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
           function() {&lt;br /&gt;
&lt;br /&gt;
             jQuery(&#039;input:radio&#039;).each(&lt;br /&gt;
&lt;br /&gt;
               function() {&lt;br /&gt;
&lt;br /&gt;
                 var s = jQuery(this);&lt;br /&gt;
&lt;br /&gt;
                 var c = s.parent().children(&#039;.answertext&#039;);&lt;br /&gt;
&lt;br /&gt;
                 for(var i=0; i &amp;lt; c.length; i++) {&lt;br /&gt;
&lt;br /&gt;
                   var a = jQuery(c[i]]);&lt;br /&gt;
&lt;br /&gt;
                   if(this.id &amp;lt;/u&amp;gt; a.attr(&#039;for&#039;) &amp;amp;&amp;amp; a.text() == &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
                     s.css({ &#039;display&#039; : &#039;none&#039; });&lt;br /&gt;
&lt;br /&gt;
                     a.css({ &#039;display&#039; : &#039;none&#039; });&lt;br /&gt;
&lt;br /&gt;
                     break;&lt;br /&gt;
&lt;br /&gt;
                   }&lt;br /&gt;
&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
             )&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
         );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advanced usage==&lt;br /&gt;
&lt;br /&gt;
If you want to place global Javascript code using the above jQuery(document).ready function then the best place to do this is the template javascript file template.js. You can edit this file using the template editor. Please be aware that placing it in the template javascript file will make the function available to all surveys using that template. If needed just create a new template copy for your survey.&lt;br /&gt;
&lt;br /&gt;
Alternatively you can place the jQuery(document).ready function in the group description to make a Javascript function only available to a certain question group.&lt;br /&gt;
&lt;br /&gt;
==Language-specific Javascript code==&lt;br /&gt;
&lt;br /&gt;
There is an easy way to find out the current language and execute according Javascript using jQuery: The &amp;lt;html&amp;gt; tag of any survey pages contains an &#039;lang&#039; attribute which holds the current language code. You can read that language code by using the followin code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
       languagecode=$(&#039;html&#039;).attr(&#039;lang&#039;);&lt;br /&gt;
&lt;br /&gt;
       alert(&#039;This is the current language code: &#039;+languagecode);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an English survey the above code would show a messagebox with &amp;quot;This is the current language code: en&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Custom onload function in multi-language survey=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use custom onload functions, as above, in multi-language surveys you must define the functions in the question source for &#039;&#039;&#039;all&#039;&#039;&#039; languages.&lt;br /&gt;
&lt;br /&gt;
While this initially seems to be a bit tedious, it actually can be useful - you can alter your onload functions depending on the language in use. For example, you can dynamically display alerts or element contents in the current language.&lt;br /&gt;
&lt;br /&gt;
=Skipping the welcome page=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85 (second code snippet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: As of version 1.91, there is a survey option letting you skip the welcome page, so this workaround is not needed.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 1:&#039;&#039;&#039; Include this Javascript in your welcome template, in the file welcome.pstpl for all welcome page, or in the source of the welcome text for one survey:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function($) {&lt;br /&gt;
&lt;br /&gt;
document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
document.limesurvey.submit(); });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will reproduce the onclick event of the submit button and submit the form.&lt;br /&gt;
&lt;br /&gt;
Drawback of course is that users will see the page flashing up.&lt;br /&gt;
&lt;br /&gt;
Therefore, you may want to announce &amp;quot;... loading survey ...&amp;quot; as a description of your welcome page (in the admin interface when creating the survey), to pretend loading something big.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 2:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function custom_on_load(){&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
window.setTimeout( &#039;custom_on_load()&#039;,1);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Filter answers of a question with the answer of another=&lt;br /&gt;
&lt;br /&gt;
===Method 1===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.70 - 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the the array_filter attribute, or relevance equations in general.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to filter the answer of a question with another answer, you can use this workaround.&lt;br /&gt;
&lt;br /&gt;
First, use answer code like that: XX for the first question, and XXYYY for the second one.&lt;br /&gt;
&lt;br /&gt;
Answer of the second question filter if the 2 first letters are the answer of the first question.&lt;br /&gt;
&lt;br /&gt;
We use 1000X1X1 and 1000X1X2 for the example, question had to be on separate page (question by question for example).The second question had to be a dropdown list (we can do similar workaround, but droplis is the best). You can do this using JQuery.  It leaves the answer in the select box, but disables it.  You could also replace &amp;quot;disable&amp;quot; with &amp;quot;remove&amp;quot; to get rid of it altogether.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var previousQuestionAnswer = &amp;quot;{INSERTANS:1000X1X1}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var currentQuestionID = &amp;quot;#answer1000X1X1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // See if the answer for the previous question matches an answer in the current question&lt;br /&gt;
&lt;br /&gt;
   // (other than &#039;No Answer&#039;)&lt;br /&gt;
&lt;br /&gt;
   // If so, disable it.&lt;br /&gt;
&lt;br /&gt;
   if (previousQuestionAnswer!=&#039;No Answer&#039;) {&lt;br /&gt;
&lt;br /&gt;
       $(currentQuestionID).children().each(function(index, Element)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           if ($(this).attr(&#039;text&#039;) == previousQuestionAnswer)&lt;br /&gt;
&lt;br /&gt;
               { $(this).attr(&#039;disabled&#039;, true); }&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       );}&lt;br /&gt;
&lt;br /&gt;
}); // End of JQuery ready function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Method 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with 1.92 + Firefox 9.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you have a country, state, and city set of questions (or similar), you could code answer options as:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1 Country&#039;&#039;&#039; &#039;&#039;Single choice list (ratio, dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
X country#&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2 State&#039;&#039;&#039; &#039;&#039;Single choice list (dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
XY state#&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3 City&#039;&#039;&#039; &#039;&#039;Single choice list (dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
XYZZ city#&lt;br /&gt;
&lt;br /&gt;
Now you must put the following Javascript code in the source of question 2 (State):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Get the countryCode (first character of the country)&lt;br /&gt;
&lt;br /&gt;
       var countryCode = &#039;{INSERTANS:1000X1X1}&#039;.substr(0, 1).toUpperCase();&lt;br /&gt;
&lt;br /&gt;
       // Loop through all dropdown options and remove those with codes not starting with the countryCode&lt;br /&gt;
&lt;br /&gt;
       $(&#039;select[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;answer&amp;quot;] option&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
           if($(this).attr(&#039;value&#039;)  &amp;amp;&amp;amp; $(this).attr(&#039;value&#039;).substr(0, 1).toUpperCase() != countryCode) {&lt;br /&gt;
&lt;br /&gt;
               $(this).remove();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the following code in the source of question 3 (City):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Get the stateCode (two first characters of the state)&lt;br /&gt;
&lt;br /&gt;
       var stateCode = &#039;{INSERTANS:1000X1X2}&#039;.substr(0, 2).toUpperCase();&lt;br /&gt;
&lt;br /&gt;
       // Loop through all dropdown options and remove those with codes not starting with the stateCode&lt;br /&gt;
&lt;br /&gt;
       $(&#039;select[id&amp;lt;/div&amp;gt;=&amp;quot;answer&amp;quot;] option&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
           if($(this).attr(&#039;value&#039;)  &amp;amp;&amp;amp; $(this).attr(&#039;value&#039;).substr(0, 2).toUpperCase() != stateCode) {&lt;br /&gt;
&lt;br /&gt;
               $(this).remove();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each question must be in different pages of survey to work, i.e. in a question by question survey, or in diferent groups in a group by group survey.&lt;br /&gt;
&lt;br /&gt;
Note that if you choose a two characters answer option code in the State question, i.e. a XYY answer option code, you must change the &#039;&#039;substr(0, 2)&#039;&#039; part of code in question 3 to &#039;&#039;substr(0, 3)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Filter answers of a multiple numeric type question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the the array_filter attribute, or relevance equations in general.  In 1.92, array_filter works with all questions that have sub-questions (e.g. also works for multiple numeric and multiple short text).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to filter a question of type &amp;quot;multiple numeric&amp;quot;, you have to modify the workaround.&lt;br /&gt;
&lt;br /&gt;
Note that this workaround assumes that the code for each of the subquestions are a numeric sequence 1,2,3...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
   // Match elements with labels using htmlFor and a loop&lt;br /&gt;
&lt;br /&gt;
   var labels = document.getElementsByTagName(&#039;LABEL&#039;);&lt;br /&gt;
&lt;br /&gt;
   for (var i = 0; i &amp;lt; labels.length; i++) {&lt;br /&gt;
&lt;br /&gt;
       if (labels[i].htmlFor != &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
            var elem = document.getElementById(labels[i].htmlFor);&lt;br /&gt;
&lt;br /&gt;
            if (elem)&lt;br /&gt;
&lt;br /&gt;
               elem.label = labels[i];&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   var answerFilter=&amp;quot;{INSERTANS:96553X63X759}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   for (i=0; i&amp;lt;30; i++){&lt;br /&gt;
&lt;br /&gt;
     var iLabel = document.getElementById(&#039;answer96553X63X760&#039;+(i+1]].label.innerHTML;&lt;br /&gt;
&lt;br /&gt;
     if (answerFilter.search(iLabel) == -1){&lt;br /&gt;
&lt;br /&gt;
       // Hide element&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question760&#039;).find(&#039;li&#039;).eq(i).hide();&lt;br /&gt;
&lt;br /&gt;
       // Set value of hidden elements to zero&lt;br /&gt;
&lt;br /&gt;
       document.getElementById(&#039;answer96553X63X760&#039;+(i+1)).value = 0;&lt;br /&gt;
&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 });&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use an answer to prefill another question (default value)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;And tested with: 1.91+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the enhanced defaults feature, which lets you pre-fill most question types with default values.  In 1.91, you could set defaults for list and multiple choice questions.  In 1.92, you can set defaults for any text-entry question too.  Moreover, the defaults can be [[Expression Manager|Expression Manager]] compatible equations or tailored text.  Finally, with 1.92, defaults are properly managed even when set on the same page.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround gives you the ablility to use an answer to fill the default value for another question. It&#039;s explained for free text question type but can be adapted for another question type.&lt;br /&gt;
&lt;br /&gt;
We use SGQA identifier. For example, we use SGQA 1000X10X20 and 1000X10X21 to prefill 1000X11X30 and 1000X11X31. For the script to work, the question has to be on a different page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X11X30&#039;).val(&#039;{INSERTANS:1000X10X20}&#039;);&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X11X31&#039;).val(&#039;{INSERTANS:1000X10X21}&#039;);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want use two times the value of an integer input, you can also use this to prefill a question that you hide via CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X2X2&#039;).val(parseInt(&#039;{INSERTANS:1000X1X1}&#039;)*2);&lt;br /&gt;
&lt;br /&gt;
 $(&amp;quot;#question2&amp;quot;).hide();&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use {INSERTANS:1000X2X2} for giving you twice the value of the user input from question 1.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Sum=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do with [[Expression Manager|Expression Manager]] using the sum() function.  Not only will sums be dynamic, but they wille exclude irrelevant values, so you can array_filter a multiple numeric question and get the sum of just the answers that are visible.  This [[Expression Manager HowTos#Calculate assessment values at runtime and store the results in the survey data|HowTo example]] demonstrates the dynamic sum feature.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Also note, as of version 1.92, the following workaround will fail, since it includes a a regular expression containing curly braces.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script is used with a &amp;quot;Multiple Options&amp;quot; type question calculate a total price based on how which checkboxes are selected. The prices are listed as part of the answer. The answers are set up like this: &amp;quot;USB Mouse ($20)&amp;quot;. The script uses the number between the &amp;quot;($&amp;quot; and the &amp;quot;)&amp;quot; as the price for that item. You can adapt the script to if you need to change the currency or need to sum something other than money.&lt;br /&gt;
&lt;br /&gt;
This script works when used in a question-by-question format.  It does not work when there are more than one question on a page. I think it can be adapted to work, but I haven&#039;t done the coding yet.&lt;br /&gt;
&lt;br /&gt;
Put the following code into body of your question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script language=Javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// General definitions&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match the labels containing information about an answer&lt;br /&gt;
&lt;br /&gt;
// In LimeSurvey, these labels start with &amp;quot;answer...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
var answerRegex = /^answer/;&lt;br /&gt;
&lt;br /&gt;
// Find all answer checkboxes in the document and set their&lt;br /&gt;
&lt;br /&gt;
// onchange events to updatePrice&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   // Find all input elements&lt;br /&gt;
&lt;br /&gt;
   var inputList=document.getElementsByTagName(&amp;quot;input&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   // Loop through each, looking for checkboxes&lt;br /&gt;
&lt;br /&gt;
   var i;&lt;br /&gt;
&lt;br /&gt;
   for( i=0; i&amp;lt; inputList.length;i++ )&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // If input item does not have an ID, skip&lt;br /&gt;
&lt;br /&gt;
       if (! (inputList[i].id)) { continue; }&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if ID doesn&#039;t start with &amp;quot;answer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
       if (!answerRegex.test(inputList[i].id)) { continue; }&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if not a checkbox&lt;br /&gt;
&lt;br /&gt;
       if (inputList[i].type.toUpperCase()!=&#039;CHECKBOX&#039;)  { continue; }&lt;br /&gt;
&lt;br /&gt;
       // This is an answer checkbox!&lt;br /&gt;
&lt;br /&gt;
       // Setup onchange event&lt;br /&gt;
&lt;br /&gt;
       inputList[i].onclick = updatePrice;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Load initial sum&lt;br /&gt;
&lt;br /&gt;
   updatePrice();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function updatePrice()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
var labels=document.getElementsByTagName(&amp;quot;LABEL&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match a price inside parenthesis&lt;br /&gt;
&lt;br /&gt;
// For example: ($29) or ($29.54).&lt;br /&gt;
&lt;br /&gt;
// Set up&lt;br /&gt;
&lt;br /&gt;
priceRegex = /\(\$(\d*\.{0,1}\d+)\)/;&lt;br /&gt;
&lt;br /&gt;
// Loop through all the labels, looking for labels corresponding to&lt;br /&gt;
&lt;br /&gt;
// answers that have a price in them.&lt;br /&gt;
&lt;br /&gt;
var i;&lt;br /&gt;
&lt;br /&gt;
var total = 0;&lt;br /&gt;
&lt;br /&gt;
for( i=0; i&amp;lt;labels.length;i++ )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   var myArray;    // Define array used for regex matching&lt;br /&gt;
&lt;br /&gt;
   var inputID;    // Define field element&lt;br /&gt;
&lt;br /&gt;
   // Get the ID of the field corresponding to the label using the&lt;br /&gt;
&lt;br /&gt;
   // &amp;quot;htmlFor&amp;quot; attribute&lt;br /&gt;
&lt;br /&gt;
   // (FYI, there are some labels that will have to be screened out&lt;br /&gt;
&lt;br /&gt;
   // because they don&#039;t correspond to an answer)&lt;br /&gt;
&lt;br /&gt;
   // Does the label start with &amp;quot;answer&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
   // If not: exit.&lt;br /&gt;
&lt;br /&gt;
   if (!answerRegex.test(labels[i].htmlFor)) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // First make sure this element exists&lt;br /&gt;
&lt;br /&gt;
   // If it doesn&#039;t, go to the next element&lt;br /&gt;
&lt;br /&gt;
   // If it does, it will be defined in inputID&lt;br /&gt;
&lt;br /&gt;
   if (! (inputID = document.getElementById(labels[i].htmlFor)) ) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // See if the corresponding answer is a checkbox that is checked.&lt;br /&gt;
&lt;br /&gt;
   // If not, go to next label&lt;br /&gt;
&lt;br /&gt;
   if (inputID.type.toUpperCase()!=&#039;CHECKBOX&#039;)  { continue; }&lt;br /&gt;
&lt;br /&gt;
   if (!inputID.checked) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // This is label for an answer.&lt;br /&gt;
&lt;br /&gt;
   // The innerHTML will give us the text of the label&lt;br /&gt;
&lt;br /&gt;
   // The price information will be in the form ($XX.XX)&lt;br /&gt;
&lt;br /&gt;
   // which in contained in the label text.&lt;br /&gt;
&lt;br /&gt;
   // Find a match for a decimal number inside the pattern &amp;quot;($&amp;quot; and &amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   if [[myArray = priceRegex.exec(labels[i].innerHTML]] != null)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // Keep a running tally&lt;br /&gt;
&lt;br /&gt;
       total += parseFloat(myArray[1]);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // Update total price on form&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&amp;quot;totalPrice&amp;quot;).value = &amp;quot;$&amp;quot; + formatCurrency(total);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function formatCurrency(num) {&lt;br /&gt;
&lt;br /&gt;
  num = isNaN(num) || num &amp;lt;u&amp;gt; &#039;&#039; || num &amp;lt;/u&amp;gt; null ? 0.00 : num;&lt;br /&gt;
&lt;br /&gt;
  return parseFloat(num).toFixed(2);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put the following code in the help section (or wherever you want the sum to appear):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Total Cost for selected accessories: &amp;lt;input type=&amp;quot;readonly&amp;quot; value=&amp;quot;&amp;quot; id=&amp;quot;totalPrice&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Focus on the first Input field=&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: LimeSurvey 1.80 / IE6/7, Firefox 3, Safari, Opera, chrome&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.91, there is a built-in JavaScript function called  focusFirst() to focus on the first visible element.  It uses jQuery, so is more robust than this example.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again an onload Function is needed for this tasks. I have done it the DOM way with compatibility to IE6/7.&lt;br /&gt;
&lt;br /&gt;
Put the following code into the startpage.pstpl of your template, right before the &amp;lt;/head&amp;gt; closing tag:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   function focusFirst(Event)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       var i=0;&lt;br /&gt;
&lt;br /&gt;
       while(document.forms[0].elements[i].type == &amp;quot;hidden&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           i++;&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       document.forms[0].elements[i].focus();&lt;br /&gt;
&lt;br /&gt;
       return;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(ie)&lt;br /&gt;
&lt;br /&gt;
   { window.attachEvent(&amp;quot;onload&amp;quot;, focusFirst); }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   { document.addEventListener(&amp;quot;load&amp;quot;, focusFirst, true); }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; I am using this with version 1.80. As changes happened to the templates in the last release, you might need to add the following before the code, if your template is older than 1.80 stable and does not include this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   var ie = false;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will need this for the var ie to be set. Without this var, the function will not work with ie.&lt;br /&gt;
&lt;br /&gt;
=Answer questions by keypress=&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: IE7, Firefox 3&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
This workaround allow to answer the question on key 0-9 (0 is for the 10 answer).&lt;br /&gt;
&lt;br /&gt;
Follow issues are supported at the moment:&lt;br /&gt;
*Yes-No Questions&lt;br /&gt;
*List Questions (radio)&lt;br /&gt;
*other radio questions&lt;br /&gt;
&lt;br /&gt;
In lists the answer limit is ten.&lt;br /&gt;
&lt;br /&gt;
You supply the template &amp;quot;endpage&amp;quot; of your template with the following script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   jQuery(document).bind(&#039;keypress&#039;, function(e){&lt;br /&gt;
&lt;br /&gt;
       if (48 &amp;lt;= e.which &amp;amp;&amp;amp; e.which &amp;lt;= 57) {&lt;br /&gt;
&lt;br /&gt;
           jQuery(&#039;input:radio&#039;).each(function() {&lt;br /&gt;
&lt;br /&gt;
               var v = jQuery(this).val();&lt;br /&gt;
&lt;br /&gt;
               var c = (e.which &amp;lt;u&amp;gt; 48) ? 10 : e.which - 48;&lt;br /&gt;
&lt;br /&gt;
               if(v &amp;lt;/u&amp;gt; &#039;Y&#039; || v &amp;lt;u&amp;gt; &#039;N&#039;) {&lt;br /&gt;
&lt;br /&gt;
                   v = (v &amp;lt;/u&amp;gt; &#039;Y&#039;) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               if(v == c) {&lt;br /&gt;
&lt;br /&gt;
                   jQuery(this).click();&lt;br /&gt;
&lt;br /&gt;
                   jQuery(&#039;#limesurvey input:submit&#039;).click();&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   })&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Math notation in LimeSurvey=&lt;br /&gt;
#download the js file from [http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html AsciiMath script]&lt;br /&gt;
#copy it in the /scripts/ folder in your installation&lt;br /&gt;
#modify the startpage.psptl of the template you want to use adding the reference to the script (if you use an older version make sure that you copy the template folder first!) for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;ASCIIMathML.js&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the notation where you need it!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you use internet explorer or safari you will need to download the plugin as well, but firefox does the lot for you.&lt;br /&gt;
&lt;br /&gt;
Finally, if you are confident with the limesurvey structure you could add the editor which support math notation and change the reference to the editor you want to use in the configuration file. here is the [http://www.imathas.com/editordemo/demo.html link for a TinyMCE with math support].&lt;br /&gt;
&lt;br /&gt;
=Reverse array_filter (for pre-1.90)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Version 1.91 natively supports this functionality via the array_filter_exclude advanced quation option.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used to filter the answers of an array question to be displayed based on the answers of a multi option question that were &#039;&#039;&#039;NOT&#039;&#039;&#039; selected. A possible application would be to have a multi-option question asking which products were purchased, followed by 2 array questions - one asking to rate the purchased products and another asking why the remaining products were not purchased. Another would be to ask about sessions attended at a conference as in [http://www.limesurvey.org/en/forum/5-can-i-do-this-with-limesurvey/27970-reverse-of-arrayfilter.html this forum thread] and pictured below. There is a live [http://www.partnersinc.biz/surveys//index.php?sid=43358&amp;amp;newtest=Y&amp;amp;lang=en demo here]&lt;br /&gt;
&lt;br /&gt;
[[File:sessions_645x344.gif]]&lt;br /&gt;
&lt;br /&gt;
We&#039;ll use the above example to explain the process as follows:&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsAttended&#039;&#039; multi-options question&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsNotAttended&#039;&#039; multi-options question with identical answers as &#039;&#039;SessionsAttended&#039;&#039; and hide it with styles or conditions&lt;br /&gt;
#In group 2 - Create a &#039;&#039;RateSessionsAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsAttended&#039;&#039;&lt;br /&gt;
#In group 2 - Create a &#039;&#039;ReasonNotAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsNotAttended&#039;&#039;&lt;br /&gt;
#In group 1 - Place JavaScript/jQeury listeners on each of the checkboxes in &#039;&#039;SessionsAttended&#039;&#039; that would toggle the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
&lt;br /&gt;
The JavaScript/jQuery code used would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       // The toggle function&lt;br /&gt;
&lt;br /&gt;
   function toggle(q1, q2) {&lt;br /&gt;
&lt;br /&gt;
       if ($(q1).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       else {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Initialize the SessionNotAttended checkboxes to &amp;quot;checked&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   // The jQuery listeners on the SessionAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   // that toggle the SessionNotAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X331&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X332&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X333&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X334&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some notes about the code:&lt;br /&gt;
*The code is in an onload function defined in the first question of group 1 - see [[Workarounds#Custom_onload_function|here]]&lt;br /&gt;
*Both &#039;&#039;SessionsAttended&#039;&#039; and &#039;&#039;SessionsNotAttended&#039;&#039; must be in the same group for the toggling to work&lt;br /&gt;
*This case only uses 4 checkboxes but could be expanded as required&lt;br /&gt;
*In this case the survey ID is 11111, the group ID is 22, &#039;&#039;SessionsAttended&#039;&#039; ID is 33 and SessionsNotAttended ID is 44 - these would need to be modified for your survey&lt;br /&gt;
*The toggle function looks for the state of a checkbox in &#039;&#039;SessionsAttended&#039;&#039; and sets the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
*The &amp;quot;Initialize&amp;quot; section sets the state of &#039;&#039;SessionsNotAttended&#039;&#039; checkboxes whenever we navigate to the group&lt;br /&gt;
*The &amp;quot;Listener&amp;quot; section uses jQuery listeners to detect any change in the &#039;&#039;SessionsAttended&#039;&#039; checkboxes and then toggle the corresponding &#039;&#039;SessionsNotAttended&#039;&#039; checkbox&lt;br /&gt;
&lt;br /&gt;
Some general notes about the questions:&lt;br /&gt;
*CSS can be used to hide &#039;&#039;SessionsNotAttended&#039;&#039; (div#question44 { display: none; }) if you don&#039;t want to use conditions (because maybe you&#039;ve got [[Optional settings#Survey Behavior|$deletenonvalues set to 1]])&lt;br /&gt;
*&#039;&#039;RateSessionsAttended&#039;&#039; and &#039;&#039;ReasonNotAttended&#039;&#039; are another group to avoid things popping in and out of existence as &#039;&#039;SessionsAttended&#039;&#039; is answered&lt;br /&gt;
*[[Setting conditions|Conditions]] are used to ensure that &#039;&#039;RateSessionsAttended&#039;&#039; only appears if some sessions are selected and &#039;&#039;ReasonNotAttended&#039;&#039; only appears if no sessions are selected&lt;br /&gt;
&lt;br /&gt;
=Filter Ranking Question With Multiple-Options (pre 1.92)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90, IE 7/8, FireFox 3/4, Safari 5.0, Chrome 10.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, most of this is easier to do using the the array_filter attribute, or relevance equations in general.  They all work on the same page, and fully support cascading relevance.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround applies a filter to a ranking question based on the checked boxes of a previous multiple-options question. There are two methods - one for filter and ranking questions being on the same page and a slightly different one for the filter question being on a page before the ranking question.&lt;br /&gt;
&lt;br /&gt;
There is a [http://www.partnersinc.biz/surveys//index.php?sid=96314&amp;amp;newtest=Y&amp;amp;lang=en demo of both methods here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH METHODS:&#039;&#039;&#039;&lt;br /&gt;
*[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
*Place the following script in your template.js file. This function will be accessed by either method.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// A function to filter choices in a ranking question&lt;br /&gt;
function rankFilter(q1ID, q2ID, prevPage) {&lt;br /&gt;
&lt;br /&gt;
	// If filter question is on a previous page, hide Q1 and check all &amp;quot;visible&amp;quot; boxes&lt;br /&gt;
	if(prevPage == 1) {&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; li[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;javatbd&amp;quot;]:visible input.checkbox&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039;&#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	handleChecked(q1ID, q2ID);&lt;br /&gt;
	$(&#039;#question&#039;+q1ID+&#039; input.checkbox&#039;).click(function() {&lt;br /&gt;
		handleChecked(q1ID, q2ID);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	function handleChecked(q1ID, q2ID) {&lt;br /&gt;
	&lt;br /&gt;
		// Find the survey and group IDs&lt;br /&gt;
		if($( &#039;input#fieldnames&#039; ).length != 0) {&lt;br /&gt;
			var fieldNames = $( &#039;input#fieldnames&#039; ).attr(&#039;value&#039;);&lt;br /&gt;
			var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
			var sID = tmp[0];&lt;br /&gt;
			var gID = tmp[1];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Loop through all Q1 options&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.checkbox&#039;).each(function(i) {&lt;br /&gt;
		&lt;br /&gt;
			// Find the answer code and value&lt;br /&gt;
			var tmp2 = $(this).attr(&#039;id&#039;).split(&#039;X&#039;+gID+&#039;X&#039;+q1ID+&#039;&#039;);&lt;br /&gt;
			var ansCode = tmp2[1];&lt;br /&gt;
			var ansTxt = $(this).next(&#039;label&#039;).text();&lt;br /&gt;
			&lt;br /&gt;
			// If option is checked and not in rank choices or output, add it to the rank choices&lt;br /&gt;
			if($(this).attr(&#039;checked&#039;) == true&lt;br /&gt;
						  &amp;amp;&amp;amp; $(&#039;#question&#039;+q2ID+&#039; select.select option[value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).length == 0&lt;br /&gt;
						  &amp;amp;&amp;amp; $(&#039;#question&#039;+q2ID+&#039; .output input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;][value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).length == 0) {&lt;br /&gt;
				$(&#039;&amp;lt;option value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;&amp;gt;&#039;+ansTxt+&#039;&amp;lt;/option&amp;gt;&#039;).appendTo(&#039;#question&#039;+q2ID+&#039; select.select&#039;);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// If option is unchecked...&lt;br /&gt;
			else if($(this).attr(&#039;checked&#039;) == false) {&lt;br /&gt;
				// Remove it from the rank choices&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select option[value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).remove();&lt;br /&gt;
				// Remove it from the rank output and reset hidden values&lt;br /&gt;
$(&#039;#question&#039;+q2ID+&#039; .output input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;][value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).attr(&#039;value&#039;, &#039;&#039;).siblings(&#039;input.text&#039;).val(&#039;&#039;).siblings(&#039;img&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Clean up empty inputs in the rank output table&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr&#039;).each(function(i) {&lt;br /&gt;
			var nextRow = $(this).next(&#039;tr&#039;);&lt;br /&gt;
			if($(&#039;input.text&#039;, this).val() == &#039;&#039; &amp;amp;&amp;amp; $(&#039;input.text&#039;, nextRow).val() != &#039;&#039;) {&lt;br /&gt;
				$(&#039;input.text&#039;, this).val($(&#039;input.text&#039;, nextRow).val());&lt;br /&gt;
				$(&#039;input.text&#039;, nextRow).val(&#039;&#039;);&lt;br /&gt;
				$(&#039;input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, this).attr(&#039;value&#039;, $(&#039;input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, nextRow).attr(&#039;value&#039;));&lt;br /&gt;
				$(&#039;input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, nextRow).attr(&#039;value&#039;, &#039;&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Show the scissors for the last populated rank output row&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table img[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;cut_&amp;quot;]&#039;).hide();&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table input.text[value!=&amp;quot;&amp;quot;]:last&#039;).siblings(&#039;img[id&amp;lt;/div&amp;gt;=&amp;quot;cut_&amp;quot;]&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Hide extra rank output rows&lt;br /&gt;
		var optNum = $(&#039;#question&#039;+q1ID+&#039; input.checkbox:checked&#039;).length;&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr&#039;).hide();&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr:lt(&#039;+(optNum+1)+&#039;)&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Hide and clear the ranking question if there are less than 2 checked options in Q1&lt;br /&gt;
		if(optNum &amp;lt; 2) {&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039;&#039;).hide();&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039; input.text&#039;).val(&#039;&#039;);&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039; input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;).attr(&#039;value&#039;, &#039;&#039;);&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039;&#039;).show();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// A workaround for the built in max-answers function&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; td.output tr:visible&#039;).each(function(i) {&lt;br /&gt;
			if($(&#039;input.text&#039;, this).val() == &#039;&#039;) {&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// A listener to work around the built in max-answers function&lt;br /&gt;
	$(&#039;#question&#039;+q2ID+&#039; td.rank&#039;).click(function (event) {&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; td.item input.text&#039;).each(function(i) {&lt;br /&gt;
			if ($(this).val() == &#039;&#039;) {&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH FILTER AND RANKING QUESTIONS ON SAME PAGE:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question and a ranking question on the same page (in the same group).&lt;br /&gt;
*Both questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Place the following script in the source of one of the questions.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;RR&amp;quot; with the ID of the ranking question.&lt;br /&gt;
*The function will hide the ranking question unless at least two options are selected in the multiple options question, in which case, it will only show the options selected.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		rankFilter(MM, RR);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR FILTER AND RANKING QUESTIONS ON SEPARATE PAGES:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question on page 1.&lt;br /&gt;
*Create a multiple options question and a ranking question on page 2.&lt;br /&gt;
*All three questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Set the multiple options on page 2 to be filtered by the multiple options on page 1.&lt;br /&gt;
*Place the following script in the source of one of the questions on page 2.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;RR&amp;quot; with the ID of the ranking question. Do not modify the &amp;quot;1&amp;quot;.&lt;br /&gt;
*The function will hide the multiple options question. If at least 2 options were selected in the multiple options on page 1, the corresponding options will be checked in the hidden multiple options question which will then be used to control the display of the ranking question.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		rankFilter(MM, RR, 1);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Filter &amp;quot;Array by Column&amp;quot; Question With &amp;quot;Multiple-Options&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, FireFox 3/4, Safari 5.0, Chrome 10.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround applies a filter to an &amp;quot;Array by Column&amp;quot; question based on the checked boxes of a previous multiple-options question. There are two methods - one for filter and array questions being on the same page and a slightly different one for the filter question being on a page before the array question.&lt;br /&gt;
&lt;br /&gt;
There is a [http://www.partnersinc.biz/surveys//index.php?sid=74213&amp;amp;newtest=Y&amp;amp;lang=en demo of both methods here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH METHODS:&#039;&#039;&#039;&lt;br /&gt;
*[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
*Place the following scripts in your template.js file. These functions will be accessed by either method.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
	function filterArrByCol(qMultiOpt, qArray, prevPage) {&lt;br /&gt;
	&lt;br /&gt;
		// If filter question is on a previous page, hide Q1 and check all &amp;quot;visible&amp;quot; boxes&lt;br /&gt;
		if(prevPage == 1) {&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039; li[id&amp;lt;/div&amp;gt;=&amp;quot;javatbd&amp;quot;]:visible input.checkbox&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039;&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Assign classes to the answer cells&lt;br /&gt;
		$(&#039;#question&#039;+qArray+&#039; table.question tbody td&#039;).each(function(i){&lt;br /&gt;
			var classArr = $(this).attr(&#039;class&#039;).split(&#039;answer_cell_00&#039;);&lt;br /&gt;
			var ansCode = classArr[1];&lt;br /&gt;
			$(this).addClass(&#039;ans-&#039;+ansCode+&#039; filtered&#039;);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Assign classes to the answer label cells&lt;br /&gt;
		$(&#039;#question&#039;+qArray+&#039; table.question tbody tr:eq(0) td&#039;).each(function(i){&lt;br /&gt;
			var classArr2 = $(this).attr(&#039;class&#039;).split(&#039; ans-&#039;);&lt;br /&gt;
			var ansCode2 = classArr2[1];&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; table.question thead tr:eq(0) th:eq(&#039;+i+&#039;)&#039;).addClass(&#039;ans-&#039;+ansCode2+&#039;&#039;);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Fire the filter function on page load&lt;br /&gt;
		filterArr(qMultiOpt, qArray);&lt;br /&gt;
&lt;br /&gt;
		// Listener on multi-opt checkboxes to fire the filter function&lt;br /&gt;
		$(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox&#039;).click(function(){&lt;br /&gt;
			filterArr(qMultiOpt, qArray);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// On submit, clear all hidden radios of array&lt;br /&gt;
		$(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; td.filtered:hidden&#039;).each(function(i){&lt;br /&gt;
				$(&#039;input.radio&#039;, this).attr(&#039;checked&#039;, false);&lt;br /&gt;
			});&lt;br /&gt;
			return true;&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function filterArr(qMultiOpt, qArray) {&lt;br /&gt;
	&lt;br /&gt;
		if($(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox:checked&#039;).length &amp;lt; 1) {&lt;br /&gt;
			// Hide the array if no multi-opt options are checked&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039;&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039;&#039;).show();&lt;br /&gt;
			&lt;br /&gt;
			// Hide all columns of array&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; table.question tbody td, #question&#039;+qArray+&#039; table.question thead th&#039;).hide();&lt;br /&gt;
			&lt;br /&gt;
			// Loop through multi-opt checkboxes and, if checked, show corresponding column of array&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox&#039;).each(function(i){&lt;br /&gt;
				if($(this).attr(&#039;checked&#039;) == true) {&lt;br /&gt;
					var classArr3 = $(this).attr(&#039;id&#039;).split(&#039;X&#039;+qMultiOpt);&lt;br /&gt;
					var ansCode3 = classArr3[1];&lt;br /&gt;
					$(&#039;#question&#039;+qArray+&#039; .ans-&#039;+ansCode3+&#039;&#039;).show();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH FILTER AND ARRAY QUESTIONS ON SAME PAGE:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question and an array-by-column question on the same page (in the same group).&lt;br /&gt;
*Both questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Place the following script in the source of one of the questions.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;AA&amp;quot; with the ID of the ranking question.&lt;br /&gt;
*The function will hide the array question unless at least one option is selected in the multiple-options question, in which case, it will only show the corresponding array column(s).&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		filterArrByCol(MM, AA);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR FILTER AND ARRAY QUESTIONS ON SEPARATE PAGES:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question on page 1.&lt;br /&gt;
*Create a multiple options question and an array-by-column question on page 2.&lt;br /&gt;
*All three questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Set the multiple options on page 2 to be filtered by the multiple options on page 1.&lt;br /&gt;
*Place the following script in the source of one of the questions on page 2.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;AA&amp;quot; with the ID of the array question. Do not modify the &amp;quot;1&amp;quot;.&lt;br /&gt;
*The function will hide the multiple options question. If options were selected in the multiple options on page 1, the corresponding options will be checked in the hidden multiple options question which will then be used to control the display of the array columns.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		filterArrByCol(MM, AA, 1);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Auto-tabbing between text input fields=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a workaround to facilitate auto-tabbing between text input questions in a single group using a [http://plugins.jquery.com/project/autotab jQuery plugin by Mathachew] and the Maximum characters attribute of questions.&lt;br /&gt;
&lt;br /&gt;
The behaviour will be: When the maximum number of characters has been entered into an input field, the focus (cursor) will be automatically moved to the next input field. When the backspace key is used to remove all characters from a field, the focus will be moved to the previous field. It&#039;s very useful in surveys having many text input questions to avoid having to manually tab or click between fields.&lt;br /&gt;
&lt;br /&gt;
You can view a small demo survey [http://www.partnersinc.biz/surveys//index.php?sid=11327&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Visit [http://plugins.jquery.com/autotabs http://plugins.jquery.com/autotabs], download the plugin script and save it as &#039;&#039;jquery.autotab-1.1b.js&#039;&#039; in the template folder.&lt;br /&gt;
#Link to the script by placing &#039;&#039;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autotab-1.1b.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&#039;&#039; within the &#039;&#039;&amp;lt;head&amp;gt;&#039;&#039; tag of startpage.pstpl.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Create the text based questions that auto-tabbing is to be applied to. (All must be in the same group if you&#039;re using group by group presentation)&lt;br /&gt;
#Define a Maximum characters attribute for all questions that the autotab is applied to.&lt;br /&gt;
{{QS:maximum_chars}}  &lt;br /&gt;
#In the source of the first question of the group that contains the auto-tabbed questions, add the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXAA&#039;).focus(); //initially focus on the first input&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXAA&#039;).autotab({ target: &#039;answerSSSSSXGGXBB&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXBB&#039;).autotab({ previous: &#039;answerSSSSSXGGXAA&#039;, target: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXCC&#039;).autotab({ previous: &#039;answerSSSSSXGGXBB&#039;, target: &#039;answerSSSSSXGGXDD&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXDD&#039;).autotab({ previous: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example has 4 fields to be auto-tabbed between - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
*SSSSS -&amp;gt; Survey ID&lt;br /&gt;
*GG -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Last question&lt;br /&gt;
&lt;br /&gt;
[[File:ids_343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;target&#039;&#039; parameter defines where the next input is and the &#039;&#039;previous&#039;&#039; parameter defines (you guessed it) the previous input.&lt;br /&gt;
&lt;br /&gt;
This plugin also has limited capability of formatting the input text - see comments in the plugin script.&lt;br /&gt;
&lt;br /&gt;
=Custom response listeners=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Listeners can be used to perform functions when a change in an input is detected. There are many uses such as the [[Workarounds#Reverse_array_filter|Reverse array_filter]] but a simple one would be to warn a respondent if they enter a value that may be too high.&lt;br /&gt;
&lt;br /&gt;
We can use the [http://docs.jquery.com/Events/change jQuery change( ) event] to fire a function whenever there is a change to the input. The function will look for an input value higher than 10 and, if found, will warn the respondent.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the script below in the source of one of the questions on the page where:&lt;br /&gt;
**11111 is the survey ID&lt;br /&gt;
**22 is the group ID&lt;br /&gt;
**33 is the question ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer11111X22X33&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
			if ( $(&#039;#answer11111X22X33&#039;).val() &amp;gt; 10 ) {&lt;br /&gt;
				alert (&amp;quot;That&#039;s an awful lot. Are you sure?&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Text input masks=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number ((###) ###-####) or a Canadian postal code (A1A 1A1) The [http://plugins.jquery.com/project/meioMask jQuery meioMask plugin by fabiomcosta] can be used to do this.&lt;br /&gt;
&lt;br /&gt;
The plugin has several pre-defined masks and supports custom masks. It also allows for pasting of input, allows default values and can auto-focus the next form element when the current input is completely filled. See [http://www.meiocodigo.com/projects/meiomask/ http://www.meiocodigo.com/projects/meiomask/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
There is a small demo [http://www.partnersinc.biz/surveys//index.php?sid=36146&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo was as follows:&lt;br /&gt;
#Visit [http://www.meiocodigo.com/projects/meiomask/ http://www.meiocodigo.com/projects/meiomask/], download the latest plugin script and save it as jquery.meiomask.js in the template folder.&lt;br /&gt;
#Link to the script by placing &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.meiomask.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; within the &amp;lt;head&amp;gt; tag of startpage.pstpl.&lt;br /&gt;
#Turn off $filterxsshtml to allow insertion of JavaScript in the questions. ([http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects See documentation here])&lt;br /&gt;
#Create the text input questions that the masks are to be applied to&lt;br /&gt;
#In the source of the help section of the first question of the group that contains the masked inputs, add the following code. ([http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ See How to use script here]) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {	&lt;br /&gt;
						   &lt;br /&gt;
	// Define custom masks&lt;br /&gt;
	$.mask.masks = $.extend($.mask.masks,{&lt;br /&gt;
		customMask1:{ mask: &#039;a9a 9a9&#039; }, // Canadian postal code&lt;br /&gt;
		// Maximum input of 9,999.99, reverse input, default value of 0.00		&lt;br /&gt;
		customMask2:{ mask: &#039;99.999,9&#039;, type : &#039;reverse&#039;, defaultValue : &#039;000&#039; } &lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Set the &#039;alt&#039; attributes of the inputs&lt;br /&gt;
	$(&#039;#answer111111X22XAA&#039;).attr(&#039;alt&#039;, &#039;phone-us&#039;); // a pre-defined mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XBB&#039;).attr(&#039;alt&#039;, &#039;customMask1&#039;); // a custom mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XCC&#039;).attr(&#039;alt&#039;, &#039;customMask2&#039;); // a custom mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XDD&#039;).attr(&#039;alt&#039;, &#039;cc&#039;); // a pre-defined mask for credit card&lt;br /&gt;
	&lt;br /&gt;
	// Tell the plugin to apply masks to these inputs&lt;br /&gt;
	$(&#039;input:#answer111111X22XAA&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XBB&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XCC&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XDD&#039;).setMask();	&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first section defines two custom masks to be used - one for Canadian postal code with a format of A#A #A# and a second for a maximum amount of 9999.99 with reverse input (useful for cost inputs) and a default value of 0.00.&lt;br /&gt;
&lt;br /&gt;
The next section sets the &amp;quot;alt&amp;quot; attributes for the text inputs. This will tell meioMask which mask we will be applying to each input. By default meioMask looks at the alt attribute to find which mask to apply however this can be changed using the [http://www.meiocodigo.com/projects/meiomask/#mm_options mask options].&lt;br /&gt;
&lt;br /&gt;
In the final section we apply the masks to the inputs.&lt;br /&gt;
&lt;br /&gt;
This example has 4 inputs with masks on them - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
&lt;br /&gt;
*11111 -&amp;gt; Survey ID&lt;br /&gt;
*22 -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Fourth question&lt;br /&gt;
&lt;br /&gt;
[[File:Ids 343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
=Text input masks - second method=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91RC6+, FireFox 4.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number ((###) ###-####) or a US social security number (###-##-####). The jQuery meioMask plugin by fabiomcosta is no longer supported but an alternative exists. The DigitalBush Masked Input Plugin is updated and simple to implement in LimeSurvey. See [http://digitalbush.com/projects/masked-input-plugin/ http://digitalbush.com/projects/masked-input-plugin/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
Implementation as follows:&lt;br /&gt;
&lt;br /&gt;
#Visit [http://digitalbush.com/projects/masked-input-plugin/ http://digitalbush.com/projects/masked-input-plugin/], download the latest plugin script and save it as jquery.maskedinput.js in the template folder.&lt;br /&gt;
#Link to the script by placing &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.maskedinput.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; within the &amp;lt;head&amp;gt; tag of startpage.pstpl.&lt;br /&gt;
#Turn off $filterxsshtml to allow insertion of JavaScript in the questions. ([http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects See documentation here])&lt;br /&gt;
#Create the text input questions that the masks are to be applied to&lt;br /&gt;
#In the source of the help section of the first question of the group that contains the masked inputs, add the following code. ([http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ See How to use script here])  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function($) {	 &lt;br /&gt;
		$(&amp;quot;#answer55431X1X5&amp;quot;).mask(&amp;quot;999-99-9999&amp;quot;,{ placeholder:&amp;quot;#&amp;quot; });&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace the &amp;quot;#answer55431X1X5&amp;quot; with your survey ID, group ID, and question ID. You can change the mask format and change or eliminate the placeholder if you wish. If you have multiple questions in the same group, simply copy and paste the line that begins with &amp;quot;$&amp;quot; and change the code to what is needed for your application.&lt;br /&gt;
&lt;br /&gt;
=Select a random response to a &amp;quot;Multiple options&amp;quot; question for later use=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to randomly select one of the checked boxes in a &amp;quot;Multiple options&amp;quot; question and store it&#039;s label for later use in the survey. A possible use would be to have a question asking what products were purchased and then randomly selecting one of the products to ask further questions about.&lt;br /&gt;
&lt;br /&gt;
There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=81252&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Basically what we&#039;ve done here is to put listeners on all of the checkboxes. If a change of state is detected in any of them the &amp;quot;randomResponse&amp;quot; function is called which loops through all of the checkboxes and if it finds a checked state, that box&#039;s label is added to an array. Then a random item is pulled from the array and used to populate the hidden question. This hidden question can then be drawn upon later in the survey using [http://docs.limesurvey.org/tiki-index.php?page=Adding+a+Question#Information_from_previous_answers INSERTANS] or [http://docs.limesurvey.org/tiki-index.php?page=Setting+conditions&amp;amp;structure=English+Instructions+for+LimeSurvey Conditions].&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
#[http://docs.limesurvey.org/tiki-index.php?page=Workarounds%3A+Manipulating+a+survey+at+runtime+using+Javascript&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._in_LimeSurvey_ Set up your survey to use JavaScript].&lt;br /&gt;
#Create a &amp;quot;Multiple options&amp;quot; question that we&#039;re going to randomly pick a checked box from&lt;br /&gt;
#Create a text input question to store the label of the checked box in (we&#039;re going to hide this with JavaScript)&lt;br /&gt;
#Place the script below in the source of one of the questions on the page. &lt;br /&gt;
&lt;br /&gt;
The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
*EDIT HERE (1) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 44 -&amp;gt; hidden question ID.&lt;br /&gt;
*EDIT HERE (2) - 44 -&amp;gt; hidden question ID.&lt;br /&gt;
*EDIT HERE (3) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 33 -&amp;gt; multiple option question ID, A/B/C/D/E/F -&amp;gt; multiple option answer codes. Also add or remove CBs for more or less checkboxes.&lt;br /&gt;
*EDIT HERE (4) - add or remove CBs for more or less checkboxes.&lt;br /&gt;
*EDIT HERE (5) - add or remove CBs for more or less checkboxes. &lt;br /&gt;
&lt;br /&gt;
For more info on these IDs see [http://docs.limesurvey.org/tiki-index.php?page=SGQA+identifier&amp;amp;structure=English+Instructions+for+LimeSurvey SGQA identifier].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
				&lt;br /&gt;
		//// Identify the hidden question input&lt;br /&gt;
		//// EDIT HERE (1) - replace with your hidden question input ID&lt;br /&gt;
		var hiddenInput = &#039;#answer11111X22X44&#039;;&lt;br /&gt;
		&lt;br /&gt;
		//// Make the &amp;quot;hidden&amp;quot; question disappear&lt;br /&gt;
		//// EDIT HERE (2) - replace with your hidden question ID&lt;br /&gt;
		$(&#039;#question44&#039;).hide();&lt;br /&gt;
		&lt;br /&gt;
		//// Identify the checkboxes to be randomized&lt;br /&gt;
		//// EDIT HERE (3) - add or remove as required, &lt;br /&gt;
		//// replace with your checkbox IDs&lt;br /&gt;
		var CB1 = &#039;#answer11111X22X33A&#039;;&lt;br /&gt;
		var CB2 = &#039;#answer11111X22X33B&#039;;&lt;br /&gt;
		var CB3 = &#039;#answer11111X22X33C&#039;;&lt;br /&gt;
		var CB4 = &#039;#answer11111X22X33D&#039;;&lt;br /&gt;
		var CB5 = &#039;#answer11111X22X33E&#039;;&lt;br /&gt;
		var CB6 = &#039;#answer11111X22X33F&#039;;&lt;br /&gt;
		&lt;br /&gt;
		//// Create an array of all checkboxes to be randomized&lt;br /&gt;
		//// EDIT HERE (4) - add or remove CBs as required&lt;br /&gt;
		checkBoxes = new Array( CB1, CB2, CB3, CB4, CB5, CB6 );&lt;br /&gt;
		var checkBoxesLength = checkBoxes.length;&lt;br /&gt;
		&lt;br /&gt;
		//// The randomizing function - no editing required&lt;br /&gt;
		function randomResponse () {&lt;br /&gt;
			var boxLabels = new Array();&lt;br /&gt;
			&lt;br /&gt;
			// loop through all of the checkboxes and if they are checked, &lt;br /&gt;
			// add their label to the boxLabels array&lt;br /&gt;
			for( var i=0; i&amp;lt;checkBoxesLength; i++ ) {&lt;br /&gt;
				if ( $(checkBoxes[i]).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
					var cbid = checkBoxes[i].replace(&#039;#&#039;,&#039;&#039;);&lt;br /&gt;
					boxLabels.push( $( &#039;label[for=&#039; + cbid + &#039;]&#039; ).html() );&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// find a random index of the responses array&lt;br /&gt;
			var randomNum = Math.floor(Math.random() * boxLabels.length); &lt;br /&gt;
			&lt;br /&gt;
			// populate the hidden question input with the &lt;br /&gt;
			// random input value&lt;br /&gt;
			$(hiddenInput).val( boxLabels[randomNum] ); &lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		//// The listeners that will fire the randomize function if a &lt;br /&gt;
		//// change occurs in the checkboxes&lt;br /&gt;
		//// EDIT HERE (5) - add or remove CBs as required&lt;br /&gt;
		$(CB1).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB2).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB3).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB4).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB5).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB6).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});	&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Display secondary options in a &amp;quot;Multiple options&amp;quot; question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to display secondary options in a &amp;quot;Multiple options&amp;quot; question if a primary option is checked as in the images below.&lt;br /&gt;
&lt;br /&gt;
Primary option not selected:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Secondary_options_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Primary option selected:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Secondary_options_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=11491&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
We&#039;ve put a listener on the primary answer (&amp;quot;Option 1&amp;quot; in the demo) that shows or hides the secondary answers depending on the state of the primary.&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
#[http://docs.limesurvey.org/tiki-index.php?page=Workarounds%3A+Manipulating+a+survey+at+runtime+using+Javascript&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._in_LimeSurvey_ Set up your survey to use JavaScript].&lt;br /&gt;
#Create a &amp;quot;Multiple options&amp;quot; question including both the primary and secondary answers (in the order that you would like them displayed if all shown)&lt;br /&gt;
#Add the following script to the source of the question.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		&lt;br /&gt;
		/**** &lt;br /&gt;
		The following code puts a listener on an answer in a multiple options&lt;br /&gt;
		question (the primary answer) and if that answer is checked, a secondary &lt;br /&gt;
		level of answers is displayed.&lt;br /&gt;
		****/&lt;br /&gt;
		&lt;br /&gt;
		// --- 1 --- Indent the secondary answers a bit&lt;br /&gt;
		$( &#039;#questionQQ li:eq(1)&#039; ).css({ &#039;margin-left&#039;:&#039;2.5em&#039; });&lt;br /&gt;
		$( &#039;#questionQQ li:eq(2)&#039; ).css({ &#039;margin-left&#039;:&#039;2.5em&#039; });&lt;br /&gt;
		&lt;br /&gt;
		// --- 2 --- When the page loads, see if the primary answer is checked and if not, &lt;br /&gt;
                //hide and un-check all secondary answers&lt;br /&gt;
		if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
			&lt;br /&gt;
			$( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
			$( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
			&lt;br /&gt;
			$( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
			$( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// --- 3 --- Now put a listener on the primary answer to show or hide secondary answers &lt;br /&gt;
		// We need to use .click instead of .change cause IE won&#039;t cooperate&lt;br /&gt;
		$(&#039;#answerSSSSSXGGXQQAA&#039;).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Have a look at the primary answer and hide/show the secondary answers accordingly&lt;br /&gt;
			if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
			&lt;br /&gt;
				$( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
				$( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
				&lt;br /&gt;
				$( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
				$( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				&lt;br /&gt;
				$( &#039;#questionQQ li:eq(1)&#039; ).show();&lt;br /&gt;
				$( &#039;#questionQQ li:eq(2)&#039; ).show();&lt;br /&gt;
			} &lt;br /&gt;
			&lt;br /&gt;
			// The original functions of the click event&lt;br /&gt;
			cancelBubbleThis(event);&lt;br /&gt;
			checkconditions(this.value, this.name, this.type);&lt;br /&gt;
		  }&lt;br /&gt;
		);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 1:&#039;&#039;&#039;&lt;br /&gt;
*This section indents the secondary answers to give the look of a list in a list when they&#039;re shown&lt;br /&gt;
*&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID&lt;br /&gt;
*&#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; are the index positions of your secondary options. Modify or add as necessary for the number and placement of secondary options in your question. Note that the index starts at 0 so &#039;&#039;&#039;eq(1)&#039;&#039;&#039; actually affects the second option in the full list and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; affects the third. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 2:&#039;&#039;&#039;&lt;br /&gt;
*This section checks the state of the primary question when the page is loaded and if necessary hides the secondary questions. We need this in case users navigate away from and then back to the page.&lt;br /&gt;
*Modify &#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; as above.&lt;br /&gt;
*&#039;&#039;&#039;SSSSS&#039;&#039;&#039; is your survey ID.&lt;br /&gt;
*&#039;&#039;&#039;GG&#039;&#039;&#039; is your group ID.&lt;br /&gt;
*&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID.&lt;br /&gt;
*&#039;&#039;&#039;AA&#039;&#039;&#039; is your primary answer code.&lt;br /&gt;
*&#039;&#039;&#039;BB&#039;&#039;&#039; and &#039;&#039;&#039;CC&#039;&#039;&#039; are your secondary answer codes (add as necessary). &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 3:&#039;&#039;&#039;&lt;br /&gt;
*This is the section that &amp;quot;listens&amp;quot; to the primary answer and reacts accordingly.&lt;br /&gt;
*Edit as in section 2.&lt;br /&gt;
&lt;br /&gt;
For more info on these IDs see SGQA identifier(external link).&lt;br /&gt;
&lt;br /&gt;
This code could be tidied up and shortened a bit but I left it this way to make it easier to follow.&lt;br /&gt;
&lt;br /&gt;
=Minimum number of required answers in an array (pre 1.92)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92 all array style questions have the min_answers and max_answers options, so this script is obsolete.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to specify a &#039;&#039;&#039;minimum number&#039;&#039;&#039; of answers required in an array question. It is an alternative to the &amp;quot;Mandatory&amp;quot; parameter which specifies that &#039;&#039;&#039;all&#039;&#039;&#039; answers are required. It could also be easily modified to specify a maximum number of answers.&lt;br /&gt;
&lt;br /&gt;
We accomplish this by placing an onload function in the source of the array question. This function hides the Next/Submit button and displays a warning element until it detects a minimum number of responses. It then hides the warning and shows the Next/Submit button.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=97166&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Set up the template to use custom onload functions. (See the [[Workarounds#Custom onload function|workaround here]])&lt;br /&gt;
#In the source of the array question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Modify the &#039;&#039;SETTINGS&#039;&#039; section of the code as required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	// Wait until the document is fully loaded&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
	&lt;br /&gt;
		/********************** SETTINGS **********************/&lt;br /&gt;
		// The text to appear in the warning element&lt;br /&gt;
		var warningText = &#039;Please answer at least 4 to continue&#039;;&lt;br /&gt;
		// The question ID&lt;br /&gt;
		var questionId = 137;&lt;br /&gt;
		// The minimum number of answers required&lt;br /&gt;
		var minNumber = 4;&lt;br /&gt;
		/******************************************************/&lt;br /&gt;
		&lt;br /&gt;
		// Create the warning element and place it after the submit button&lt;br /&gt;
		var el = document.createElement(&#039;div&#039;);&lt;br /&gt;
		el.setAttribute(&#039;id&#039;,&#039;warning&#039;);&lt;br /&gt;
		document.body.appendChild(el);&lt;br /&gt;
		$( &#039;#warning&#039; ).css({&lt;br /&gt;
			&#039;border&#039;:&#039;1px solid #333333&#039;,&lt;br /&gt;
			&#039;width&#039;:&#039;200px&#039;,&lt;br /&gt;
			&#039;padding&#039;:&#039;3px&#039;,&lt;br /&gt;
			&#039;color&#039;:&#039;red&#039;&lt;br /&gt;
		});&lt;br /&gt;
		$(&#039;#warning&#039;).html(warningText);&lt;br /&gt;
		$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).after($(&#039;#warning&#039;));&lt;br /&gt;
		&lt;br /&gt;
		// Detect the initial number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
		var inputInitCount = 0;&lt;br /&gt;
		$(&#039;#question&#039; + questionId + &#039; input&#039;).each(function(i) {&lt;br /&gt;
			if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
				inputInitCount++;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		if (inputInitCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
			$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
			$(&#039;#warning&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#warning&#039;).show();&lt;br /&gt;
			$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Listener to detect number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
		$(&#039;#question&#039; + questionId + &#039; input.radio, #question&#039;+questionId+&#039; tbody[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;javatbd&amp;quot;] td&#039;).click(function() {&lt;br /&gt;
			var inputCount = 0;&lt;br /&gt;
			$(&#039;#question&#039; + questionId + &#039; input.radio&#039;).each(function(i) {&lt;br /&gt;
				if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
					inputCount++;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
			if (inputCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
				$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
				$(&#039;#warning&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;#warning&#039;).show();&lt;br /&gt;
				$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// The original functions of the click event&lt;br /&gt;
			checkconditions(this.value, this.name, this.type);&lt;br /&gt;
		});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Minimum elapsed time before moving forward in survey=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, Firefox 7.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround interrupts the Next/Submit function and checks the amount of time elapsed since the page loaded. If the time is less than the minimum dictated, the respondent is alerted and not allowed to proceed. It is useful if you want to enforce a minimum amount of time spent viewing a page.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the script below in the source of one of the questions on the page, replacing &amp;quot;TT&amp;quot; with the minimum number of seconds required before advancing is allowed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		minTime(TT);&lt;br /&gt;
&lt;br /&gt;
		function minTime(minTime) {&lt;br /&gt;
&lt;br /&gt;
			var startTime = new Date();&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
				var endTime = new Date();&lt;br /&gt;
&lt;br /&gt;
				if((endTime - startTime)/1000 &amp;lt;= minTime) {&lt;br /&gt;
					alert (&#039;You must spend at least &#039;+minTime+&#039; seconds on the question.&#039;);&lt;br /&gt;
					return false;&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					return true;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Minimum number of characters in Long free text or Huge free text questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, Firefox 7.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.91, you can use regular expression masks (validation) to specify the minimum number of required characters.  However, even if the question is mandatory, it can still be blank.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version  1.92, if you make the question mandatory and use a validation mask to specify the minimum number of characters, then the user will be forced to answer the question.  Note that unlike 1.91, they can submit their current answers, even if partially invalid (so they are stored in the database), but they will not ber able to proceed to the next page until they have passed all mandatory and validity checks.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround interrupts the Next/Submit function and checks the number of characters entered in a Long free text or Huge free text question. If the number is less than the minimum dictated, the respondent is alerted and not allowed to proceed.&lt;br /&gt;
&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
&lt;br /&gt;
#Place the script below in the source of one of the questions on the page, replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;CC&amp;quot; with the minimum number of characters required before advancing is allowed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       minChar(QQ, CC);&lt;br /&gt;
&lt;br /&gt;
       function minChar(qID, minChars) {&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               if($(&#039;#question&#039;+qID+&#039; textarea&#039;).val().replace(/ /g,&#039;&#039;).length &amp;lt; minChars) {&lt;br /&gt;
&lt;br /&gt;
                   alert (&#039;You must enter at least &#039;+minChars+&#039; characters.&#039;);&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Variable Length Array (Multi Flexible Text) question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows a respondent to add or remove rows of an Array (Multi Flexible Text) question. It&#039;s useful to avoid the page being cluttered with unnecessary array rows.&lt;br /&gt;
&lt;br /&gt;
A function is placed in the template.js file of your template (use template editor). This function hides all of the array rows except the first and inserts two elements that when clicked show or hide rows accordingly.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=53132&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
It must be noted that you can not make this question Mandatory as the respondent will have no way to complete hidden fields. If you want the displayed fields to be mandatory you will need to validate them in another function or modify this function to only allow the addition of rows if all fields in the last row are completed and then disable those fields - that, however, is a little over the top for this example.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
#Set up your survey to use JavaScript (See instructions [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|here]])&lt;br /&gt;
&lt;br /&gt;
#Add the following script to your &#039;&#039;template.js&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end with the question ID.&lt;br /&gt;
&lt;br /&gt;
#Create one or more Array (Multi Flexible Text) questions&lt;br /&gt;
&lt;br /&gt;
#If you want to apply it to more arrays on the same page simply add more calls with the appropriate question IDs. (eg. varLengthArray(1); varLengthArray(2);...)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // A function to add or remove rows of an Array (Multi Flexible)(Text) question&lt;br /&gt;
	function varLengthArray(qID) {&lt;br /&gt;
&lt;br /&gt;
		if ($(&#039;#question&#039;+qID+&#039;&#039;).length &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
			// The HTML content of the Add/Remove elements - modify as you wish&lt;br /&gt;
			var addContent = &#039;[+]&#039;;&lt;br /&gt;
			var removeContent = &#039;[-]&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Create the Add and Remove elements &amp;amp; insert them&lt;br /&gt;
			var el1 = document.createElement(&#039;div&#039;);&lt;br /&gt;
			el1.setAttribute(&#039;id&#039;,&#039;addButton&#039;+qID);&lt;br /&gt;
			document.body.appendChild(el1);&lt;br /&gt;
			var el2 = document.createElement(&#039;div&#039;);&lt;br /&gt;
			el2.setAttribute(&#039;id&#039;,&#039;removeButton&#039;+qID);&lt;br /&gt;
			document.body.appendChild(el2);&lt;br /&gt;
&lt;br /&gt;
			// Move them to after the array&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).appendTo($( &#039;#question&#039; + qID + &#039; table.question&#039; ).parent());&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).appendTo($( &#039;#question&#039; + qID + &#039; table.question&#039; ).parent());&lt;br /&gt;
&lt;br /&gt;
			// Insert their HTML&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).html( addContent );&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).html( removeContent );&lt;br /&gt;
&lt;br /&gt;
			// Style the elements - you can modify here if you wish&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).css({&lt;br /&gt;
				&#039;margin&#039;:&#039;10px 0 0 10px&#039;,&lt;br /&gt;
				&#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
				&#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
				&#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
				&#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
				&#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
				&#039;float&#039;:&#039;left&#039;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).css({&lt;br /&gt;
				&#039;margin&#039;:&#039;10px 0 0 10px&#039;,&lt;br /&gt;
				&#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
				&#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
				&#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
				&#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
				&#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
				&#039;float&#039;:&#039;left&#039;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Initially hide the Remove element&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).hide();&lt;br /&gt;
&lt;br /&gt;
			// Call the functions below when clicked&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).click(function (event) {&lt;br /&gt;
				addRow(qID);&lt;br /&gt;
			});&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).click(function (event) {&lt;br /&gt;
				removeRow(qID);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Function to add a row, also shows the Remove element and hides the&lt;br /&gt;
			//Add element if all rows are shown&lt;br /&gt;
			function addRow(qID) {&lt;br /&gt;
				var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
				var rowCount = $( arrayRow ).size() - 1;&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
				$( &#039;div#removeButton&#039;+qID ).show();&lt;br /&gt;
				if ( $( arrayRow + &#039;:eq(&#039; + rowCount + &#039;)&#039; ).attr(&#039;name&#039;) == &#039;visible&#039; )  {&lt;br /&gt;
					$( &#039;div#addButton&#039;+qID ).hide();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Function to remove a row, also clears the contents of the removed row,&lt;br /&gt;
			// shows the Add element if the last row is hidden and hides the Remove&lt;br /&gt;
			// element if only the first row is shown&lt;br /&gt;
			function removeRow(qID) {&lt;br /&gt;
				var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
				var rowCount = $( arrayRow ).size() - 1;&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last input[type=&amp;quot;text&amp;quot;]&#039; ).val(&#039;&#039;);&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last&#039; ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
				$( &#039;div#addButton&#039;+qID ).show();&lt;br /&gt;
				if ( $( arrayRow + &#039;:eq(1)&#039; ).attr(&#039;name&#039;) == &#039;hidden&#039; )  {&lt;br /&gt;
					$( &#039;div#removeButton&#039;+qID ).hide();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Just some initialization stuff&lt;br /&gt;
			var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
			var rowCount = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Initially hide all except first row or any rows with populated inputs&lt;br /&gt;
			$( arrayRow ).each(function(i) {&lt;br /&gt;
				if ( i &amp;gt; 0 ) {&lt;br /&gt;
					// We also need to give the hidden rows a name cause IE doesn&#039;t&lt;br /&gt;
					// recognize jQuery :visible selector consistently&lt;br /&gt;
					$( this ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
					$(&#039;input[type=text]&#039;, this).each(function(i) {&lt;br /&gt;
						if ($(this).attr(&#039;value&#039;) != &#039;&#039;) {&lt;br /&gt;
							$(this).parents(&#039;tbody:eq(0)&#039;).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
							$( &#039;div#removeButton&#039;+qID ).show();&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
					rowCount = i;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Call the function with a question ID&lt;br /&gt;
	varLengthArray(QQ);&lt;br /&gt;
&lt;br /&gt;
});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expandable Array=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to present an array question incrementally. That is to say that initially only the first option (row) in the array is shown. When that option is answered the next is shown and so-on.&lt;br /&gt;
&lt;br /&gt;
A JavaScript function is placed in the source of the array question. This function hides all of the array rows except the first and then displays them as options are answered.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=94958&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
The workaround supports following question types:&lt;br /&gt;
*Array (flexible labels)&lt;br /&gt;
*Array (flexible labels) by column&lt;br /&gt;
*Array (Yes/No/Uncertain)&lt;br /&gt;
*Array (Increase, Same, Decrease)&lt;br /&gt;
*Array (Flexible Labels) dual scale&lt;br /&gt;
*Array (10 point choice)&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Set up your survey to use JavaScript. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|documentation here]])&lt;br /&gt;
#Create one or more Array questions&lt;br /&gt;
#In the source of the first array question add the following script.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end of the script with the question ID of the array you would like to manipulate.&lt;br /&gt;
#If you want to apply it to more arrays on the same page, simply add more calls with the appropriate question IDs. (eg. expandingArray(1); expandingArray(2);...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// A function to show subsequent rows of an array as options are checked&lt;br /&gt;
		function expandingArray(qID) {&lt;br /&gt;
&lt;br /&gt;
			// Build an array of the question rows&lt;br /&gt;
			var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody tr&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Initially hide all rows unless an input was previously checked&lt;br /&gt;
			$( arrayRow ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
				if ( $( arrayRow  + &#039;:eq(&#039; + i + &#039;) input.radio:checked&#039; ).length != 0 ) {&lt;br /&gt;
					$(this).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					$(this).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Now show the first hidden row&lt;br /&gt;
			addRow();&lt;br /&gt;
&lt;br /&gt;
			// Add another row when an option is checked for the first time&lt;br /&gt;
			$( &#039;#question&#039; + qID + &#039; td.answer input.radio&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
				if ($(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;) != &#039;clickedRow&#039;) {&lt;br /&gt;
					addRow();&lt;br /&gt;
					$(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				// The original function of the click event&lt;br /&gt;
				checkconditions(this.value, this.name, this.type);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Add another row when an table cell is clicked for the first time&lt;br /&gt;
			$( &#039;#question&#039; + qID + &#039; table.question tbody td&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
				if ($(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;) != &#039;clickedRow&#039;) {&lt;br /&gt;
					addRow();&lt;br /&gt;
					$(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Function to add a row&lt;br /&gt;
			function addRow() {&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with a question ID&lt;br /&gt;
		expandingArray(QQ);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions - ENHANCED=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping as many answers at the end of the list as specified by the var insertitems=n, where n is the number of answers you want left unrandomized. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the 5th to 7th displayed last as in the image below (assuming you assigned the number 3 to insertitems):&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [[Optional settings#Survey Behavior|$shownoanswer option]] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Set var insertitems=n (n = the number of items you want un-randomized)&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
Onload code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Function to allow randomization of all answers except the last one in Multiple options and List/radio questions&lt;br /&gt;
&lt;br /&gt;
       function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
           //var to define how many lists to be added at the end&lt;br /&gt;
&lt;br /&gt;
           var insertitems=3;&lt;br /&gt;
&lt;br /&gt;
           // Find the number of answers&lt;br /&gt;
&lt;br /&gt;
           var ansCount = &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
           lastitems=new Array();&lt;br /&gt;
&lt;br /&gt;
           var liid=new Array();&lt;br /&gt;
&lt;br /&gt;
           var $ul;&lt;br /&gt;
&lt;br /&gt;
           var j=0;&lt;br /&gt;
&lt;br /&gt;
           $( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                           ansCount = (i + 1);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                           if(i&amp;gt;ansCount-(insertitems+1)){&lt;br /&gt;
&lt;br /&gt;
                             lastitems[j]=$(this).html();&lt;br /&gt;
&lt;br /&gt;
                             liid[j]=$(this).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                             j++;&lt;br /&gt;
&lt;br /&gt;
                             $(this).remove();&lt;br /&gt;
&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
// get current ul&lt;br /&gt;
&lt;br /&gt;
$ul = $(this).parent();&lt;br /&gt;
&lt;br /&gt;
// get array of list items in current ul&lt;br /&gt;
&lt;br /&gt;
var $liArr = $ul.children(&#039;li&#039;);&lt;br /&gt;
&lt;br /&gt;
// sort array of list items in current ul randomly&lt;br /&gt;
&lt;br /&gt;
$liArr.sort(function(a,b){&lt;br /&gt;
&lt;br /&gt;
// Get a random number between 0 and 100&lt;br /&gt;
&lt;br /&gt;
var temp = parseInt( Math.random()*100 );&lt;br /&gt;
&lt;br /&gt;
// Get 1 or 0, whether temp is odd or even&lt;br /&gt;
&lt;br /&gt;
var isOddOrEven = temp%2;&lt;br /&gt;
&lt;br /&gt;
// Get +1 or -1, whether temp greater or smaller than 5&lt;br /&gt;
&lt;br /&gt;
var isPosOrNeg = temp&amp;gt;5 ? 1 : -1;&lt;br /&gt;
&lt;br /&gt;
// Return -1, 0, or +1&lt;br /&gt;
&lt;br /&gt;
return( isOddOrEven*isPosOrNeg );&lt;br /&gt;
&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
// append list items to ul&lt;br /&gt;
&lt;br /&gt;
.appendTo($ul);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$.each(lastitems,function(i){&lt;br /&gt;
&lt;br /&gt;
$( $ul ).append(&amp;quot;&amp;lt;li id=&amp;quot;+liid[i]+&amp;quot;&amp;gt;&amp;quot;+this+&amp;quot;&amp;lt;/li&amp;gt;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Call the function with the SID, GID and QID&lt;br /&gt;
&lt;br /&gt;
       partRand(SSSSS, GG, QQ);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last as in the image below:&lt;br /&gt;
&lt;br /&gt;
[[File:random_336x179gif.gif]]&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [[Optional settings#Survey Behavior|$shownoanswer option]] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [[Advanced question settings#random_order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers except the last one in Multiple options and List/radio questions&lt;br /&gt;
		function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = (i + 1);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list&lt;br /&gt;
			$( &#039;input#answer&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).parent().appendTo($( &#039;#question&#039; + qID + &#039; td.answer ul&#039; ));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
			partRand(SSSSS, GG, QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - List (dropdown) questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the one above, allows the answers of List (dropdown) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more List (dropdown) questions with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers&lt;br /&gt;
		//except the last one in List/dropdown questions&lt;br /&gt;
		function partRandDD(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; select option&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = i;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list&lt;br /&gt;
			$( &#039;option[value=&amp;quot;&#039; + ansCount + &#039;&amp;quot;]&#039; ).appendTo($( &#039;div#question&#039; + qID + &#039; select&#039; ));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
		partRandDD(89344, 72, 244);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple numerical input=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, Safari 5.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the ones above, allows the answers of Multiple numerical input questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple numerical input question with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers except the last one in multiple numeric input questions&lt;br /&gt;
		function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; div.answers li&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = (i - 1);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list - but before the first helping sum&lt;br /&gt;
			$( &#039;li#javatbd&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).insertBefore($( &#039;div#question&#039; + qID + &#039; div.answers li.multiplenumerichelp&#039; ).first());&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
		partRand(SID, GID, QID);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using this solution for Multiple numerical input questions might be a bit more complicated than for other question types. All answers are organized in an unordered list (&amp;lt;nowiki&amp;gt;&amp;lt;ul&amp;gt;&amp;lt;/nowiki&amp;gt;) structure. However, if advanced question settings like &#039;&#039;Equals sum value&#039;&#039; are used, LimeSurvey adds helping information (e.g. sum of all entries and remainder) to the same unordered list using the class &#039;&#039;multiplenumerichelp&#039;&#039; for these additional list items. The above example  assumes that at least one of these list items is present and moves the last answer to the position right above the first helper item. Without such advanced settings, the code will most certainly need adaptation.&lt;br /&gt;
&lt;br /&gt;
=Making one (or more) rows of an array mandatory=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, Firefox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to define one or more rows of an array question as mandatory (instead of all of them which the &amp;quot;Mandatory&amp;quot; question setting does). It is [http://www.partnersinc.biz/surveys//index.php?sid=26842&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
A JavaScript function interrupts the submit function and checks if the inputs in the mandatory row(s) are populated. If not, an alert is popped up, the offending inputs are turned pink and the submit is aborted. Otherwise the submit goes ahead.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions (see [[Optional settings#Security|documentation here]]).&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following script (see [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]]).&lt;br /&gt;
#Modify the warningText (line10)as required.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; (lines 13 and 14)  with the question ID and add calls as necessary for more rows - the example code renders rows 1 and 3 mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function () {&lt;br /&gt;
&lt;br /&gt;
		// Interrupt the submit function&lt;br /&gt;
		$(&#039;form#limesurvey&#039;).submit(function () {&lt;br /&gt;
&lt;br /&gt;
			// Override the built-in &amp;quot;disable navigation buttons&amp;quot; feature&lt;br /&gt;
			$(&#039;#moveprevbtn, #movenextbtn, #movesubmitbtn&#039;).attr(&#039;disabled&#039;, &#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
			var empty = 0;&lt;br /&gt;
			var warningText = &#039;Please complete the highlighted inputs.&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Call the mandatory row function with question IDs and row numbers&lt;br /&gt;
			mandatoryRow(QQ, 1);&lt;br /&gt;
			mandatoryRow(QQ, 3);&lt;br /&gt;
&lt;br /&gt;
			// A function to render rows of an array mandatory&lt;br /&gt;
			function mandatoryRow(qID, rowNum) {&lt;br /&gt;
&lt;br /&gt;
				$(&#039;div#question&#039; + qID + &#039; table.question tbody[id&amp;lt;/div&amp;gt;=&amp;quot;javatbd&amp;quot;]:eq(&#039; + Number(rowNum - 1) + &#039;) input[type=&amp;quot;text&amp;quot;]&#039;).each(function (i) {&lt;br /&gt;
&lt;br /&gt;
					if ($(this).val() == &#039;&#039;) {&lt;br /&gt;
						$(this).css(&#039;background-color&#039;, &#039;pink&#039;);&lt;br /&gt;
						empty = 1;&lt;br /&gt;
					} &lt;br /&gt;
					else {&lt;br /&gt;
						$(this).css(&#039;background-color&#039;, &#039;#FFFFFF&#039;);&lt;br /&gt;
					}&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (empty == 1) {&lt;br /&gt;
				alert(warningText);&lt;br /&gt;
				return false;&lt;br /&gt;
			} &lt;br /&gt;
			else {&lt;br /&gt;
				return true;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Randomly displaying one of a few YouTube videos, and recording which was displayed=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland has created and documented a method to randomly display one of a number of youtube videos in a single question, and save which one was displayed.&lt;br /&gt;
&lt;br /&gt;
http://www.aptigence.com.au/home/archives/23-Random-display-of-videos-in-a-question-2-YouTube.html&lt;br /&gt;
&lt;br /&gt;
=Randomly displaying one of a few pictures, and recording which was displayed=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.91+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The following steps allow you to randomly display one of a few pictures and record in the dataset which picture was displayed. We use four pictures in this example, but you can easily adapt these scripts according to your needs.&lt;br /&gt;
&lt;br /&gt;
1. Create a new sub-directory &#039;&#039;&#039;pic&#039;&#039;&#039; in your LimeSurvey folder.&lt;br /&gt;
&lt;br /&gt;
2. Copy four pictures (named &#039;&#039;1.jpg&#039;&#039;, &#039;&#039;2.jpg&#039;&#039;, &#039;&#039;3.jpg&#039;&#039;, and &#039;&#039;4.jpg&#039;&#039;) in this pic sub-directory.&lt;br /&gt;
&lt;br /&gt;
3. Deactivate the &#039;&#039;Filter HTML for XSS&#039;&#039; function in LimeSurvey&#039;s &#039;&#039;Global Settings&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
4. Create a &#039;&#039;&#039;Short free text&#039;&#039;&#039; question where you want these pictures to be displayed.&lt;br /&gt;
&lt;br /&gt;
5. Figure out the [[SGQA identifier|SGQA Identifier]] of this question (e.g., 12345X67X89).&lt;br /&gt;
&lt;br /&gt;
6. Paste the following code as question text after activating the editor&#039;s &#039;&#039;Source&#039;&#039; view and replace both SSSSSXGGXQQ strings with your SGQA identifier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please have a look at this picture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(&lt;br /&gt;
&lt;br /&gt;
function(){&lt;br /&gt;
&lt;br /&gt;
// Find a random number (here between 1 and 4)&lt;br /&gt;
&lt;br /&gt;
var randNumber = Math.floor(Math.random()*4 + 1);&lt;br /&gt;
&lt;br /&gt;
// Save the number as answer of this question&lt;br /&gt;
&lt;br /&gt;
$(&#039;input#answerSSSSSXGGXQQ&#039;).val(randNumber);&lt;br /&gt;
&lt;br /&gt;
// Hide this answer field&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&amp;quot;answerSSSSSXGGXQQ&amp;quot;).style.display=&#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
// Show the picture&lt;br /&gt;
&lt;br /&gt;
picString = &#039;&amp;lt;img src=&amp;quot;pic/&#039; + String(randNumber) + &#039;.jpg&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;pic&#039;).innerHTML = picString;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
);&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;pic&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to display the number of this picture in a later question, use the following code as question text (don&#039;t forget to replace the SSSSSXGGXQQ string acordingly):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You saw picture number {INSERTANS:SSSSSXGGXQQ}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perhaps you want to display the same picture again in a later question, but a little bit smaller (100px width, 100px height)? Just paste the following code as question text after activating the editor&#039;s &#039;&#039;Source&#039;&#039; view, and replace the SSSSSXGGXQQ string acordingly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here you see the picture again: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(&lt;br /&gt;
&lt;br /&gt;
function(){&lt;br /&gt;
&lt;br /&gt;
// Get the picture number from previous question&lt;br /&gt;
&lt;br /&gt;
var randNumber = &amp;quot;{INSERTANS:SSSSSXGGXQQ}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Show picture&lt;br /&gt;
&lt;br /&gt;
picString = &#039;&amp;lt;img width=&amp;quot;100&amp;quot; height=&amp;quot;100&amp;quot; src=&amp;quot;pic/&#039; + String(randNumber) + &#039;.jpg&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;pic&#039;).innerHTML = picString;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
);&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;pic&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple numerical input with max_num_value defined in token (personalized limit)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, max_num_value can be an experession, so you can simply enter the {TOKEN} or other variable in that question attribute.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make personalized survey with multiple numerical input when max_num_value (Maximum sum value) is different for each user and is loaded from the token use following tricks:&lt;br /&gt;
*Create 1st group with numerical input field (1000X10X11). &amp;quot;Limit&amp;quot;&lt;br /&gt;
*Add java script into this question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&#039;answer1000X10X11&#039;).value=&#039;{TOKEN:ATTRIBUTE_1}&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&#039;answer1000X10X11&#039;).readOnly=1;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
TOKEN:ATTRIBUTE_1 is individual limit defined in token.&lt;br /&gt;
&lt;br /&gt;
readOnly=1 // user shouldn&#039;t change it.&lt;br /&gt;
*Create 2nd group with multiple numerical input and add &amp;quot;Max value from SGQA&amp;quot; with 1000X10X11 as argument.&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t want to show first field with numerical input (and show definied limit in different way) you can add 2 lines to above script to hide whole question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;question85&#039;).style.display=&#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;display85&#039;).value=&#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
question85 and display85 are field names.&lt;br /&gt;
&lt;br /&gt;
Note: It&#039;s no possible to create it into one group, because all SGQA references can only refer to data on a previous page because when clicking next the answer is stored at the DB and the SGQA is replaced by querying the database.&lt;br /&gt;
&lt;br /&gt;
=Default values in array questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.87+ (7557), IE 6/7, Firefox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of Version 1.92, many more question types support default values.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to allow you to pre-check default answers in all sub-questions of an array type question. You can select a column of the array to be checked as the page loads. The script first checks to see if a sub-question has already been answered and, if not, checks the default answer.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use script]].&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following script.&lt;br /&gt;
#Replace&amp;quot;QQ&amp;quot; with the question ID and &amp;quot;CC&amp;quot; with the column number to be checked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // A function to pre-check a column of an array&lt;br /&gt;
&lt;br /&gt;
       function checkedDefault(qID, column) {&lt;br /&gt;
&lt;br /&gt;
           var checkedCol = column - 1;&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039; + qID + &#039; table.question tbody tr&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
               if ($(&#039;input.radio[checked=true]&#039;, this).length == 0) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;input.radio:eq(&#039; + checkedCol + &#039;)&#039;, this).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       // Call the function with a question ID and column number&lt;br /&gt;
&lt;br /&gt;
       checkedDefault(QQ, CC);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Record group view time=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.87+ (8518), IE 6/7, Firefox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, group view time is accurately recorded in the timings table if you choose the Record Timings survey option.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to populate a hidden question with the total time that a respondent views a group. If used in a group with only one question, it could be used to track the amount of time required to answer the question.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#In the group, create a short-text question. We will hide this later with JavaScript and populate it with the elapsed time.&lt;br /&gt;
#Place the following script in the source of the short-text question.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in line 6 with the ID of the short-text question.&lt;br /&gt;
&lt;br /&gt;
The script populates the hidden question with the elapsed time since the group was opened. If a respondent leaves the group and then returns, the timer continues up from the elapsed time of the last visit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
       // call the functions with the hidden timer question ID&lt;br /&gt;
&lt;br /&gt;
       runTimer(QQ);&lt;br /&gt;
&lt;br /&gt;
       function runTimer(timeQID) {&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+timeQID).hide();&lt;br /&gt;
&lt;br /&gt;
           var initSec = &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
           // Check for elapsed time from previous visits&lt;br /&gt;
&lt;br /&gt;
           if ($(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val()) {&lt;br /&gt;
&lt;br /&gt;
               var initTime = $(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               initTimeArr = initTime.split(&#039;:&#039;);&lt;br /&gt;
&lt;br /&gt;
               initSec = Number[[initTimeArr[0]*3600]]+Number[[initTimeArr[1]*60]]+Number(initTimeArr[2]);&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Run the timer update function&lt;br /&gt;
&lt;br /&gt;
           recordTime(initSec, timeQID);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Timer update function&lt;br /&gt;
&lt;br /&gt;
   function recordTime(elapsedSec, timeQID){&lt;br /&gt;
&lt;br /&gt;
       elapsedSec++;&lt;br /&gt;
&lt;br /&gt;
       var h = Math.floor(elapsedSec / 3600);&lt;br /&gt;
&lt;br /&gt;
       var m = Math.floor(elapsedSec % 3600 / 60);&lt;br /&gt;
&lt;br /&gt;
       var s = Math.floor(elapsedSec % 3600 % 60);&lt;br /&gt;
&lt;br /&gt;
       var elapsedTime = [[h &amp;gt; 0 ? h + &amp;quot;:&amp;quot; : &amp;quot;00:&amp;quot;) + (m &amp;gt; 0 ? (m &amp;lt; 10 ? &amp;quot;0&amp;quot; : &amp;quot;&amp;quot;) + m + &amp;quot;:&amp;quot; : &amp;quot;00:&amp;quot;) + (s &amp;lt; 10 ? &amp;quot;0&amp;quot; : &amp;quot;&amp;quot;) + s);&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val(elapsedTime);&lt;br /&gt;
&lt;br /&gt;
        // Run the timer update function every second&lt;br /&gt;
&lt;br /&gt;
        setTimeout(&#039;recordTime(&#039;+elapsedSec+&#039;, &#039;+timeQID+&#039;)&#039;,1000);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Toggle visibility of groups=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to toggle the visibility of groups in an &amp;quot;all in one&amp;quot; survey. Initially the groups are hidden and there are links inserted to display the groups. It&#039;s useful to avoid the page being cluttered with many groups and lets the respondent focus on one at a time.&lt;br /&gt;
&lt;br /&gt;
It&#039;s [http://www.partnersinc.biz/surveys//index.php?sid=33613&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Set the survey to run in &amp;quot;all in one&amp;quot; mode.&lt;br /&gt;
#Add your groups and questions.&lt;br /&gt;
#Place the following script in the source of one of the questions in the first group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The comments in the script are pretty self-explanatory but it does the following:&lt;br /&gt;
&lt;br /&gt;
#initially hides all of the groups&lt;br /&gt;
#inserts a link above each one to toggle its display&lt;br /&gt;
#some styles are added to the clickable links but these could be done in template.css instead&lt;br /&gt;
#shows any groups that have an unanswered mandatory after a submit attempt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
		// Insert show/hide divs before all group wrapper divs&lt;br /&gt;
		$(&#039;&amp;lt;div class=&amp;quot;groupToggler&amp;quot;&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;).insertBefore(&#039;div[id^=&amp;quot;group-&amp;quot;]&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Add some text to the show/hide divs&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).each(function(i) {&lt;br /&gt;
			($( this ).text(&#039;Show/Hide Group &#039;+(i+1)+&#039;&#039;));&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Add some styles to the show/hide divs&lt;br /&gt;
		$(&#039;.groupToggler&#039;).css({&lt;br /&gt;
			&#039;padding&#039;:&#039;5px 0 10px 0&#039;,&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).css({&lt;br /&gt;
			&#039;text-decoration&#039;:&#039;underline&#039;,			&lt;br /&gt;
			&#039;cursor&#039;:&#039;pointer&#039;&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Add some hover effects to the show/hide divs&lt;br /&gt;
		$(&amp;quot;.groupToggler span&amp;quot;).hover(&lt;br /&gt;
			function () {&lt;br /&gt;
				$(this).css({&lt;br /&gt;
					&#039;text-decoration&#039;:&#039;none&#039;,&lt;br /&gt;
					&#039;font-weight&#039;:&#039;bold&#039;&lt;br /&gt;
				});&lt;br /&gt;
			}, &lt;br /&gt;
			function () {&lt;br /&gt;
				$(this).css({&lt;br /&gt;
					&#039;text-decoration&#039;:&#039;underline&#039;,&lt;br /&gt;
					&#039;font-weight&#039;:&#039;normal&#039;&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
		);&lt;br /&gt;
		&lt;br /&gt;
		// Initially hide all of the groups&lt;br /&gt;
		// Toggle their visibility when the show/hide is clicked&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).click(function() {&lt;br /&gt;
			$(this).parent().next().toggle();&lt;br /&gt;
			return false;&lt;br /&gt;
		}).parent().next().hide();&lt;br /&gt;
		&lt;br /&gt;
		// Display any groups that have unanswered mandatories&lt;br /&gt;
		$(&#039;.errormandatory&#039;).parents(&#039;div[id^=&amp;quot;group-&amp;quot;]&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Some tidying up&lt;br /&gt;
		$(&#039;h1&#039;).next().next().hide();&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).css({&#039;margin-bottom&#039;:&#039;10px&#039;});&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).next().hide();&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).next().next().hide();&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use jQuery Autocomplete plugin to suggest answers for text inputs=&lt;br /&gt;
&lt;br /&gt;
== 1.90 and previous versions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://docs.jquery.com/Plugins/Autocomplete jQuery Autocomplete] plugin to provide a respondent a list of suggested answers that the they can select from as they type in a text input.&lt;br /&gt;
&lt;br /&gt;
Although the plugin allows for much more complex applications, the two that I use most frequently are outlined below. The first method uses a relatively small list of suggestions that is stored in an array locally. The second is a little more complex - it uses a remote CSV file of suggestions that is accessed through AJAX an PHP.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve put together a small demonstration [http://www.partnersinc.biz/surveys//index.php?sid=78611&amp;amp;newtest=Y&amp;amp;lang=en here] and implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Both methods:&#039;&#039;&#039;&lt;br /&gt;
*[http://docs.jquery.com/Plugins/Autocomplete Download the plugin]&lt;br /&gt;
*Place the files &#039;&#039;jquery.autocomplete.css&#039;&#039; and &#039;&#039;jquery.autocomplete.js&#039;&#039; in your template directory&lt;br /&gt;
*Add the following code inside the &amp;lt;head&amp;gt; element of startpage.pstpl&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autocomplete.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;{TEMPLATEURL}jquery.autocomplete.css&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 1 (&amp;quot;States&amp;quot; question in the demo):&#039;&#039;&#039;&lt;br /&gt;
*Create a text input question&lt;br /&gt;
*Add the following script to the source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace the states with your list of suggestions (comma separated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var q1ID = QQ;&lt;br /&gt;
&lt;br /&gt;
		var states = &amp;quot;Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware, District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky, Louisiana,Maine,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York, North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Maryland,Massachusetts,Michigan, Minnesota,Mississippi,Missouri,Pennsylvania,Rhode Island,South Carolina,South Dakota, Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming&amp;quot;.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.text&#039;).autocomplete(states, {&lt;br /&gt;
			matchContains: true,&lt;br /&gt;
			minChars: 0&lt;br /&gt;
		});&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 2 (&amp;quot;Countries&amp;quot; question in the demo):&#039;&#039;&#039;&lt;br /&gt;
*Place the CSV file of suggestions in your template directory. &lt;br /&gt;
*Place a PHP file containing the code below in your template directory&lt;br /&gt;
*Replace &amp;quot;countries2.csv&amp;quot; with your CSV filename (you could make this more universal by passing the filename in the URL)&lt;br /&gt;
*This file will grab the contents of the CSV and encode them in JSON format that the JavaScript can use&lt;br /&gt;
*Place the JavaScript code below in ths source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace &amp;quot;templates/yourTemplate/countries.php&amp;quot; with the path to the PHP file (from LimeSurvey root)&lt;br /&gt;
*This script will grab the jsonized data from the PHP file and load it into an array that the plugin can use&lt;br /&gt;
&lt;br /&gt;
PHP code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
	$countriesArr = array();&lt;br /&gt;
&lt;br /&gt;
	$file_handle = fopen(&amp;quot;countries2.csv&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	while (!feof($file_handle) ) {&lt;br /&gt;
		$line_of_text = fgetcsv($file_handle);&lt;br /&gt;
		array_push($countriesArr, $line_of_text[0]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose($file_handle);&lt;br /&gt;
&lt;br /&gt;
	echo json_encode($countriesArr);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qID = QQ;&lt;br /&gt;
		var url = &amp;quot;templates/yourTemplate/countries.php&amp;quot;;&lt;br /&gt;
		var countriesArr = new Array();&lt;br /&gt;
&lt;br /&gt;
		$.getJSON(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			$(data).each(function(i, item){&lt;br /&gt;
				countriesArr.push(item);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#question&#039;+qID+&#039; input.text&#039;).autocomplete(countriesArr, {&lt;br /&gt;
				matchContains: true,&lt;br /&gt;
				minChars: 0&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.91 and later versions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://jqueryui.com/demos/autocomplete/ Autocomplete widget] included with jQuery UI to provide a respondent a list of suggested answers that the they can select from as they type in a text input.&lt;br /&gt;
&lt;br /&gt;
Although the plugin allows for much more complex applications, the two that I use most frequently are outlined below. The first method uses a relatively small list of suggestions that is stored in an array locally. The second is a little more complex - it uses a remote CSV file of suggestions that is accessed through AJAX an PHP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Both methods:&#039;&#039;&#039;&lt;br /&gt;
*Add the following styles to the end of your &#039;template.css&#039; file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;/* Autocomplete styles */&lt;br /&gt;
&lt;br /&gt;
ul.ui-autocomplete {&lt;br /&gt;
	width: 250px !important;&lt;br /&gt;
	padding: 5px 10px;&lt;br /&gt;
	list-style: none;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 1 (use local JavaScript array for data):&#039;&#039;&#039;&lt;br /&gt;
*Create a text input question&lt;br /&gt;
*Add the following script to the source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace the states with your list of suggestions (comma separated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var q1ID = QQ;&lt;br /&gt;
&lt;br /&gt;
		var states = &amp;quot;Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware, District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky, Louisiana,Maine,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York, North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Maryland,Massachusetts,Michigan, Minnesota,Mississippi,Missouri,Pennsylvania,Rhode Island,South Carolina,South Dakota, Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming&amp;quot;.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
			source: states&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 2 (use remote CSV file for data):&#039;&#039;&#039;&lt;br /&gt;
*Place the CSV file of suggestions in your template directory&lt;br /&gt;
*Place a PHP file containing the code below in your template directory&lt;br /&gt;
*Replace &amp;quot;countries2.csv&amp;quot; with your CSV filename (you could make this more universal by passing the filename in the URL)&lt;br /&gt;
*This file will grab the contents of the CSV and encode them in JSON format that the JavaScript can use&lt;br /&gt;
*Place the JavaScript code below in ths source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace &amp;quot;templates/yourTemplate/countries.php&amp;quot; with the path to the PHP file (from LimeSurvey root)&lt;br /&gt;
*This script will grab the jsonized data from the PHP file and load it into an array that the plugin can use&lt;br /&gt;
&lt;br /&gt;
PHP code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
	$countriesArr = array();&lt;br /&gt;
&lt;br /&gt;
	$file_handle = fopen(&amp;quot;countries2.csv&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	while (!feof($file_handle) ) {&lt;br /&gt;
		$line_of_text = fgetcsv($file_handle);&lt;br /&gt;
		array_push($countriesArr, $line_of_text[0]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose($file_handle);&lt;br /&gt;
&lt;br /&gt;
	echo json_encode($countriesArr);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qID = QQ;&lt;br /&gt;
		var url = &amp;quot;templates/yourTemplate/countries.php&amp;quot;;&lt;br /&gt;
		var dataArr = [];&lt;br /&gt;
&lt;br /&gt;
		$.getJSON(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			$.each(data,function(i, item){&lt;br /&gt;
				dataArr.push(item);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#question&#039;+qID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
				source: dataArr&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Use autocomplete to populate several fields==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, IE 7/8/9, Firefox 18&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://jqueryui.com/demos/autocomplete/ Autocomplete widget] included with jQuery UI and the [https://code.google.com/p/jquery-csv/source/browse/jquery.csv.js?r=f13189b2550a770ccaa777f1d747bc860b943fe7 jquery.csv.js] plugin to provide a respondent with a list of suggested answers as they type in a text input and then to automatically populate other fields depending on the selection.&lt;br /&gt;
&lt;br /&gt;
For example, if you have 3 questions - &amp;quot;Name&amp;quot;, &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; - you can use this workaround to autocomplete the &amp;quot;Name&amp;quot; question and then the &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; questions can be automatically populated with values associated with the selected name.&lt;br /&gt;
*Download the [https://code.google.com/p/jquery-csv/source/browse/jquery.csv.js?r=f13189b2550a770ccaa777f1d747bc860b943fe7 jquery.csv.js] plugin and place it in your template folder&lt;br /&gt;
*If using LimeSurvey 1.9x, add the following line to your startpage.pstpl BEFORE the tag for template.js, if using 2.x, add it AFTER the {TEMPLATEJS} placeholder&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.csv.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Create your CSV file with 3 columns (name, ID, email) as in this example and place it in your template folder&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Bob,    Bob&#039;s ID,    Bob&#039;s email&lt;br /&gt;
&lt;br /&gt;
Andy,    Andy&#039;s ID,    Andy&#039;s email&lt;br /&gt;
&lt;br /&gt;
Sam,    Sam&#039;s ID,    Sam&#039;s email&lt;br /&gt;
&lt;br /&gt;
Tony,    Tony&#039;s ID,    Tony&#039;s email&lt;br /&gt;
&lt;br /&gt;
Fred,    Fred&#039;s ID,    Fred&#039;s email&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Create your 3 questions - &amp;quot;Name&amp;quot;, &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot;. They must be in the same group/page.&lt;br /&gt;
*Add the following styles to the end of your &#039;template.css&#039; file&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;/* Autocomplete styles */&lt;br /&gt;
&lt;br /&gt;
ul.ui-autocomplete {&lt;br /&gt;
&lt;br /&gt;
   width: 250px !important;&lt;br /&gt;
&lt;br /&gt;
   padding: 5px 10px;&lt;br /&gt;
&lt;br /&gt;
   list-style: none;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Add the following script to the source of one of the questions&lt;br /&gt;
*Replace:&lt;br /&gt;
**&amp;quot;NN&amp;quot; with the &amp;quot;Name&amp;quot; question ID&lt;br /&gt;
**&amp;quot;II&amp;quot; with the &amp;quot;ID&amp;quot; question ID&lt;br /&gt;
**&amp;quot;EE&amp;quot; with the &amp;quot;Email&amp;quot; question ID&lt;br /&gt;
*Modify the path to your CSV file&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qNameID = NN;&lt;br /&gt;
&lt;br /&gt;
		var qIDID = II;&lt;br /&gt;
&lt;br /&gt;
		var qEmailID = EE;&lt;br /&gt;
&lt;br /&gt;
		var url = &amp;quot;upload/templates/yourTemplate/yourCsvFile.csv&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		// Create an array to hold the names&lt;br /&gt;
		var namesArr = new Array();&lt;br /&gt;
&lt;br /&gt;
		// Grab the CSV contents&lt;br /&gt;
		$.get(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			// Convert CSV contents to an array of arrays&lt;br /&gt;
			fullArray = $.csv.toArrays(data);&lt;br /&gt;
&lt;br /&gt;
			// Load the names array&lt;br /&gt;
			$(fullArray).each(function(i, item){&lt;br /&gt;
				namesArr.push(item[0]);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Initialise the autocomplete plugin&lt;br /&gt;
			$(&#039;#question&#039;+qNameID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
				source: namesArr,&lt;br /&gt;
				// Event fired when a selection is made (ui.item.value refers to the selected item)&lt;br /&gt;
				select: function(event, ui) {&lt;br /&gt;
					// Find the &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; values associated with the selected name value and load those questions&lt;br /&gt;
					$(fullArray).each(function(i, item){&lt;br /&gt;
						if(item[0] == ui.item.value) {&lt;br /&gt;
							// The value from column 2 of the CSV&lt;br /&gt;
							$(&#039;#question&#039;+qIDID+&#039; input.text&#039;).val(item[1]);&lt;br /&gt;
							// The value from column 3 of the CSV&lt;br /&gt;
							$(&#039;#question&#039;+qEmailID+&#039; input.text&#039;).val(item[2]);&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Drag and Drop Rankings {{Deprecated|2.0}} =&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }} &lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking - Version 1.90 to 1.92==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+ &amp;amp; 1.91RC4, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }} &lt;br /&gt;
&lt;br /&gt;
This workaround is a modification of the workaround below and also uses [http://jqueryui.com/demos/sortable/#connect-lists JQuery connected sortables]. Thanks to the author of that workaround.&lt;br /&gt;
&lt;br /&gt;
[[File:Untitled-12.png]]&lt;br /&gt;
&lt;br /&gt;
Modifications include:&lt;br /&gt;
*Allow for multiple drag-n-drop ranking questions on a page&lt;br /&gt;
*Handle minimum and maximum answers settings&lt;br /&gt;
*Allow double clicking of items to add or remove them from the ranking list&lt;br /&gt;
*Work with the new shipped jQuery UI&lt;br /&gt;
&lt;br /&gt;
There is a &#039;&#039;&#039;[http://www.partnersinc.biz/surveys//index.php?sid=36981&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the large script below in your template.js file.&lt;br /&gt;
#Place the small script below in the source a ranking question, (this applies the &amp;quot;dragDropRank&amp;quot; function to the question). Replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID].&lt;br /&gt;
**Note: the LimeSurvey translations will be automatically used for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; header labels but can be overridden with custom labels - see the example calls below.&lt;br /&gt;
#Insert the CSS below at the end of template.css (these styles are for the default template).&lt;br /&gt;
&lt;br /&gt;
NOTE: I have not tested this workaround with conditions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code for template.js:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
function dragDropRank(qID, choiceText, rankText) {&lt;br /&gt;
&lt;br /&gt;
	if(!choiceText) {&lt;br /&gt;
		choiceText = $(&#039;#question&#039;+qID+&#039; td.label label&#039;).text();&lt;br /&gt;
	}&lt;br /&gt;
	if(!rankText) {&lt;br /&gt;
		rankText = $(&#039;#question&#039;+qID+&#039; td.output tr:first td:eq(1)&#039;).text();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Add a class to the question&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039;&#039;).addClass(&#039;dragDropRanking&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Hide the original question in LimeSurvey (so that we can replace with drag and drop)&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; .rank, #question&#039;+qID+&#039; .questionhelp&#039;).hide();&lt;br /&gt;
	&lt;br /&gt;
	// Turn off display of question (to override error checking built into LimeSurvey ranking question)&lt;br /&gt;
	//$(&#039;#display&#039;+qID).val(&#039;off&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Add connected sortables elements to the question&lt;br /&gt;
	var htmlCode = &#039;&amp;lt;table class=&amp;quot;dragDropTable&amp;quot;&amp;gt; \&lt;br /&gt;
		&amp;lt;tbody&amp;gt; \&lt;br /&gt;
			&amp;lt;tr&amp;gt; \&lt;br /&gt;
				&amp;lt;td&amp;gt; \&lt;br /&gt;
					&amp;lt;span class=&amp;quot;dragDropHeader choicesLabel&amp;quot;&amp;gt;&#039;+choiceText+&#039;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt; \&lt;br /&gt;
					&amp;lt;div class=&amp;quot;ui-state-highlight dragDropChoices&amp;quot;&amp;gt; \&lt;br /&gt;
						&amp;lt;ul id=&amp;quot;sortable1&#039;+qID+&#039;&amp;quot; class=&amp;quot;connectedSortable&#039;+qID+&#039; dragDropChoiceList&amp;quot;&amp;gt; \&lt;br /&gt;
							&amp;lt;li&amp;gt;Choices&amp;lt;/li&amp;gt; \&lt;br /&gt;
						&amp;lt;/ul&amp;gt; \&lt;br /&gt;
					&amp;lt;/div&amp;gt; \&lt;br /&gt;
				&amp;lt;/td&amp;gt; \&lt;br /&gt;
				&amp;lt;td&amp;gt; \&lt;br /&gt;
					&amp;lt;span class=&amp;quot;dragDropHeader rankingLabel&amp;quot;&amp;gt;&#039;+rankText+&#039;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt; \&lt;br /&gt;
					&amp;lt;div class=&amp;quot;ui-state-highlight dragDropRanks&amp;quot;&amp;gt; \&lt;br /&gt;
						&amp;lt;ol id=&amp;quot;sortable2&#039;+qID+&#039;&amp;quot; class=&amp;quot;connectedSortable&#039;+qID+&#039; dragDropRankList&amp;quot;&amp;gt; \&lt;br /&gt;
							&amp;lt;li&amp;gt;Ranks&amp;lt;/li&amp;gt; \&lt;br /&gt;
						&amp;lt;/ol&amp;gt; \&lt;br /&gt;
					&amp;lt;/div&amp;gt; \&lt;br /&gt;
				&amp;lt;/td&amp;gt; \&lt;br /&gt;
			&amp;lt;/tr&amp;gt; \&lt;br /&gt;
		&amp;lt;/tbody&amp;gt; \&lt;br /&gt;
					&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
	$(htmlCode).insertAfter(&#039;#question&#039;+qID+&#039; table.rank&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Remove placeholder list items (have to have one item so that LimeSurvey doesn&amp;quot;t remove the &amp;lt;ul&amp;gt;)&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li, #sortable2&#039;+qID+&#039; li&#039;).remove();&lt;br /&gt;
	&lt;br /&gt;
	// Load any previously-set values&lt;br /&gt;
	loadDragDropRank(qID);&lt;br /&gt;
	&lt;br /&gt;
	// Find the number of LimeSurvey ranking inputs (&amp;quot;Maximum answers&amp;quot;)&lt;br /&gt;
	var maxAnswer = $(&#039;#question&#039;+qID+&#039; td.output input.text&#039;).length;&lt;br /&gt;
	&lt;br /&gt;
	// Set up the connected sortable&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039;, #sortable2&#039;+qID+&#039;&#039;).sortable({&lt;br /&gt;
		connectWith: &#039;.connectedSortable&#039;+qID+&#039;&#039;,&lt;br /&gt;
		placeholder: &#039;ui-sortable-placeholder&#039;,&lt;br /&gt;
		helper: &#039;clone&#039;,&lt;br /&gt;
		revert: 50,&lt;br /&gt;
		receive: function(event, ui) {&lt;br /&gt;
			if($(&#039;#sortable2&#039;+qID+&#039; li&#039;).length &amp;gt; maxAnswer) {&lt;br /&gt;
				alert (&#039;You can only rank a maximum of &#039;+maxAnswer+&#039; choices.&#039;);&lt;br /&gt;
				$(ui.sender).sortable(&#039;cancel&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		stop: function(event, ui) {&lt;br /&gt;
			$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			updateDragDropRank(qID);&lt;br /&gt;
		}&lt;br /&gt;
	}).disableSelection();&lt;br /&gt;
	&lt;br /&gt;
	// Get the list of choices from the LimeSurvey question and copy them as items into the sortable choices list&lt;br /&gt;
	$(&#039;#CHOICES_&#039; + qID).children().each(function(index, Element) {&lt;br /&gt;
		var liCode = &#039;&amp;lt;li class=&amp;quot;ui-state-default&amp;quot; id=&amp;quot;choice_&#039; + $(this).attr(&amp;quot;value&amp;quot;) + &#039;&amp;quot;&amp;gt;&#039; + this.text + &#039;&amp;lt;/li&amp;gt;&#039;&lt;br /&gt;
		$(liCode).appendTo(&#039;#sortable1&#039;+qID+&#039;&#039;);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Allow users to double click to move to selections from list to list&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li&#039;).live(&#039;dblclick&#039;, function() {&lt;br /&gt;
		if($(&#039;#sortable2&#039;+qID+&#039; li&#039;).length == maxAnswer) {&lt;br /&gt;
			alert (&#039;You can only rank a maximum of &#039;+maxAnswer+&#039; choices.&#039;);&lt;br /&gt;
			return false;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(this).appendTo(&#039;#sortable2&#039;+qID+&#039;&#039;);&lt;br /&gt;
			$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			updateDragDropRank(qID);&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	$(&#039;#sortable2&#039;+qID+&#039; li&#039;).live(&#039;dblclick&#039;, function() {&lt;br /&gt;
		$(this).appendTo(&#039;#sortable1&#039;+qID+&#039;&#039;);&lt;br /&gt;
		$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
		$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
		updateDragDropRank(qID);&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function copies the drag and drop sortable data into the LimeSurvey ranking list.&lt;br /&gt;
function updateDragDropRank(qID) {&lt;br /&gt;
&lt;br /&gt;
	// Reload the LimeSurvey choices select element&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	$(&#039;#sortable2&#039;+qID+&#039; li&#039;).each(function(index) {&lt;br /&gt;
		$(this).attr(&#039;value&#039;, index+1);&lt;br /&gt;
		&lt;br /&gt;
		// Get value of ranked item&lt;br /&gt;
		var liID = $(this).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Save to an array&lt;br /&gt;
		rankees[rankees.length] = { &amp;quot;r_name&amp;quot;:$(this).text(),&amp;quot;r_value&amp;quot;:liIDArray[1] };&lt;br /&gt;
	});&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
		if (rankees.length &amp;gt; index) {&lt;br /&gt;
			$(this).val(rankees[index].r_name);&lt;br /&gt;
			$(this).next(&#039;input&#039;).attr(&#039;value&#039;, rankees[index].r_value);&lt;br /&gt;
		} else {&lt;br /&gt;
			$(this).val(&#039;&#039;);&lt;br /&gt;
			$(this).next().val(&#039;&#039;);&lt;br /&gt;
		}&lt;br /&gt;
	 });&lt;br /&gt;
	 &lt;br /&gt;
	// Reload the LimeSurvey choices select element (we need this for &amp;quot;Minimum answers&amp;quot; code)&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; td.label select option&#039;).remove();&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li&#039;).each(function(index) {&lt;br /&gt;
		var liText = $(this).text();&lt;br /&gt;
		var liID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		var optionCode = &#039;&amp;lt;option value=&amp;quot;&#039;+liIDArray[1]+&#039;&amp;quot;&amp;gt;&#039;+liText+&#039;&amp;lt;/option&amp;gt;&#039;;&lt;br /&gt;
		$(optionCode).appendTo(&#039;#question&#039;+qID+&#039; td.label select&#039;);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Hack for IE6&lt;br /&gt;
	if ($.browser.msie &amp;amp;&amp;amp; $.browser.version.substr(0,1)&amp;lt;7) {&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; select&#039;).show();&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; select&#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function is called on page load to see if there are any items already ranked (from a previous visit&lt;br /&gt;
// or cached due to a page change.  If so, the already-ranked items are loaded into the sortable list&lt;br /&gt;
function loadDragDropRank(qID) {&lt;br /&gt;
&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	&lt;br /&gt;
	// Loop through each item in the built-in LimeSurvey ranking list looking for non-empty values&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;/div&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
	&lt;br /&gt;
		// Check to see if the current item has a value&lt;br /&gt;
		if ($(this).val()) {&lt;br /&gt;
		&lt;br /&gt;
			// Item has a value - save to the array&lt;br /&gt;
			// Use this element to contain the name and the next for the value (numeric)&lt;br /&gt;
			rankees[rankees.length] = { &amp;quot;r_name&amp;quot;:$(this).val(),&amp;quot;r_value&amp;quot;:$(this).next().val() };&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Now that we have a list of all the pre-ranked items, populate the sortable list&lt;br /&gt;
	// Note that the items *won&amp;quot;t* appear in the main list because LimeSurvey has removed them.&lt;br /&gt;
	$.each(rankees, function(index, value) {&lt;br /&gt;
	&lt;br /&gt;
		// Create the items in the sortable&lt;br /&gt;
		var liCode = &#039;&amp;lt;li class=&amp;quot;ui-state-default&amp;quot; id=&amp;quot;choice_&#039; + value.r_value + &#039;&amp;quot;&amp;gt;&#039; + value.r_name + &#039;&amp;lt;/li&amp;gt;&#039;;&lt;br /&gt;
		$(liCode).appendTo(&#039;#sortable2&#039;+qID+&#039;&#039;);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s) using the LimeSurvey translations for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; element header labels&#039;&#039;&#039; (replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRank(QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix for later versions of 1.91+&#039;&#039;&#039;&lt;br /&gt;
In my version of LimeSurvey 1.91+, build 11026, this drag-n-drop workaround was not saving the selections properly. I&#039;m not sure if that&#039;s because of my template, or other jquery uses, but I fixed it by making the following modifications to the above code placed into template.js.&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having problems (and it&#039;s definitely worth testing that the rankings are actually saving into your response table before proceeding with the survey) give this a try.&lt;br /&gt;
&lt;br /&gt;
In the &#039;updateDragDropRank(qID)&#039; function, replace the line:&lt;br /&gt;
&amp;lt;syntaxhighlight  lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name^=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the &#039;loadDragDropRank(qID) function, replace the line:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&amp;lt;script&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;/div&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&amp;lt;script&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name^=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s) using custom text for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; element header labels&#039;&#039;&#039; (replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRank(QQ, &#039;Custom Choices Label&#039;, &#039;Custom Rankings Label&#039;);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Styles for template.css:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
/* Drag-n-drop ranking styles */&lt;br /&gt;
.dragDropTable {&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable td {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	width: 50%;&lt;br /&gt;
	padding-right: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropHeader {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoices,&lt;br /&gt;
.dragDropTable .dragDropRanks {&lt;br /&gt;
	margin: 5px 0 0 0;&lt;br /&gt;
	background: transparent none;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoiceList,&lt;br /&gt;
.dragDropTable .dragDropRankList {&lt;br /&gt;
	float: left;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	min-height: 2.4em;&lt;br /&gt;
	_height: 2.4em; /* IE6 and below hack */&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	list-style-type: none;&lt;br /&gt;
	background: #FBFBFB none;&lt;br /&gt;
	border: 1px solid #CCCCCC;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoiceList li,&lt;br /&gt;
.dragDropTable .dragDropRankList li {&lt;br /&gt;
	margin: 3px;&lt;br /&gt;
	*margin-left: -13px; /* IE7 and below */&lt;br /&gt;
	padding: 3px;&lt;br /&gt;
	min-height: 1.3em;&lt;br /&gt;
	_height: 1.3em; /* IE6 and below hack */&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	cursor: move;&lt;br /&gt;
	display: block; /* Force the li to full width */&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking using Images - Version 1.90 to 1.92==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+ &amp;amp; 1.91RC4, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }}&lt;br /&gt;
&lt;br /&gt;
This workaround works in conjunction with the above workaround to allow ranking of images.&lt;br /&gt;
&lt;br /&gt;
[[File:Untitled-11.png]]&lt;br /&gt;
&lt;br /&gt;
There is a &#039;&#039;&#039;[http://www.partnersinc.biz/surveys//index.php?sid=36981&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
1) Follow the above workaround to get basic drag-n-drop functionality in your ranking question.&lt;br /&gt;
&lt;br /&gt;
2) Insert your images in the ranking question text or help section after any text that you wish to have there (we&#039;ll move them later with JavaScript).&lt;br /&gt;
&lt;br /&gt;
3) Give the images &#039;&#039;&#039;EXACTLY&#039;&#039;&#039; the same IDs as the answer code you would like them to be associated with:[[File:Untitled-8.png]]&lt;br /&gt;
&lt;br /&gt;
4) Place the first script below in your template.js file.&lt;br /&gt;
&lt;br /&gt;
5) Place the second script below in the source the ranking question &#039;&#039;&#039;AFTER&#039;&#039;&#039; the initial call for the dragDropRank function from the workaround above. Replace &amp;quot;QQ&amp;quot; with the ID of the ranking question (this applies the &amp;quot;dragDropRankImages&amp;quot; function to the question).&lt;br /&gt;
&lt;br /&gt;
6) Insert the CSS below at the end of template.css. Replace &amp;quot;11&amp;quot; with your question ID. These styles are for the default template using 50x50px images (as in the demo) and may need to be modified for other templates or image sizes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code for template.js:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function dragDropRankImages(qID) {&lt;br /&gt;
&lt;br /&gt;
	$(&#039;.connectedSortable&#039;+qID+&#039; li&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
		// Remove any text in the sortable choice or rank items&lt;br /&gt;
		$(this).text(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Move the images into the appropriate sortable list item&lt;br /&gt;
		var liID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; img#&#039;+liIDArray[1]+&#039;&#039;).appendTo(this);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRankImages(QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Styles for template.css:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Drag-n-drop for ranking images */&lt;br /&gt;
#question11 .dragDropTable {&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable .dragDropChoiceList,&lt;br /&gt;
#question11 .dragDropTable .dragDropRankList {&lt;br /&gt;
	min-height: 60px;&lt;br /&gt;
	_height: 60px; /* IE6 and below hack */&lt;br /&gt;
	width: auto;&lt;br /&gt;
	min-width: 60px;&lt;br /&gt;
	_width: 60px; /* IE6 and below hack */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable li {&lt;br /&gt;
	background: 0 none;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
	height: 50px;&lt;br /&gt;
	width: 50px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable li img {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking for iPad - Version 1.91 and newer==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LimeSurvey 1.91, iPad 2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround extends the above workarounds to work with the touch interface on iPads.&lt;br /&gt;
&lt;br /&gt;
1) Follow the [[Workarounds: Manipulating a survey at runtime using Javascript#Drag and Drop Ranking - Version 1.90 and newer|Drag and Drop Ranking - Version 1.90 and newer]] workaround above to get basic drag-n-drop functionality in your ranking question.&lt;br /&gt;
&lt;br /&gt;
2) Download the [https://github.com/furf/jquery-ui-touch-punch jQuery.ui.touch-punch.js plugin] and save it in your template directory.&lt;br /&gt;
&lt;br /&gt;
3) Replace this line in your startpage.pstpl:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}template.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;With this:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.ui.touch-punch.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}template.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking - Version 1.86==&lt;br /&gt;
&lt;br /&gt;
Tested with 1.86 on IE 7,8, FireFox 3, Chrome, and Safari 4&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }}&lt;br /&gt;
&lt;br /&gt;
This workaround uses [http://jqueryui.com/demos/sortable/#connect-lists JQuery connected sortables] to modify a ranking question and allow the survey taker to drag and drop choices instead of clicking.  The nice thing is that the choices can be easily re-arranged or removed from the ranking, all by drag and drop.&lt;br /&gt;
&lt;br /&gt;
I used it for a voting application and some of the element names reflect that use.&lt;br /&gt;
&lt;br /&gt;
It looks best when some CSS is added to control the appearance of the boxers around each choice.&lt;br /&gt;
&lt;br /&gt;
[[File:drag-n-drop.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
	// Question ID global variable&lt;br /&gt;
	var questionID;&lt;br /&gt;
	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
	&lt;br /&gt;
		// Grab the question ID[[File:drag-n-drop.png]]&lt;br /&gt;
		// This is something with a class of &amp;quot;ranking&amp;quot; and an ID that starts with &amp;quot;questionXXXXX&amp;quot;.  The X&#039;s represent the question ID&lt;br /&gt;
		var entire_questionID = $(&amp;quot;.ranking[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&#039;question&#039;]&amp;quot;).attr(&#039;id&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Get just the question number (ID)&lt;br /&gt;
		var patt=/\d+$/;&lt;br /&gt;
		questionID=patt.exec(entire_questionID);&lt;br /&gt;
		&lt;br /&gt;
		// Hide the original quetion in LimeSurvey (so that we can replace with drag and drop)&lt;br /&gt;
		$(&amp;quot;.rank, .questionhelp&amp;quot;).hide();&lt;br /&gt;
		&lt;br /&gt;
		// Turn off display of question (to override error checking built into LimeSurvey ranking question)&lt;br /&gt;
		$(&amp;quot;#display&amp;quot;+questionID).val(&amp;quot;off&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Add connected sortables to the question&lt;br /&gt;
		var html_code = &amp;quot;&amp;lt;table style=&#039;border: medium none ; width: 770px; margin-left: auto; \&lt;br /&gt;
								margin-right: auto;&#039;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&#039;width: 590px; vertical-align: top;&#039;&amp;gt;&amp;lt;h3&amp;gt;List of Candidates:&amp;lt;/h3&amp;gt; \&lt;br /&gt;
								&amp;lt;div class=&#039;ui-state-highlight&#039; style=&#039;margin: 5px; float: left;&#039; id=&#039;ballot_list&#039;&amp;gt; \&lt;br /&gt;
								&amp;lt;ul id=&#039;sortable1&#039; class=&#039;connectedSortable&#039;&amp;gt;&amp;lt;li&amp;gt;Candidates&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt; \&lt;br /&gt;
								&amp;lt;td style=&#039;vertical-align: top;&#039;&amp;gt;&amp;lt;h3&amp;gt;Your selections:&amp;lt;/h3&amp;gt;&amp;lt;div class=&#039;ui-state-highlight&#039; \&lt;br /&gt;
								style=&#039;margin: 5px; float: left;&#039; id=&#039;voting_selections&#039;&amp;gt;&amp;lt;ol id=&#039;sortable2&#039; class=&#039;connectedSortable&#039;&amp;gt; \&lt;br /&gt;
								&amp;lt;li&amp;gt;Voting Area&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;;&lt;br /&gt;
		$(html_code).appendTo(&amp;quot;#question&amp;quot; + questionID);&lt;br /&gt;
		&lt;br /&gt;
		// Remove list items (have to have one item so that LimeSurvey doesn&#039;t remove the &amp;lt;ul&amp;gt;)&lt;br /&gt;
		$(&amp;quot;#sortable1 li, #sortable2 li&amp;quot;).remove();&lt;br /&gt;
		&lt;br /&gt;
		// Load any previously-set values&lt;br /&gt;
		loadRanking();&lt;br /&gt;
		&lt;br /&gt;
		// Load jQuery UI&lt;br /&gt;
		$.getScript(&amp;quot;/scripts/jquery/jquery-ui.js&amp;quot;, function() {&lt;br /&gt;
		&lt;br /&gt;
			// After JQuery UI finishes loading, set up the connected sortable.&lt;br /&gt;
			$(&amp;quot;#sortable1, #sortable2&amp;quot;).sortable({&lt;br /&gt;
				connectWith: &#039;.connectedSortable&#039;,&lt;br /&gt;
				placeholder: &#039;ui-sortable-placeholder&#039;,&lt;br /&gt;
				stop: function(event, ui) {&lt;br /&gt;
					$(&amp;quot;#sortable1&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
					$(&amp;quot;#sortable2&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
					updateRanking();&lt;br /&gt;
					}&lt;br /&gt;
			}).disableSelection();&lt;br /&gt;
			&lt;br /&gt;
			// Get the list of candidates from the built-in LimeSurvey question and copy them as items in sortable1&lt;br /&gt;
			$(&amp;quot;#CHOICES_&amp;quot; + questionID).children().each(function(index, Element) {&lt;br /&gt;
				li_tag = &amp;quot;&amp;lt;li class=&#039;ui-state-default&#039; id=&#039;choice_&amp;quot; + $(this).attr(&#039;value&#039;) + &amp;quot;&#039;&amp;gt;&amp;quot; + this.text + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;&lt;br /&gt;
				$(li_tag).appendTo(&amp;quot;#sortable1&amp;quot;); }	);&lt;br /&gt;
				&lt;br /&gt;
			// Make sure the submit button is showing&lt;br /&gt;
			$(&amp;quot;:submit[value|=&#039; Submit&#039;]&amp;quot;).show();&lt;br /&gt;
			&lt;br /&gt;
			// Show a confirmation alert upon submit&lt;br /&gt;
			$(&amp;quot;form&amp;quot;).submit(function() {&lt;br /&gt;
			&lt;br /&gt;
				// Override the built-in &amp;quot;disable navigation buttons&amp;quot; feature&lt;br /&gt;
				$(&#039;#moveprevbtn, #movenextbtn, #movesubmitbtn&#039;).attr(&#039;disabled&#039;, &#039;&#039;);&lt;br /&gt;
				var validated = confirm(&amp;quot;Cast your ballot now?&amp;quot;);&lt;br /&gt;
				if (validated) { return true; } else { return false; }&lt;br /&gt;
			});&lt;br /&gt;
			&lt;br /&gt;
			// Allow users to double click to move to selection list&lt;br /&gt;
			$(&amp;quot;#sortable1 li&amp;quot;).assignDblClick();&lt;br /&gt;
		});  // End of JQuery UI loading&lt;br /&gt;
		&lt;br /&gt;
	}); // End of JQuery ready function&lt;br /&gt;
	&lt;br /&gt;
// Define the actions when an item is double clicked&lt;br /&gt;
$.fn.assignDblClick = function() {&lt;br /&gt;
	$(this).dblclick(function(){&lt;br /&gt;
		$(this).appendTo(&#039;#sortable2&#039;);&lt;br /&gt;
		$(&amp;quot;#sortable1&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
		$(&amp;quot;#sortable2&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
		updateRanking();&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function copies the drag and drop sortable data into the standard LimeSurvey ranking structure.&lt;br /&gt;
function updateRanking() {&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	$(&#039;#sortable2 li&#039;).each(function(index) {&lt;br /&gt;
	$(this).attr(&amp;quot;value&amp;quot;, index+1);&lt;br /&gt;
	&lt;br /&gt;
		// Get value of person&lt;br /&gt;
		li_tag = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		li_tag_array = li_tag.split(&amp;quot;_&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Save to an array&lt;br /&gt;
		rankees[rankees.length] = { &#039;r_name&#039;:$(this).text(),&#039;r_value&#039;:li_tag_array[1] };&lt;br /&gt;
	});&lt;br /&gt;
	$(&amp;quot;input[name&amp;lt;/div&amp;gt;=&#039;RANK_&#039;]&amp;quot;).each(function(index) {&lt;br /&gt;
		if (rankees.length &amp;gt; index) {&lt;br /&gt;
			$(this).val(rankees[index].r_name);&lt;br /&gt;
			$(this).next().val(rankees[index].r_value);&lt;br /&gt;
		} else {&lt;br /&gt;
			$(this).val(&amp;quot;&amp;quot;);&lt;br /&gt;
			$(this).next().val(&amp;quot;&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	 });&lt;br /&gt;
	 &lt;br /&gt;
	// Re-assign double click action to first list items and remove&lt;br /&gt;
	// double click action from section list items&lt;br /&gt;
	$(&#039;#sortable1 li&#039;).unbind(&#039;dblclick&#039;).assignDblClick();&lt;br /&gt;
	$(&#039;#sortable2 li&#039;).unbind(&#039;dblclick&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function is called on page load to see if there are any items already ranked (from a previous visit&lt;br /&gt;
// or cached due to a page change.  If so, the already-ranked items are loaded into the sortable list&lt;br /&gt;
function loadRanking() {&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	&lt;br /&gt;
	// Loop through each item in the built-in LimeSurvey ranking list looking for non-empty values&lt;br /&gt;
	$(&amp;quot;input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&#039;RANK_&#039;]&amp;quot;).each(function(index) {&lt;br /&gt;
	&lt;br /&gt;
		// Check to see if the current item has a value&lt;br /&gt;
		if ($(this).val()) {&lt;br /&gt;
			// Item has a value - save to the array&lt;br /&gt;
			// Use this element to contain the name and the next for the value (numeric)&lt;br /&gt;
			rankees[rankees.length] = { &#039;r_name&#039;:$(this).val(),&#039;r_value&#039;:$(this).next().val() };&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Now that we have a list of all the pre-ranked items, populate the sortable list&lt;br /&gt;
	// Note that the items *won&#039;t* appear in the main list because LimeSurvey has removed them.&lt;br /&gt;
	$.each(rankees, function(index, value) {&lt;br /&gt;
		// Create the items in the sortable&lt;br /&gt;
		li_tag = &amp;quot;&amp;lt;li class=&#039;ui-state-default&#039; id=&#039;choice_&amp;quot; + value.r_value + &amp;quot;&#039;&amp;gt;&amp;quot; + value.r_name + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
		$(li_tag).appendTo(&amp;quot;#sortable2&amp;quot;);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Create MaxDiff question type=&lt;br /&gt;
&lt;br /&gt;
See the [[Workarounds: Question design, layout and templating|Question design, layout and templating]] section for a workaround that uses JavaScript to convert an &#039;&#039;&#039;&#039;&#039;Array (flexible labels) by column&#039;&#039;&#039;&#039;&#039; question into a [http://en.wikipedia.org/wiki/MaxDiff MaxDiff] question type.&lt;br /&gt;
&lt;br /&gt;
[[File:max_diff_596x253.gif]]&lt;br /&gt;
&lt;br /&gt;
=In a checkbox matrix, have the &#039;none&#039; option in a row disable all other columns in that row=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LimeSurvey 1.90+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The questionId parameter is the base ID of the question matrix (multiflexible).&lt;br /&gt;
&lt;br /&gt;
numColumns and numRows speak for themselves&lt;br /&gt;
&lt;br /&gt;
specialColumns is an array of the columns that have the special ability that when one of them&lt;br /&gt;
&lt;br /&gt;
is checked, none of the others can be checked. E.g., a &#039;none of these&#039; and/or a &#039;do now know&#039; option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
numColumns=13;&lt;br /&gt;
&lt;br /&gt;
numRows=18;&lt;br /&gt;
&lt;br /&gt;
questionId=&#039;28417X2X24&#039;;&lt;br /&gt;
&lt;br /&gt;
specialColumns=[1,12,13];&lt;br /&gt;
&lt;br /&gt;
function action(obj){&lt;br /&gt;
&lt;br /&gt;
   locator=obj.id.replace(&#039;cbox_&#039;+questionId, &#039;&#039;).split(&#039;_&#039;);&lt;br /&gt;
&lt;br /&gt;
   row=locator[0];&lt;br /&gt;
&lt;br /&gt;
   column=locator[1];&lt;br /&gt;
&lt;br /&gt;
   //alert(&#039;Action for row,column=&#039;+row+&#039;,&#039;+column);&lt;br /&gt;
&lt;br /&gt;
   my_id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+column+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   if($(my_id).attr(&#039;checked&#039;) == false) {&lt;br /&gt;
&lt;br /&gt;
       for( var i=1; i&amp;lt;=numColumns; i++ ) {&lt;br /&gt;
&lt;br /&gt;
           if(i==column) continue;&lt;br /&gt;
&lt;br /&gt;
           id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;disabled&#039;,false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   } else {&lt;br /&gt;
&lt;br /&gt;
       for( var i=1; i&amp;lt;=numColumns; i++ ) {&lt;br /&gt;
&lt;br /&gt;
           if(i==column) continue;&lt;br /&gt;
&lt;br /&gt;
           id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           aid=&#039;#answer&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           $(aid).val(0);&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;checked&#039;,false);&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;disabled&#039;,true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function customOnLoad(){&lt;br /&gt;
&lt;br /&gt;
   for( var row=1; row&amp;lt;=numRows; row++ ) {&lt;br /&gt;
&lt;br /&gt;
       for( var k=0; k&amp;lt;specialColumns.length; k++ )&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           column=specialColumns[k];&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+column).change(function() {&lt;br /&gt;
&lt;br /&gt;
               action(this);&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
   customOnLoad();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Last Option In Array (Numbers) (Checkboxes) Row Excludes All Others=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 2.05, IE 7-10, Firefox&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to make the last option of each Array (Numbers) (Checkboxes) row exclude all other options in the same row.&lt;br /&gt;
&lt;br /&gt;
The script will uncheck all options in a row if the last option is checked and uncheck the last option in a row if any other options are checked.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following script in the source of the array question.&lt;br /&gt;
&lt;br /&gt;
NOTE: Care should be taken when using this script and conditional questions on the same page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Call the exclude function using question ID&lt;br /&gt;
		excludeOpt ({QID});&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// A function to make the last option in each array row exclusive&lt;br /&gt;
	function excludeOpt (qID) {&lt;br /&gt;
		&lt;br /&gt;
		var thisQuestion = $(&#039;#question&#039;+qID)&lt;br /&gt;
&lt;br /&gt;
		// Add some classes to the checkbox cells&lt;br /&gt;
		$(&#039;table.question tbody td&#039;, thisQuestion).addClass(&#039;normalOpt&#039;);&lt;br /&gt;
		$(&#039;table.question tbody tr&#039;, thisQuestion).each(function(i) {&lt;br /&gt;
			$(&#039;.normalOpt:last&#039;, this).removeClass(&#039;normalOpt&#039;).addClass(&#039;exlusiveOpt&#039;)&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// A listener on the checkbox cells&lt;br /&gt;
		$(&#039;table.question tbody td&#039;, thisQuestion).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Set some vars&lt;br /&gt;
			var thisRow = $(this).closest(&#039;tr&#039;);&lt;br /&gt;
&lt;br /&gt;
			// Uncheck the appropriate boxes in a row&lt;br /&gt;
			if ($(this).hasClass(&#039;normalOpt&#039;)) {&lt;br /&gt;
				$(&#039;.exlusiveOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;.normalOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// A listener on the checkboxes&lt;br /&gt;
		$(&#039;table.question tbody td input[type=checkbox]&#039;, thisQuestion).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Set some vars&lt;br /&gt;
			var thisRow = $(this).closest(&#039;tr&#039;);&lt;br /&gt;
			var thisCell = $(this).closest(&#039;td&#039;);&lt;br /&gt;
&lt;br /&gt;
			// Uncheck the appropriate boxes in a row&lt;br /&gt;
			if ($(thisCell).hasClass(&#039;normalOpt&#039;)) {&lt;br /&gt;
				$(&#039;.exlusiveOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;.normalOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Add Navigation Buttons (Next and Previous) To Top Of Page=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add the following to the end of template.js. It will insert a new div after the progress bar and then insert clones of the nav buttons in the new div.&lt;br /&gt;
&lt;br /&gt;
This example is for the default template in 1.90 or 1.91. The placement of the new div may need to be modified for other templates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Insert a new div after the progress bar&lt;br /&gt;
		$(&#039;&amp;lt;div id=&amp;quot;navigator2&amp;quot; /&amp;gt;&#039;).insertAfter(&#039;#progress-wrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Style the new div&lt;br /&gt;
		$(&#039;#navigator2&#039;).css({&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// Insert clones of the nav buttons in the new div&lt;br /&gt;
		$(&#039;input.submit:eq(0)&#039;).clone().appendTo(&#039;#navigator2&#039;);&lt;br /&gt;
		$(&#039;input.submit:eq(2)&#039;).clone().appendTo(&#039;#navigator2&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Give the new buttons some new IDs&lt;br /&gt;
		$(&#039;#navigator2 input.submit&#039;).each(function(i) {&lt;br /&gt;
			var oldID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
			var newID = oldID + &#039;2&#039;;&lt;br /&gt;
			$(this).attr(&#039;id&#039;, newID)&lt;br /&gt;
		});&lt;br /&gt;
	});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:extra_buttons.png]]&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;add&#039;&#039; an opt out link to your survey=&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.91+, Firefox 5.0&lt;br /&gt;
&lt;br /&gt;
This javascript inserts a link to opt out of the survey above the progress bar.&lt;br /&gt;
&lt;br /&gt;
[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]]&lt;br /&gt;
&lt;br /&gt;
Then insert the following code into to the source of a group description or a question. I used the group description.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt; &amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Find the survey ID&lt;br /&gt;
		if($(&#039;input#fieldnames&#039;).length != 0) {&lt;br /&gt;
			var fieldNames = $(&#039;input#fieldnames&#039;).attr(&#039;value&#039;);&lt;br /&gt;
			var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
			var sID = tmp[0];&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Insert a new div after the progress bar&lt;br /&gt;
		$(&#039;&amp;lt;div id=&amp;quot;optOutLink&amp;quot; /&amp;gt;&#039;).insertBefore(&#039;#progress-wrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Style the new div&lt;br /&gt;
		$(&#039;#optOutLink&#039;).css({&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// Insert opt out url in the new div&lt;br /&gt;
		$(&#039;#optOutLink&#039;).html(&#039;&amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;optout.php?lang=en&amp;amp;sid;=&#039;+sID+&#039;&amp;amp;token;={TOKEN}&amp;quot;&amp;gt;Click here to opt out of this survey.&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;br&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Anonymously track respondents answers across multiple surveys=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+ and 1.92+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to enable tracking of respondents across multiple surveys ensuring anonymity (it does not use tokens).&lt;br /&gt;
&lt;br /&gt;
To do this you have to use this question in all the surveys you want to link respondents answers.&lt;br /&gt;
&lt;br /&gt;
This workaround create an ID by asking some partial personal information (like initials, birth month ...). The ID will be encrypted using a one-way function (in this case SHA-1) and stored in a short text answer.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following code in the source of a short text question.&lt;br /&gt;
#Optional: you can also add other select field to avoid collisions (e.g. for large population sample)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This answers are used to generate your ID. These information will be encrypted, it will not be possible in any case to identify you neither from your answers nor from your ID.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;Initial of your name&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select id=&amp;quot;field1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;A&amp;quot;&amp;gt;A&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;B&amp;quot;&amp;gt;B&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;C&amp;quot;&amp;gt;C&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;D&amp;quot;&amp;gt;D&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;E&amp;quot;&amp;gt;E&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;F&amp;quot;&amp;gt;F&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;G&amp;quot;&amp;gt;G&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;H&amp;quot;&amp;gt;H&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;I&amp;quot;&amp;gt;I&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;J&amp;quot;&amp;gt;J&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;K&amp;quot;&amp;gt;K&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;L&amp;quot;&amp;gt;L&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;M&amp;quot;&amp;gt;M&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;N&amp;quot;&amp;gt;N&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;O&amp;quot;&amp;gt;O&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;P&amp;quot;&amp;gt;P&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Q&amp;quot;&amp;gt;Q&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;R&amp;quot;&amp;gt;R&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;S&amp;quot;&amp;gt;S&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;T&amp;quot;&amp;gt;T&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;U&amp;quot;&amp;gt;U&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;V&amp;quot;&amp;gt;V&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;W&amp;quot;&amp;gt;W&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;X&amp;quot;&amp;gt;X&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Y&amp;quot;&amp;gt;Y&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Z&amp;quot;&amp;gt;Z&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;Your birth month&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select id=&amp;quot;field2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;01&amp;quot;&amp;gt;January&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;02&amp;quot;&amp;gt;February&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;03&amp;quot;&amp;gt;March&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;04&amp;quot;&amp;gt;April&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;05&amp;quot;&amp;gt;May&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;06&amp;quot;&amp;gt;June&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;07&amp;quot;&amp;gt;July&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;08&amp;quot;&amp;gt;August&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;09&amp;quot;&amp;gt;September&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;10&amp;quot;&amp;gt;October&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;11&amp;quot;&amp;gt;November&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;12&amp;quot;&amp;gt;December&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/sha1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   $(&amp;quot;#answer{SGQ}&amp;quot;).attr(&#039;readonly&#039;, &#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
   //$(&amp;quot;#answer{SGQ}&amp;quot;).css(&#039;display&#039;, &#039;none&#039;); //uncomment this line for not displaying the code&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(&#039;#field1, #field2&#039;).bind(&#039;change keyup&#039;, function() {&lt;br /&gt;
&lt;br /&gt;
   if ($(&amp;quot;#field1&amp;quot;).val()==&#039;&#039; || $(&amp;quot;#field2&amp;quot;).val()==&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;#answer{SGQ}&amp;quot;).val(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
   else {&lt;br /&gt;
&lt;br /&gt;
       var sha1 = CryptoJS.algo.SHA1.create();&lt;br /&gt;
&lt;br /&gt;
       sha1.update($(&amp;quot;#field1&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       sha1.update($(&amp;quot;#field2&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       // sha1.update($(&amp;quot;#otherfield&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       var hash = sha1.finalize();&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;#answer{SGQ}&amp;quot;).val(hash);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Check validity of international phone number in subquestion=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, Firefox 8, Chrome 15&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As of version 1.92, you can use the core Validation querstion option to validate multiple short text and array text questions. Any question that fails that validation check will have its background color changed to red.&lt;br /&gt;
&lt;br /&gt;
Note, the below workaround will fail in version 1.92 because it contains a regular expression with curly braces.  However, as described above, support for this feature is now built-in to version 1.92&lt;br /&gt;
&lt;br /&gt;
This workaround uses javascript to check the validity of an international phone number in a subquestion of multiple short text.&lt;br /&gt;
&lt;br /&gt;
Add the following code to the source of your question.&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;NN&amp;quot; with the row number that you want to validate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the phone function with the question ID and the row number&lt;br /&gt;
&lt;br /&gt;
       phoneTest(QQ, NN);&lt;br /&gt;
&lt;br /&gt;
       function phoneTest(qID, inputNum) {&lt;br /&gt;
&lt;br /&gt;
           // Interrupt next/submit function&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               // Some vars - modify as required&lt;br /&gt;
&lt;br /&gt;
               var phoneMatch = /^[0-9,+,(), ,]{1,}(,[0-9]+){0,}$/;&lt;br /&gt;
&lt;br /&gt;
               var msg1 = &#039;Please enter a valid phone number.&#039;;&lt;br /&gt;
&lt;br /&gt;
               // Test the input&lt;br /&gt;
&lt;br /&gt;
               var phoneInput = $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               if(phoneInput != &#039;&#039; &amp;amp;&amp;amp; !phoneMatch.test(phoneInput)) {&lt;br /&gt;
&lt;br /&gt;
                   alert(msg1);&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;pink&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The regex is from: [http://www.regexlib.com/REDetails.aspx?regexp_id=1136 regexlib.com blank]&lt;br /&gt;
&lt;br /&gt;
=Check validity of email address in subquestion=&lt;br /&gt;
&lt;br /&gt;
&#039;Tested with: 1.91+, Firefox 8, Chrome 15&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, you can use the core Validation querstion option to validate multiple short text and array text questions. Any question that fails that validation check will have its background color changed to red.&amp;lt;br /&amp;gt;Note, the below workaround will fail in version 1.92 because it contains a regular expression with curly braces.  However, as described above, support for this feature is now built-in to version 1.92&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses javascript to check the validity of an email address in a subquestion of multiple short text.&lt;br /&gt;
&lt;br /&gt;
Add the following code to the source of your question.&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;NN&amp;quot; with the row number that you want to validate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the email function with the question ID and the row number&lt;br /&gt;
&lt;br /&gt;
       emailTest(QQ, NN);&lt;br /&gt;
&lt;br /&gt;
       function emailTest(qID, inputNum) {&lt;br /&gt;
&lt;br /&gt;
           // Interrupt next/submit function&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               // Some vars - modify as required&lt;br /&gt;
&lt;br /&gt;
               var emailMatch = /^[a-zA-Z0-9\_\-]+[a-zA-Z0-9\.\_\-]*@([a-zA-Z0-9\_\-]+\.)+([a-zA-Z]{2,4}|travel|museum)$/;&lt;br /&gt;
&lt;br /&gt;
               var msg1 = &#039;Please enter a valid email address.&#039;;&lt;br /&gt;
&lt;br /&gt;
               // Test the input&lt;br /&gt;
&lt;br /&gt;
               var emailInput = $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               if(emailInput != &#039;&#039; &amp;amp;&amp;amp; !emailMatch.test(emailInput)) {&lt;br /&gt;
&lt;br /&gt;
                   alert(msg1);&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;pink&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The regex is from: [http://www.regexlib.com/REDetails.aspx?regexp_id=1653 regexlib.com blank]&lt;br /&gt;
&lt;br /&gt;
=Hiding the help-text when it&#039;s empty=&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.91+&lt;br /&gt;
&lt;br /&gt;
I had made a style in my template putting a border around my help-text. To avoid empty help-text to show up (and have lines instead of just &#039;nothing&#039; when there was no help text, I used this piece of code in question.pstpl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                   var questionhelp=&amp;quot;{QUESTIONHELP}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
                   if (questionhelp==&amp;quot;&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
                          document.write(&amp;quot;&amp;quot;);}&lt;br /&gt;
&lt;br /&gt;
                   else {&lt;br /&gt;
&lt;br /&gt;
                   document.write(&#039;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;survey-question-help&amp;quot;&amp;gt;&#039;+ questionhelp +&#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;);}&lt;br /&gt;
&lt;br /&gt;
               &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
it can probably be optimized but it worked for me&lt;br /&gt;
&lt;br /&gt;
=Disable or hide selected fields in a matrix question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+, IE 7/8/9, FireFox 12/13&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
TASK&lt;br /&gt;
&lt;br /&gt;
Hide or disable selected fields in a Matrix, so that users cannot make any input.&lt;br /&gt;
&lt;br /&gt;
(See example, where users should not make input into red framed fields)&lt;br /&gt;
&lt;br /&gt;
[[File:snap035.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Prevent users from input into first two fields (as an example)&lt;br /&gt;
&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
First find the name of the fields you want to hide / disable. In my case I used Firebug with firefox to figure that out.&lt;br /&gt;
&lt;br /&gt;
[[File:snap037.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 2: Figure out the name(s) of the field(s)&lt;br /&gt;
&lt;br /&gt;
Then put the following script-code into the HTML-source code as described above:&lt;br /&gt;
&lt;br /&gt;
Note: you have to change the code to match the names of your fields!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;input[name=&amp;quot;69965X2X10SQ001_SQ001&amp;quot;]&#039;).attr(&#039;disabled&#039;, &#039;disabled&#039;);&lt;br /&gt;
&lt;br /&gt;
       $(&#039;input[name=&amp;quot;69965X2X10SQ001_SQ002&amp;quot;]&#039;).attr(&#039;hidden&#039;, &#039;hidden&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:snap039.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 3: Result: first field is diabled (&amp;quot;greyed out&amp;quot;), second one is completely hidden&lt;br /&gt;
&lt;br /&gt;
I think this way one can apply many other attributes to a field like color etc. But did not try that myself.&lt;br /&gt;
&lt;br /&gt;
Thanks to roB2009 for the input in the forum!&lt;br /&gt;
&lt;br /&gt;
=Add prefix or suffix to question type &amp;quot;Array (Texts)&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
TASK&lt;br /&gt;
&lt;br /&gt;
Add a prefix or suffix to the text fields in questions of the &amp;quot;Array (Texts)&amp;quot; type.&lt;br /&gt;
&lt;br /&gt;
[[File:suffix.png]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Suffix&lt;br /&gt;
&lt;br /&gt;
[[File:prefix.png]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Prefix&lt;br /&gt;
&lt;br /&gt;
SOLUTION&lt;br /&gt;
*Set up your survey to use JavaScript.&lt;br /&gt;
*Add the following script to the source of the array. Replace &amp;quot;12345&amp;quot; with the array question ID and modify the suffixes/prefixes as required.&lt;br /&gt;
*The function call must consist of a question ID followed by the suffixes for each column. Suffixes/Prefixes must be enclosed in quotes and comma separated.&lt;br /&gt;
*In this example question ID 12345 will get an &amp;quot;in &amp;amp;euro;&amp;quot; suffix in the first column and an &amp;quot;in %&amp;quot; in the next 3 columns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the function with the question ID followed by a comma-separated list of suffixes&lt;br /&gt;
&lt;br /&gt;
       addSuffix(12345, &#039;in &amp;amp;euro;&#039;, &#039;in %&#039;, &#039;in %&#039;, &#039;in %&#039;);&lt;br /&gt;
&lt;br /&gt;
       function addSuffix() {&lt;br /&gt;
&lt;br /&gt;
           var qID = $(arguments)[0];&lt;br /&gt;
&lt;br /&gt;
           // Assign some column-specific classes&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+qID+&#039; table.question tbody tr&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
               $(&#039;td&#039;, this).each(function(i){&lt;br /&gt;
&lt;br /&gt;
                   $(this).addClass(&#039;answerCol-&#039;+(i+1)+&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
               });&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Some styling&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+qID+&#039; table.question tbody input[type=&amp;quot;text&amp;quot;]&#039;).css({&lt;br /&gt;
&lt;br /&gt;
               &#039;width&#039;: &#039;50%&#039;&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Insert the suffixes&lt;br /&gt;
&lt;br /&gt;
           $(arguments).each(function(i, val){&lt;br /&gt;
&lt;br /&gt;
               if(i &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).append(val);&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For adding a prefix you need to substitute the following line in the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).append(val);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).prepend(val);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Time question (Date question-like)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to build a Time question just like to the Date one.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Download the file at [http://trentrichardson.com/examples/timepicker/jquery-ui-timepicker-addon.js trentrichardson.com/examples/timepicker/jquery-ui-timepicker-addon.js] and upload it to your survey.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following code in the source of a short text question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;/upload/surveys/{SID}/jquery-ui-timepicker-addon.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer{SGQ}&#039;).timepicker({&lt;br /&gt;
			timeText: &#039;Time&#039;, //here translation&lt;br /&gt;
			hourText: &#039;hour&#039;, //here translation&lt;br /&gt;
			minuteText: &#039;minute&#039;, //here translation&lt;br /&gt;
			closeText: &#039;Done&#039; //here translation&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer{SGQ}&#039;).attr(&#039;readonly&#039;, &#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
		$( &amp;quot;&amp;lt;style&amp;gt;&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-widget-header, .ui-datepicker-current { display:none; }&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }&amp;quot;&lt;br /&gt;
		+&amp;quot; }&amp;quot;&lt;br /&gt;
		+&amp;quot;&amp;lt;/style&amp;gt;&amp;quot;).appendTo( &amp;quot;head&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Calculating date difference=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+ Build 120909&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround explains how calculate difference between two dates (in: days, weeks, months and years) and is based on this [http://ditio.net/2010/05/02/javascript-date-difference-calculation/ resource external].&lt;br /&gt;
&lt;br /&gt;
Requieres 2 groups and &#039;group by group&#039; or &#039;question by question&#039; presentation.&lt;br /&gt;
&lt;br /&gt;
Group 1 (2 date questions)&lt;br /&gt;
*1st question - Question code: &amp;quot;DD&amp;quot;&lt;br /&gt;
*2nd question - Question code: &amp;quot;D2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Group 2&lt;br /&gt;
*1 numerical input question.&lt;br /&gt;
&lt;br /&gt;
This question retrieves the number of days between the 2 dates, and check if D2 is posterior than DD.&lt;br /&gt;
&lt;br /&gt;
All the requiered code have to be added in the source of this numerical question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
Adapted from http://ditio.net/2010/05/02/javascript-date-difference-calculation/&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var DateDiff = {&lt;br /&gt;
&lt;br /&gt;
   inDays: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var t2 = d2.getTime();&lt;br /&gt;
&lt;br /&gt;
       var t1 = d1.getTime();&lt;br /&gt;
&lt;br /&gt;
       return parseInt[[t2-t1)/(24*3600*1000]];&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inWeeks: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var t2 = d2.getTime();&lt;br /&gt;
&lt;br /&gt;
       var t1 = d1.getTime();&lt;br /&gt;
&lt;br /&gt;
       return parseInt[[t2-t1)/(24*3600*1000*7]];&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inMonths: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var d1Y = d1.getFullYear();&lt;br /&gt;
&lt;br /&gt;
       var d2Y = d2.getFullYear();&lt;br /&gt;
&lt;br /&gt;
       var d1M = d1.getMonth();&lt;br /&gt;
&lt;br /&gt;
       var d2M = d2.getMonth();&lt;br /&gt;
&lt;br /&gt;
       return (d2M+12*d2Y)-(d1M+12*d1Y);&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inYears: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       return d2.getFullYear()-d1.getFullYear();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
d1 = new Date({substr(DD,0,4)}, {substr(DD,5,2)}, {substr(DD,8,2)});&lt;br /&gt;
&lt;br /&gt;
d2 = new Date({substr(D2,0,4)}, {substr(D2,5,2)}, {substr(D2,8,2)});&lt;br /&gt;
&lt;br /&gt;
// Displays result&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;days&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inDays(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;weeks&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inWeeks(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;months&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inMonths(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;years&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inYears(d1, d2));&lt;br /&gt;
&lt;br /&gt;
// filled the numerical input with number of days (or nights)&lt;br /&gt;
&lt;br /&gt;
var nDays = +DateDiff.inDays(d1, d2);&lt;br /&gt;
&lt;br /&gt;
    jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;.numeric:eq(0) input.text&amp;quot;).val(nDays);&lt;br /&gt;
&lt;br /&gt;
               $(&amp;quot;.numeric:eq(0) input.text&amp;quot;).attr(&#039;readonly&#039;,&#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
// check if d2 &amp;gt; d1&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#movenextbtn&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#movesubmitbtn&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               if(nDays &amp;gt;= 0){&lt;br /&gt;
&lt;br /&gt;
       // automatic submit (uncomment if needed)&lt;br /&gt;
&lt;br /&gt;
               // document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
               // $(&#039;body&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
               else alert(&amp;quot;Check out date must be posterior than Check in\nPlease return to the previous page and edit your answers&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How to set minDate/maxDate based on other Datequestions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039; tested with Version 2.00+ Build 130708&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
QQ1 and QQ2 are the question identifiers. QQ2 gets as maxDate today and as minDate the date set in QQ1. The onClose event is needed because on document.ready the value of QQ1 is not yet known, although the value of today is.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        &#039;use strict&#039;;&lt;br /&gt;
        var qID1 = QQ1,&lt;br /&gt;
            qID2 = QQ2,&lt;br /&gt;
            q1 = $(&#039;#question&#039; + &#039;QQ1&#039; + &#039; .popupdate&#039;), &lt;br /&gt;
            q2 = $(&#039;#question&#039; + &#039;QQ2&#039; + &#039; .popupdate&#039;);&lt;br /&gt;
	&lt;br /&gt;
        //if q1 loses focus, its value is taken and used as minDate in q2   &lt;br /&gt;
        q1.datepicker(&amp;quot;option&amp;quot;, &amp;quot;onClose&amp;quot;, function (datum){&lt;br /&gt;
            q2.datepicker( &amp;quot;option&amp;quot;, &amp;quot;minDate&amp;quot;, datum );&lt;br /&gt;
        });&lt;br /&gt;
        //q2 gets today as its maxDate&lt;br /&gt;
        q2.datepicker( &#039;option&#039;, &#039;maxDate&#039;, new Date() );&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Remove Question Help if empty=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Version 2.00+ Build 130513&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Change your question.pstpl in your Template Editor so that the line looks like below. I&#039;ve added the ID tag help_{question_number}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;survey-question-help&amp;quot; id=help_{QUESTION_NUMBER}&amp;gt;{QUESTIONHELP}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add the following javascript at the end of question.pstpl. If the contents of the help tag is empty then hide the element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
$(document).ready(function(){&lt;br /&gt;
  if($(&#039;#help_{QUESTION_NUMBER}&#039;).is(&#039;:empty&#039;)){&lt;br /&gt;
  $(&#039;#help_{QUESTION_NUMBER}&#039;).hide();&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Implicit Association Test (IAT)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 2.0, IE 7-10, Firefox, Chrome, iPad&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to insert an IAT interface into an Array (Texts) question. The workaround prompts respondents to assign words or phrases using the &amp;quot;E&amp;quot; or &amp;quot;I&amp;quot; keys. In mobile devices, &amp;quot;E&amp;quot; and &amp;quot;I&amp;quot; buttons are provided.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Iat_1.png]]&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download a [[Media:Demo_IAT_Concept.zip|working template]] and [[Media:Demo_iat_concept.lss|working survey]].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
1) [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
&lt;br /&gt;
2) Create your Array (Texts) with sub-questions as follows:&amp;lt;br /&amp;gt;&lt;br /&gt;
- Y scale - all of your &amp;quot;attribut&amp;quot; words or phrases&amp;lt;br /&amp;gt;&lt;br /&gt;
- X scale - &amp;quot;Key Pressed&amp;quot; and &amp;quot;Elapsed Time (ms)&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Iat_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
3) Insert your association terms and the other text elements for the interface into the Question Help section as depicted below. The text strings must be separated with &amp;quot;double pipes&amp;quot; (||) and you will need to place them in the following order:&amp;lt;br /&amp;gt;&lt;br /&gt;
- Left association term&amp;lt;br /&amp;gt;&lt;br /&gt;
- Right association term&amp;lt;br /&amp;gt;&lt;br /&gt;
- Instructional text&amp;lt;br /&amp;gt;&lt;br /&gt;
- Finished text&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Iat_3.png]]&lt;br /&gt;
&lt;br /&gt;
4) Add the following to the end of template.js:&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// A plugin to insert an IAT interface&lt;br /&gt;
function implicitAssociation(el, showAnswers) {&lt;br /&gt;
		&lt;br /&gt;
	$(el).each(function() {&lt;br /&gt;
			&lt;br /&gt;
		var thisQuestion = $(this);&lt;br /&gt;
		var thisQuestionHelp = $(&#039;img[src$=&amp;quot;help.gif&amp;quot;]&#039;, thisQuestion).parent();&lt;br /&gt;
		var thisQuestionAnswers = $(&#039;table.question&#039;, thisQuestion).parent();&lt;br /&gt;
		var startTime = &#039;&#039;;&lt;br /&gt;
		var endTime = &#039;&#039;;	&lt;br /&gt;
		var agent = navigator.userAgent.toLowerCase();&lt;br /&gt;
		var mobile = false;&lt;br /&gt;
		if( /android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent) ) { // Mobile devices&lt;br /&gt;
			mobile = true;&lt;br /&gt;
		}&lt;br /&gt;
		mobile = true;&lt;br /&gt;
		&lt;br /&gt;
		// Some classes&lt;br /&gt;
		$(thisQuestion).addClass(&#039;iatQuestion&#039;);&lt;br /&gt;
		$(&#039;.subquestion-list&#039;).addClass(&#039;unanswered&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Hide the question help element&lt;br /&gt;
		$(thisQuestionHelp).hide();&lt;br /&gt;
		&lt;br /&gt;
		// Hide the answers&lt;br /&gt;
		if(showAnswers != true) {&lt;br /&gt;
			$(&#039;table.question&#039;, thisQuestion).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Insert IAT display&lt;br /&gt;
		var iatTexts = $(thisQuestionHelp).text().split(&#039;||&#039;);&lt;br /&gt;
		var iatDisplayHTML = &#039;&amp;lt;div class=&amp;quot;iatWrapper&amp;quot;&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatLeftLabel&amp;quot;&amp;gt;&#039;+iatTexts[0]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatRightLabel&amp;quot;&amp;gt;&#039;+iatTexts[1]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatWord&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatInstructions&amp;quot;&amp;gt;&#039;+iatTexts[2]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;div class=&amp;quot;iatMobileButtonWrapper&amp;quot;&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatButton iatLeftButton&amp;quot;&amp;gt;E&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatButton iatRightButton&amp;quot;&amp;gt;I&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div style=&amp;quot;width:100%; clear:both;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
		$(thisQuestionAnswers).prepend(iatDisplayHTML);&lt;br /&gt;
		&lt;br /&gt;
		// Show a word&lt;br /&gt;
		function iatShowWord() {&lt;br /&gt;
			$(&#039;div.iatWord&#039;, thisQuestion).text($(&#039;.subquestion-list.unanswered:first .answertext&#039;, thisQuestion).text());&lt;br /&gt;
			startTime = new Date();&lt;br /&gt;
			&lt;br /&gt;
			$(document).bind(&#039;keypress.iatKeypress&#039;, function(e) {&lt;br /&gt;
				if(e.which == 101 || e.which == 105) {&lt;br /&gt;
					var thisRow = $(&#039;.subquestion-list.unanswered:eq(0)&#039;, thisQuestion);&lt;br /&gt;
					$(thisRow).removeClass(&#039;unanswered&#039;);&lt;br /&gt;
					endTime = new Date();&lt;br /&gt;
					$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(1)&#039;, thisRow).val(endTime.valueOf() - startTime.valueOf());&lt;br /&gt;
					if(e.which == 101) {&lt;br /&gt;
						$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val(&#039;E&#039;);&lt;br /&gt;
					}&lt;br /&gt;
					else {&lt;br /&gt;
						$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val(&#039;I&#039;);&lt;br /&gt;
					}&lt;br /&gt;
					$(document).unbind(&#039;keypress.iatKeypress&#039;);&lt;br /&gt;
					if($(&#039;.subquestion-list.unanswered&#039;, thisQuestion).length &amp;gt; 0) {&lt;br /&gt;
						iatShowWord();&lt;br /&gt;
					}&lt;br /&gt;
					else {&lt;br /&gt;
						$(&#039;.iatLeftLabel, .iatWord, .iatRightLabel, .iatInstructions&#039;, thisQuestion).fadeOut(&#039;slow&#039;, function() {&lt;br /&gt;
							$(&#039;div.iatWord&#039;, thisQuestion).text(iatTexts[3]);&lt;br /&gt;
							$(&#039;.iatWord&#039;, thisQuestion).addClass(&#039;done&#039;).fadeIn(&#039;slow&#039;);&lt;br /&gt;
						});&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		function iatShowWordMobile() {&lt;br /&gt;
			$(&#039;div.iatWord&#039;, thisQuestion).text($(&#039;.subquestion-list.unanswered:first .answertext&#039;, thisQuestion).text());&lt;br /&gt;
			startTime = new Date();&lt;br /&gt;
			&lt;br /&gt;
			$(&#039;.iatButton&#039;, thisQuestion).bind(&#039;click.iatButtonClick&#039;, function(e) {&lt;br /&gt;
				var thisRow = $(&#039;.subquestion-list.unanswered:eq(0)&#039;, thisQuestion);&lt;br /&gt;
				$(thisRow).removeClass(&#039;unanswered&#039;);&lt;br /&gt;
				endTime = new Date();&lt;br /&gt;
				$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(1)&#039;, thisRow).val(endTime.valueOf() - startTime.valueOf());&lt;br /&gt;
				$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val($(this).text());&lt;br /&gt;
				$(&#039;.iatButton&#039;, thisQuestion).unbind(&#039;click.iatButtonClick&#039;);&lt;br /&gt;
				if($(&#039;.subquestion-list.unanswered&#039;, thisQuestion).length &amp;gt; 0) {&lt;br /&gt;
					iatShowWordMobile();&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					$(&#039;.iatLeftLabel, .iatWord, .iatRightLabel, .iatInstructions, .iatMobileButtonWrapper&#039;, thisQuestion).fadeOut(&#039;slow&#039;, function() {&lt;br /&gt;
						$(&#039;div.iatWord&#039;, thisQuestion).text(iatTexts[3]);&lt;br /&gt;
						$(&#039;.iatWord&#039;, thisQuestion).addClass(&#039;done&#039;).fadeIn(&#039;slow&#039;);&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Start the IAT display&lt;br /&gt;
		if(mobile == true) { // Mobile devices&lt;br /&gt;
			$(&#039;.iatMobileButtonWrapper&#039;, thisQuestion).show();&lt;br /&gt;
			$(&#039;.iatButton&#039;, thisQuestion).bind(&#039;click.iatStartMobile&#039;, function(e) {&lt;br /&gt;
				$(&#039;.iatButton&#039;, thisQuestion).unbind(&#039;click.iatStartMobile&#039;);&lt;br /&gt;
				iatShowWordMobile();&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(document).bind(&#039;keypress.iatStart&#039;, function(e) { // Non-mobile devices&lt;br /&gt;
				if(e.which == 101 || e.which == 105) {&lt;br /&gt;
					$(document).unbind(&#039;keypress.iatStart&#039;);&lt;br /&gt;
					iatShowWord();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;5) Add the following to the end of template.css:&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
/* IAT questions */&lt;br /&gt;
&lt;br /&gt;
.iatWrapper {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	width: 600px;&lt;br /&gt;
	height: 300px;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
	background-color: #000000;&lt;br /&gt;
	font-size: 21px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatLeftLabel {&lt;br /&gt;
	float: left;&lt;br /&gt;
	padding: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatRightLabel {&lt;br /&gt;
	float: right;&lt;br /&gt;
	padding: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatWord {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	top: 35%;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	font-size: 36px;&lt;br /&gt;
	color:#0F0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatWord.done {&lt;br /&gt;
	color:#FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatInstructions {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	bottom: 0px;&lt;br /&gt;
	padding-bottom: 10px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatMobileButtonWrapper {&lt;br /&gt;
	display: none;&lt;br /&gt;
	position: relative;&lt;br /&gt;
	width: 600px;&lt;br /&gt;
	font-size: 36px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatButton {&lt;br /&gt;
	float: left;&lt;br /&gt;
	margin: 20px;&lt;br /&gt;
	width: 100px;&lt;br /&gt;
	padding: 2px 0 5px 0;&lt;br /&gt;
	border: 5px solid #999;&lt;br /&gt;
	-moz-border-radius: 10px;&lt;br /&gt;
	-webkit-border-radius: 10px;&lt;br /&gt;
	-khtml-border-radius: 10px;&lt;br /&gt;
	border-radius: 10px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	line-height: normal;&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatLeftButton {&lt;br /&gt;
	float: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatRightButton {&lt;br /&gt;
	float: right;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;6) To apply the plugin, add one of the two scripts below to the question source:&amp;lt;br /&amp;gt;&lt;br /&gt;
- With hidden answer table (for normally activated survey)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Apply the IAT plugin to this question&lt;br /&gt;
		implicitAssociation(&#039;#question{QID}&#039;);&lt;br /&gt;
	});	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
- With visible answer table (for testing purposes)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Apply the IAT plugin to this question&lt;br /&gt;
		implicitAssociation(&#039;#question{QID}&#039;, true);&lt;br /&gt;
	});	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Make multiple choice easier=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with Version 2.00 in Chrome, FF, Safar, IE&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The problem:&lt;br /&gt;
We often have multiple choice question, where the user has to select 4 elements out of 78 possible answers or 3 out of 25 and so on.&lt;br /&gt;
If we use pen and paper version for this questions, we noticed that the participants go through the whole list and if an answer doesn&#039;t suit on the first sight, they cross it out.&lt;br /&gt;
&lt;br /&gt;
The solution:&lt;br /&gt;
The script gives the participant the possibility to cross out this answers in a digital way. The script adds a small &amp;quot;X&amp;quot; before the checkbox. When it is clicked, the label text of the checkbox turns grey.&lt;br /&gt;
(see the attached screenshot for an example)&lt;br /&gt;
&lt;br /&gt;
Here is the script, just add it to help text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
* Small script that adds a &amp;quot;X&amp;quot; before a checkbox. &lt;br /&gt;
* On click the text color of the label of the checkbox turns grey&lt;br /&gt;
* If the user has to choose some answers from many options, he can &amp;quot;delete&amp;quot; answers, that on first sight looks wrong&lt;br /&gt;
* Add the script to the question in Limesurvey (for example within the source code of the help text)&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
//Define the X (standard is a X in capitals)&lt;br /&gt;
var x = &amp;quot;X&amp;quot;;&lt;br /&gt;
css_class = &amp;quot;x&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
/*&lt;br /&gt;
* Define the style of the X&lt;br /&gt;
* Of course you can define the style in the stylesheet - if so, the script ignores the following settings&lt;br /&gt;
* If there is a style, than set style var to 1&lt;br /&gt;
*/&lt;br /&gt;
var style = 0;&lt;br /&gt;
var size = &amp;quot;12px&amp;quot;;&lt;br /&gt;
var weight = &amp;quot;bold&amp;quot;;&lt;br /&gt;
var color = &amp;quot;red&amp;quot;;&lt;br /&gt;
var cursor = &amp;quot;pointer&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
//element type - standard is a span element&lt;br /&gt;
var type = &amp;quot;span&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
//Define the new font color of the checkbox label&lt;br /&gt;
label_color = &amp;quot;#bfbfbf&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
//End of configuration - start of the function&lt;br /&gt;
 &lt;br /&gt;
//Define the element that is added&lt;br /&gt;
if(style == 1) {&lt;br /&gt;
	ele = &amp;quot;&amp;lt;&amp;quot;+type+&amp;quot; class=&#039;&amp;quot;+css_class+&amp;quot;&#039;&amp;gt;&amp;quot;+x+&amp;quot;&amp;lt;/&amp;quot;+type+&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
	ele = &amp;quot;&amp;lt;&amp;quot;+type+&amp;quot; class=&#039;&amp;quot;+css_class+&amp;quot;&#039; style=&#039;font-size:&amp;quot;+size+&amp;quot;; font-weight:&amp;quot;+weight+&amp;quot;; color:&amp;quot;+color+&amp;quot;; cursor:&amp;quot;+cursor+&amp;quot;;&#039;&amp;gt;&amp;quot;+x+&amp;quot;&amp;lt;/&amp;quot;+type+&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
//Get the standard font-color of the used style&lt;br /&gt;
st_color = $(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
//insert the X before the checkboxes&lt;br /&gt;
$(document).ready(function() { &lt;br /&gt;
	$(&amp;quot;li&amp;quot;).each(function(){&lt;br /&gt;
		$(this).prepend(ele);&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
//bind an eventhandler on the X (delegate is used, because Limesurvey uses an old jQuery version)&lt;br /&gt;
var css_class_c = &amp;quot;.&amp;quot;+css_class;&lt;br /&gt;
$(document).delegate(css_class_c,&amp;quot;click&amp;quot;,function() {&lt;br /&gt;
	var color_check = $(this).siblings(&amp;quot;label&amp;quot;).data(&amp;quot;color&amp;quot;);&lt;br /&gt;
	if(color_check != &amp;quot;true&amp;quot;) {&lt;br /&gt;
    	$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,label_color).data(&amp;quot;color&amp;quot;,&amp;quot;true&amp;quot;);&lt;br /&gt;
    	$(this).siblings(&#039;input&#039;).attr(&#039;checked&#039;, false);&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,st_color).data(&amp;quot;color&amp;quot;,&amp;quot;false&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
$(&amp;quot;.checkbox&amp;quot;).click(function () {&lt;br /&gt;
	$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,st_color).data(&amp;quot;color&amp;quot;,&amp;quot;false&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Workarounds:_Manipulating_a_survey_at_runtime_using_Javascript&amp;diff=59823</id>
		<title>Workarounds: Manipulating a survey at runtime using Javascript</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Workarounds:_Manipulating_a_survey_at_runtime_using_Javascript&amp;diff=59823"/>
		<updated>2014-01-16T03:55:18Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: /* Drag and Drop Ranking - Version 1.90 to 1.92 */  - Fix for later versions of 1.91+ where ranked responses were not saved&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Often you want to manipulate certain elements of a survey at runtime. The only solution without touching the source code is to use JavaScript or jQuery which is shipped with LimeSurvey. Here are some examples to hide and style elements, validate user input or do calculations at runtime.&lt;br /&gt;
&lt;br /&gt;
Other workarounds can be found at&lt;br /&gt;
* [[Workarounds: Survey behaviour]]&lt;br /&gt;
* [[Workarounds: Question design, layout and templating]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;lt;center&amp;gt;&amp;lt;br /&amp;gt;&#039;&#039;&#039;Please keep in mind that these workarounds are not official LimeSurvey extensions - they are solutions that users have created for themselves.&amp;lt;br /&amp;gt;&amp;lt;span style=&#039;color:#EE0000,#FFFFFF&#039;&amp;gt;Therefore LimeSurvey can&#039;t offer guarantees or support for these solutions.&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;If you have questions, please contact the users that, thankfully, shared their solutions with the community.&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/center&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note:  Version 1.92 implements many new features that make some existing workarounds obsolete.  You can continue to use existing workarounds, but may want to consider switching over to using the new features (since those new features are officially supported, and the workarounds are not).  Please review below for details of which are no longer needed.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Also Note:  Version 1.92&#039;s Expression Manager (EM) may cause some of these work-arounds to fail.  Any custom javascript included as a .js file will be fine.  However, if you in-line your JavaScript code, you must make sure that you have a space after every opening (left) curly brace, and a space before every closing (right) curly brace.  Otherwise, EM will think that the content between the curly braces is something it should parse and understand.  I have fixed all of the work-arounds below that can be fixed (many did not follow those rules).  However, some will continue to break.  If a work-around contains a regular expression which contains curly braces (to indicate a range of repeats of a sub-expression), EM will try to process those curly braces, and thus break your regular expression.  Strategies to continue to support that work-around functionality are discussed below.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;add&#039;&#039; a javascript workaround solution to this Wiki page?=&lt;br /&gt;
&lt;br /&gt;
Well, this is pretty easy. Click the edit icon and create your own headline within the javascript section starting with &amp;quot;&#039;&#039;&#039;!&#039;&#039;&#039;&amp;quot;. Then add a short note about the version you have used when creating your workaround, you can copy/paste this code snippet &amp;lt;nowiki&amp;gt;&#039;&#039;Tested with: (enter LimeSurvey version and maybe browser)&#039;&#039;&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Finally it&#039;s imported to mark all your code with code tags, other wise you might break this page.&lt;br /&gt;
*Start tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
*End tag: &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;use&#039;&#039; Script (eg. JavaScript etc.) in LimeSurvey?=&lt;br /&gt;
&lt;br /&gt;
To use JavaScript within LimeSurvey, the XSS filter must be turned off and the code inserted in the source of a question or a group description.&lt;br /&gt;
*Go to Global settings --&amp;gt; Security and set &amp;quot;Filter HTML for XSS&amp;quot; to &amp;quot;Off&amp;quot;.&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=Adding+A+Question Add a new question]&lt;br /&gt;
* Edit the question and click the &amp;quot;Source&amp;quot; button in the editor toolbar:&lt;br /&gt;
&lt;br /&gt;
   [[File:editor_1.gif]]&lt;br /&gt;
* Enter your script after the question text:&lt;br /&gt;
&lt;br /&gt;
   [[File:editor_2.gif]]&lt;br /&gt;
* Save the question&lt;br /&gt;
&lt;br /&gt;
A simple test to see if JavaScript is enabled is to echo an alert. Use this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good practice to use the jQuery $(document).ready function to prevent the code from executing until the page is fully loaded:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       alert(&amp;quot;Test!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is also good practice to use jslint.com to get a good layout and design (e.q. no cluttering of name space)&lt;br /&gt;
&lt;br /&gt;
=Sum up input values using Javascript=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the sum() function in [[Expression Manager|Expression Manager]].  See this [[Expression Manager HowTos#Calculate assessment values at runtime and store the results in the survey data|HowTo example]].&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Starting in  Version 1.92, you also do no longer need to use SGQA (e.g. 45251X1X5) identifiers. Instead the code &amp;lt;code&amp;gt;{SGQ}&amp;lt;/code&amp;gt; will automatically replaced by the current questions SGQA-codes.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is from a survey that is a invitation to a longer party, when the user clicks to the next page, the calculated results will be shown.&lt;br /&gt;
&lt;br /&gt;
If you wonder what the {INSERTANS:1X6X12} stuff is, look at [http://docs.limesurvey.org/tiki-index.php?page=SGQA+Identifier SGQA identifier] and [[Adding a question#Information from previous answers|Using information from previous answers]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: left&amp;quot;&amp;gt;These are your answers:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;u&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;script LANGUAGE=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
partyprice = 3;&lt;br /&gt;
&lt;br /&gt;
beadclothprice = 3;&lt;br /&gt;
&lt;br /&gt;
breakfastprice = 7;&lt;br /&gt;
&lt;br /&gt;
lunchprice = 8;&lt;br /&gt;
&lt;br /&gt;
dinnerprice = 10;&lt;br /&gt;
&lt;br /&gt;
foodtotal = 0;&lt;br /&gt;
&lt;br /&gt;
var isreallytrue = &amp;quot;Yes&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var noanswer = &amp;quot;No answer&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
document.write( &amp;quot;Can you come? = {INSERTANS:45251X1X1}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:45251X1X1}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X3}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X3}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
   partypeople = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   partytotal = partyprice * partypeople;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;It&#039;s {INSERTANS:45251X1X3} persons who will come = &amp;quot; + partytotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X4}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X4}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   beadcloths = parseInt(answer);&lt;br /&gt;
&lt;br /&gt;
   beadclothtotal = beadclothprice * beadcloths;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;You want to borrow {INSERTANS:45251X1X4} beadcloths = &amp;quot; + beadclothtotal + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there thursday? = {INSERTANS:45251X1X5}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;On friday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X71}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X71}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   breakfastfriday = parseInt(answer) * breakfastprice;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X72}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X72}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   lunchfriday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X73}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
   else { answer = &amp;quot;{INSERTANS:45251X1X73}&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
   dinnerfriday = parseInt(answer)* dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnerfriday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   foodtotal = breakfastfriday + lunchfriday + dinnerfriday;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there saturday? = {INSERTANS:45251X1X8}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X8}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On saturday you will have these meals: &amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X91}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X91}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       breakfastsaturday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write(&amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X92}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X92}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       lunchsaturday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X93}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X93}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       dinnersaturday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersaturday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsaturday + lunchsaturday + dinnersaturday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;Will you be there sunday? = {INSERTANS:45251X1X10}&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   if (&amp;quot;{INSERTANS:45251X1X10}&amp;quot; == isreallytrue )&lt;br /&gt;
&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;On sunday you will have these meals: &amp;lt;br&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X111}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X111}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       breakfastsunday = parseInt(answer) * breakfastprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; breakfeasts = &amp;quot; + breakfastsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot;  );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X112}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X112}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       lunchsunday = parseInt(answer) * lunchprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; lunches = &amp;quot; + lunchsunday + &amp;quot;&amp;amp;euro;&amp;lt;BR&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       if (&amp;quot;{INSERTANS:45251X1X113}&amp;quot;== noanswer) { answer = 0; }&lt;br /&gt;
&lt;br /&gt;
       else { answer = &amp;quot;{INSERTANS:45251X1X113}&amp;quot;; }&lt;br /&gt;
&lt;br /&gt;
       dinnersunday = parseInt(answer) * dinnerprice ;&lt;br /&gt;
&lt;br /&gt;
       document.write( &amp;quot;&#039;&#039;&#039;_ &amp;quot; + answer + &amp;quot; dinners = &amp;quot; + dinnersunday + &amp;quot;&amp;amp;euro;&amp;lt;p&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
       foodtotal = foodtotal + breakfastsunday + lunchsunday + dinnersunday;&lt;br /&gt;
&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
   total = partytotal + beadclothtotal + foodtotal;&lt;br /&gt;
&lt;br /&gt;
   document.write( &amp;quot;&amp;lt;h3&amp;gt;In total it will cost you &amp;quot; + total + &amp;quot;&amp;amp;euro;&amp;lt;/h3&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   Put that sum in this bank account 1234 5678 9012&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/SCRIPT&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Question Validation=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the min/max/equals_num_value attributes (to validate sums), or the em_validation_q function, which lets you refer to other variables when you validate the current question [[Expression Manager|Expression Manager]].  Such validations also work on the current page, and properly handle array_filter and cascading relevance.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround is in case you need to do some validation involving more than one question, it implies a very little JavaScript programming and the use of SGQA Identifiers; this should work on almost any version of LimeSurvey.&lt;br /&gt;
&lt;br /&gt;
Is easy to explain with an example, we need to do a survey of the percentage of males and females and we want to be sure that the sum is 100, to do this follow this steps (the necessary data that is not indicated in these instructions are not important i.e. question codes, etc.):&lt;br /&gt;
#Create a new survey of type &amp;quot;group by group&amp;quot;, set the &amp;quot;Show |&amp;lt;&amp;lt; Prev| button&amp;quot; to yes and note the SID.&lt;br /&gt;
#Add a new group called &amp;quot;Group 1&amp;quot; and note the GID.&lt;br /&gt;
#Add a new question &amp;quot;Percent of males&amp;quot; of type &amp;quot;numeric&amp;quot;, make it mandatory and note the QID (we will refer to this as QID1).&lt;br /&gt;
#Add a new question &amp;quot;Percent of females&amp;quot; of type &amp;quot;numeric&amp;quot;, make it mandatory and note the QID (we will refer to this as QID2).&lt;br /&gt;
#Add a new group called &amp;quot;Group 2&amp;quot;&lt;br /&gt;
#Add a new non mandatory question, here is the trick the question text has to be (be sure to replace the SID, GID, QID1 and QID2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function validation()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   if [[{INSERTANS:SIDXGIDXQID1}+{INSERTANS:SIDXGIDXQID2}) != 100)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     alert(&amp;quot;Your responses don&#039;t sum 100! Check them&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.move.value = &#039;movelast&#039;;&lt;br /&gt;
&lt;br /&gt;
     document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But this will show shortly the question and will jump to the end page, a little weird for the survey taker but works.&lt;br /&gt;
&lt;br /&gt;
This is a proof of concept, and may have some problems, please if you notice something or improve it send me an e-mail to leochaton-limesurvey at yahoo dot com.&lt;br /&gt;
&lt;br /&gt;
This will work for 2 questions that you want to be the same.  Works well for email and confirm email questions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 function validation() {&lt;br /&gt;
&lt;br /&gt;
 if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; != &amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
    alert(&amp;quot;Your responses don&#039;t match Check them&amp;quot;); document.limesurvey.move.value = &#039;moveprev&#039;;&lt;br /&gt;
&lt;br /&gt;
    document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 setTimeout(&amp;quot;validation()&amp;quot;,250);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Alternate exit=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using the same idea of the previous post, you can implement an alternate exit of your survey.&lt;br /&gt;
&lt;br /&gt;
This script should be in the first question to be displayed in a next page after the question that should trigger the alternate exit. In this example the question that trigger the alternate exit is a Yes/No question, if the user chooses no, he is redirected to another page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;{INSERTANS:SIDXGIDXQID}&amp;quot; == &amp;quot;No&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  window.location=&amp;quot;http://www.limesurvey.org&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Custom onload function=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: &#039;All browsers&#039;, LimeSurvey 1.70 and up&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
&lt;br /&gt;
This simple workaround describes how to &#039;&#039;&#039;add a custom Javascript code&#039;&#039;&#039; that is triggered right after the page is loaded. It may have numerous applications, especially when you deal with a custom JS/HTML code. It may be used to hide form elements (&amp;lt;input&amp;gt;  tags), make them read-only, display alert messages, etc.&lt;br /&gt;
&lt;br /&gt;
To run any Javascript code right after page load use the Query ready() function. It will be executed when the page is being loaded. For example when you add the following code to one of your question definitions...:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
       alert(&#039;onload alert!&#039;);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...it will display a pop-up message immediately after the page has been loaded.&lt;br /&gt;
&lt;br /&gt;
Some of the applications of this trick I&#039;ve explored are:&lt;br /&gt;
&lt;br /&gt;
a) Hiding the form elements by calling in your Custom_On_Load:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: As of svn build 9755, you can now dynamically reference the questions input fields by using the {SGQ} keyword. You can rewrite the previous example like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer{SGQ}&amp;quot;).style.display=&#039;none&#039;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
this makes it a little easier when exporting surveys, so you don&#039;t have to worry about manually entering each questions SurveyGroupQuestion ID.&lt;br /&gt;
&lt;br /&gt;
b) Making the elements read only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;document.getElementById(&amp;quot;answer73166X16X54&amp;quot;).readOnly=true;&amp;lt;/syntaxhighlight&amp;gt; where the &amp;quot;answer73166X16X54&amp;quot; structure has been described in one of other workarounds above.&lt;br /&gt;
&lt;br /&gt;
c) For Hiding by a lot of elements by calling in your Customer_On_Load&lt;br /&gt;
&lt;br /&gt;
jQuery searchs in html document for input-fields with radio type, if his answer text empty then do the display css set to none.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
           function() {&lt;br /&gt;
&lt;br /&gt;
             jQuery(&#039;input:radio&#039;).each(&lt;br /&gt;
&lt;br /&gt;
               function() {&lt;br /&gt;
&lt;br /&gt;
                 var s = jQuery(this);&lt;br /&gt;
&lt;br /&gt;
                 var c = s.parent().children(&#039;.answertext&#039;);&lt;br /&gt;
&lt;br /&gt;
                 for(var i=0; i &amp;lt; c.length; i++) {&lt;br /&gt;
&lt;br /&gt;
                   var a = jQuery(c[i]]);&lt;br /&gt;
&lt;br /&gt;
                   if(this.id &amp;lt;/u&amp;gt; a.attr(&#039;for&#039;) &amp;amp;&amp;amp; a.text() == &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
                     s.css({ &#039;display&#039; : &#039;none&#039; });&lt;br /&gt;
&lt;br /&gt;
                     a.css({ &#039;display&#039; : &#039;none&#039; });&lt;br /&gt;
&lt;br /&gt;
                     break;&lt;br /&gt;
&lt;br /&gt;
                   }&lt;br /&gt;
&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
             )&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
         );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advanced usage==&lt;br /&gt;
&lt;br /&gt;
If you want to place global Javascript code using the above jQuery(document).ready function then the best place to do this is the template javascript file template.js. You can edit this file using the template editor. Please be aware that placing it in the template javascript file will make the function available to all surveys using that template. If needed just create a new template copy for your survey.&lt;br /&gt;
&lt;br /&gt;
Alternatively you can place the jQuery(document).ready function in the group description to make a Javascript function only available to a certain question group.&lt;br /&gt;
&lt;br /&gt;
==Language-specific Javascript code==&lt;br /&gt;
&lt;br /&gt;
There is an easy way to find out the current language and execute according Javascript using jQuery: The &amp;lt;html&amp;gt; tag of any survey pages contains an &#039;lang&#039; attribute which holds the current language code. You can read that language code by using the followin code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
       languagecode=$(&#039;html&#039;).attr(&#039;lang&#039;);&lt;br /&gt;
&lt;br /&gt;
       alert(&#039;This is the current language code: &#039;+languagecode);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an English survey the above code would show a messagebox with &amp;quot;This is the current language code: en&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Custom onload function in multi-language survey=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use custom onload functions, as above, in multi-language surveys you must define the functions in the question source for &#039;&#039;&#039;all&#039;&#039;&#039; languages.&lt;br /&gt;
&lt;br /&gt;
While this initially seems to be a bit tedious, it actually can be useful - you can alter your onload functions depending on the language in use. For example, you can dynamically display alerts or element contents in the current language.&lt;br /&gt;
&lt;br /&gt;
=Skipping the welcome page=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85 (second code snippet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: As of version 1.91, there is a survey option letting you skip the welcome page, so this workaround is not needed.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 1:&#039;&#039;&#039; Include this Javascript in your welcome template, in the file welcome.pstpl for all welcome page, or in the source of the welcome text for one survey:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function($) {&lt;br /&gt;
&lt;br /&gt;
document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
document.limesurvey.submit(); });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will reproduce the onclick event of the submit button and submit the form.&lt;br /&gt;
&lt;br /&gt;
Drawback of course is that users will see the page flashing up.&lt;br /&gt;
&lt;br /&gt;
Therefore, you may want to announce &amp;quot;... loading survey ...&amp;quot; as a description of your welcome page (in the admin interface when creating the survey), to pretend loading something big.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution 2:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function custom_on_load(){&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.move.value = &#039;movenext&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
window.setTimeout( &#039;custom_on_load()&#039;,1);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Filter answers of a question with the answer of another=&lt;br /&gt;
&lt;br /&gt;
===Method 1===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.70 - 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the the array_filter attribute, or relevance equations in general.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to filter the answer of a question with another answer, you can use this workaround.&lt;br /&gt;
&lt;br /&gt;
First, use answer code like that: XX for the first question, and XXYYY for the second one.&lt;br /&gt;
&lt;br /&gt;
Answer of the second question filter if the 2 first letters are the answer of the first question.&lt;br /&gt;
&lt;br /&gt;
We use 1000X1X1 and 1000X1X2 for the example, question had to be on separate page (question by question for example).The second question had to be a dropdown list (we can do similar workaround, but droplis is the best). You can do this using JQuery.  It leaves the answer in the select box, but disables it.  You could also replace &amp;quot;disable&amp;quot; with &amp;quot;remove&amp;quot; to get rid of it altogether.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var previousQuestionAnswer = &amp;quot;{INSERTANS:1000X1X1}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
var currentQuestionID = &amp;quot;#answer1000X1X1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // See if the answer for the previous question matches an answer in the current question&lt;br /&gt;
&lt;br /&gt;
   // (other than &#039;No Answer&#039;)&lt;br /&gt;
&lt;br /&gt;
   // If so, disable it.&lt;br /&gt;
&lt;br /&gt;
   if (previousQuestionAnswer!=&#039;No Answer&#039;) {&lt;br /&gt;
&lt;br /&gt;
       $(currentQuestionID).children().each(function(index, Element)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           if ($(this).attr(&#039;text&#039;) == previousQuestionAnswer)&lt;br /&gt;
&lt;br /&gt;
               { $(this).attr(&#039;disabled&#039;, true); }&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       );}&lt;br /&gt;
&lt;br /&gt;
}); // End of JQuery ready function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Method 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with 1.92 + Firefox 9.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you have a country, state, and city set of questions (or similar), you could code answer options as:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1 Country&#039;&#039;&#039; &#039;&#039;Single choice list (ratio, dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
X country#&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2 State&#039;&#039;&#039; &#039;&#039;Single choice list (dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
XY state#&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3 City&#039;&#039;&#039; &#039;&#039;Single choice list (dropdown)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
XYZZ city#&lt;br /&gt;
&lt;br /&gt;
Now you must put the following Javascript code in the source of question 2 (State):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Get the countryCode (first character of the country)&lt;br /&gt;
&lt;br /&gt;
       var countryCode = &#039;{INSERTANS:1000X1X1}&#039;.substr(0, 1).toUpperCase();&lt;br /&gt;
&lt;br /&gt;
       // Loop through all dropdown options and remove those with codes not starting with the countryCode&lt;br /&gt;
&lt;br /&gt;
       $(&#039;select[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;answer&amp;quot;] option&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
           if($(this).attr(&#039;value&#039;)  &amp;amp;&amp;amp; $(this).attr(&#039;value&#039;).substr(0, 1).toUpperCase() != countryCode) {&lt;br /&gt;
&lt;br /&gt;
               $(this).remove();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the following code in the source of question 3 (City):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Get the stateCode (two first characters of the state)&lt;br /&gt;
&lt;br /&gt;
       var stateCode = &#039;{INSERTANS:1000X1X2}&#039;.substr(0, 2).toUpperCase();&lt;br /&gt;
&lt;br /&gt;
       // Loop through all dropdown options and remove those with codes not starting with the stateCode&lt;br /&gt;
&lt;br /&gt;
       $(&#039;select[id&amp;lt;/div&amp;gt;=&amp;quot;answer&amp;quot;] option&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
           if($(this).attr(&#039;value&#039;)  &amp;amp;&amp;amp; $(this).attr(&#039;value&#039;).substr(0, 2).toUpperCase() != stateCode) {&lt;br /&gt;
&lt;br /&gt;
               $(this).remove();&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
       });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each question must be in different pages of survey to work, i.e. in a question by question survey, or in diferent groups in a group by group survey.&lt;br /&gt;
&lt;br /&gt;
Note that if you choose a two characters answer option code in the State question, i.e. a XYY answer option code, you must change the &#039;&#039;substr(0, 2)&#039;&#039; part of code in question 3 to &#039;&#039;substr(0, 3)&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Filter answers of a multiple numeric type question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the the array_filter attribute, or relevance equations in general.  In 1.92, array_filter works with all questions that have sub-questions (e.g. also works for multiple numeric and multiple short text).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to filter a question of type &amp;quot;multiple numeric&amp;quot;, you have to modify the workaround.&lt;br /&gt;
&lt;br /&gt;
Note that this workaround assumes that the code for each of the subquestions are a numeric sequence 1,2,3...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
   // Match elements with labels using htmlFor and a loop&lt;br /&gt;
&lt;br /&gt;
   var labels = document.getElementsByTagName(&#039;LABEL&#039;);&lt;br /&gt;
&lt;br /&gt;
   for (var i = 0; i &amp;lt; labels.length; i++) {&lt;br /&gt;
&lt;br /&gt;
       if (labels[i].htmlFor != &#039;&#039;) {&lt;br /&gt;
&lt;br /&gt;
            var elem = document.getElementById(labels[i].htmlFor);&lt;br /&gt;
&lt;br /&gt;
            if (elem)&lt;br /&gt;
&lt;br /&gt;
               elem.label = labels[i];&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   var answerFilter=&amp;quot;{INSERTANS:96553X63X759}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   for (i=0; i&amp;lt;30; i++){&lt;br /&gt;
&lt;br /&gt;
     var iLabel = document.getElementById(&#039;answer96553X63X760&#039;+(i+1]].label.innerHTML;&lt;br /&gt;
&lt;br /&gt;
     if (answerFilter.search(iLabel) == -1){&lt;br /&gt;
&lt;br /&gt;
       // Hide element&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#question760&#039;).find(&#039;li&#039;).eq(i).hide();&lt;br /&gt;
&lt;br /&gt;
       // Set value of hidden elements to zero&lt;br /&gt;
&lt;br /&gt;
       document.getElementById(&#039;answer96553X63X760&#039;+(i+1)).value = 0;&lt;br /&gt;
&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
 });&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use an answer to prefill another question (default value)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.72&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;And tested with: 1.91+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do using the enhanced defaults feature, which lets you pre-fill most question types with default values.  In 1.91, you could set defaults for list and multiple choice questions.  In 1.92, you can set defaults for any text-entry question too.  Moreover, the defaults can be [[Expression Manager|Expression Manager]] compatible equations or tailored text.  Finally, with 1.92, defaults are properly managed even when set on the same page.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround gives you the ablility to use an answer to fill the default value for another question. It&#039;s explained for free text question type but can be adapted for another question type.&lt;br /&gt;
&lt;br /&gt;
We use SGQA identifier. For example, we use SGQA 1000X10X20 and 1000X10X21 to prefill 1000X11X30 and 1000X11X31. For the script to work, the question has to be on a different page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X11X30&#039;).val(&#039;{INSERTANS:1000X10X20}&#039;);&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X11X31&#039;).val(&#039;{INSERTANS:1000X10X21}&#039;);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want use two times the value of an integer input, you can also use this to prefill a question that you hide via CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
 $(&#039;#answer1000X2X2&#039;).val(parseInt(&#039;{INSERTANS:1000X1X1}&#039;)*2);&lt;br /&gt;
&lt;br /&gt;
 $(&amp;quot;#question2&amp;quot;).hide();&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use {INSERTANS:1000X2X2} for giving you twice the value of the user input from question 1.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Sum=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, this is easier to do with [[Expression Manager|Expression Manager]] using the sum() function.  Not only will sums be dynamic, but they wille exclude irrelevant values, so you can array_filter a multiple numeric question and get the sum of just the answers that are visible.  This [[Expression Manager HowTos#Calculate assessment values at runtime and store the results in the survey data|HowTo example]] demonstrates the dynamic sum feature.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Also note, as of version 1.92, the following workaround will fail, since it includes a a regular expression containing curly braces.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script is used with a &amp;quot;Multiple Options&amp;quot; type question calculate a total price based on how which checkboxes are selected. The prices are listed as part of the answer. The answers are set up like this: &amp;quot;USB Mouse ($20)&amp;quot;. The script uses the number between the &amp;quot;($&amp;quot; and the &amp;quot;)&amp;quot; as the price for that item. You can adapt the script to if you need to change the currency or need to sum something other than money.&lt;br /&gt;
&lt;br /&gt;
This script works when used in a question-by-question format.  It does not work when there are more than one question on a page. I think it can be adapted to work, but I haven&#039;t done the coding yet.&lt;br /&gt;
&lt;br /&gt;
Put the following code into body of your question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script language=Javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// General definitions&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match the labels containing information about an answer&lt;br /&gt;
&lt;br /&gt;
// In LimeSurvey, these labels start with &amp;quot;answer...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
var answerRegex = /^answer/;&lt;br /&gt;
&lt;br /&gt;
// Find all answer checkboxes in the document and set their&lt;br /&gt;
&lt;br /&gt;
// onchange events to updatePrice&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   // Find all input elements&lt;br /&gt;
&lt;br /&gt;
   var inputList=document.getElementsByTagName(&amp;quot;input&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   // Loop through each, looking for checkboxes&lt;br /&gt;
&lt;br /&gt;
   var i;&lt;br /&gt;
&lt;br /&gt;
   for( i=0; i&amp;lt; inputList.length;i++ )&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // If input item does not have an ID, skip&lt;br /&gt;
&lt;br /&gt;
       if (! (inputList[i].id)) { continue; }&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if ID doesn&#039;t start with &amp;quot;answer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
       if (!answerRegex.test(inputList[i].id)) { continue; }&lt;br /&gt;
&lt;br /&gt;
       // Skip to next if not a checkbox&lt;br /&gt;
&lt;br /&gt;
       if (inputList[i].type.toUpperCase()!=&#039;CHECKBOX&#039;)  { continue; }&lt;br /&gt;
&lt;br /&gt;
       // This is an answer checkbox!&lt;br /&gt;
&lt;br /&gt;
       // Setup onchange event&lt;br /&gt;
&lt;br /&gt;
       inputList[i].onclick = updatePrice;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Load initial sum&lt;br /&gt;
&lt;br /&gt;
   updatePrice();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function updatePrice()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
var labels=document.getElementsByTagName(&amp;quot;LABEL&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Define a regular expression to match a price inside parenthesis&lt;br /&gt;
&lt;br /&gt;
// For example: ($29) or ($29.54).&lt;br /&gt;
&lt;br /&gt;
// Set up&lt;br /&gt;
&lt;br /&gt;
priceRegex = /\(\$(\d*\.{0,1}\d+)\)/;&lt;br /&gt;
&lt;br /&gt;
// Loop through all the labels, looking for labels corresponding to&lt;br /&gt;
&lt;br /&gt;
// answers that have a price in them.&lt;br /&gt;
&lt;br /&gt;
var i;&lt;br /&gt;
&lt;br /&gt;
var total = 0;&lt;br /&gt;
&lt;br /&gt;
for( i=0; i&amp;lt;labels.length;i++ )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   var myArray;    // Define array used for regex matching&lt;br /&gt;
&lt;br /&gt;
   var inputID;    // Define field element&lt;br /&gt;
&lt;br /&gt;
   // Get the ID of the field corresponding to the label using the&lt;br /&gt;
&lt;br /&gt;
   // &amp;quot;htmlFor&amp;quot; attribute&lt;br /&gt;
&lt;br /&gt;
   // (FYI, there are some labels that will have to be screened out&lt;br /&gt;
&lt;br /&gt;
   // because they don&#039;t correspond to an answer)&lt;br /&gt;
&lt;br /&gt;
   // Does the label start with &amp;quot;answer&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
   // If not: exit.&lt;br /&gt;
&lt;br /&gt;
   if (!answerRegex.test(labels[i].htmlFor)) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // First make sure this element exists&lt;br /&gt;
&lt;br /&gt;
   // If it doesn&#039;t, go to the next element&lt;br /&gt;
&lt;br /&gt;
   // If it does, it will be defined in inputID&lt;br /&gt;
&lt;br /&gt;
   if (! (inputID = document.getElementById(labels[i].htmlFor)) ) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // See if the corresponding answer is a checkbox that is checked.&lt;br /&gt;
&lt;br /&gt;
   // If not, go to next label&lt;br /&gt;
&lt;br /&gt;
   if (inputID.type.toUpperCase()!=&#039;CHECKBOX&#039;)  { continue; }&lt;br /&gt;
&lt;br /&gt;
   if (!inputID.checked) { continue; }&lt;br /&gt;
&lt;br /&gt;
   // This is label for an answer.&lt;br /&gt;
&lt;br /&gt;
   // The innerHTML will give us the text of the label&lt;br /&gt;
&lt;br /&gt;
   // The price information will be in the form ($XX.XX)&lt;br /&gt;
&lt;br /&gt;
   // which in contained in the label text.&lt;br /&gt;
&lt;br /&gt;
   // Find a match for a decimal number inside the pattern &amp;quot;($&amp;quot; and &amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   if [[myArray = priceRegex.exec(labels[i].innerHTML]] != null)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       // Keep a running tally&lt;br /&gt;
&lt;br /&gt;
       total += parseFloat(myArray[1]);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // Update total price on form&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&amp;quot;totalPrice&amp;quot;).value = &amp;quot;$&amp;quot; + formatCurrency(total);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function formatCurrency(num) {&lt;br /&gt;
&lt;br /&gt;
  num = isNaN(num) || num &amp;lt;u&amp;gt; &#039;&#039; || num &amp;lt;/u&amp;gt; null ? 0.00 : num;&lt;br /&gt;
&lt;br /&gt;
  return parseFloat(num).toFixed(2);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put the following code in the help section (or wherever you want the sum to appear):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Total Cost for selected accessories: &amp;lt;input type=&amp;quot;readonly&amp;quot; value=&amp;quot;&amp;quot; id=&amp;quot;totalPrice&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Focus on the first Input field=&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: LimeSurvey 1.80 / IE6/7, Firefox 3, Safari, Opera, chrome&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.91, there is a built-in JavaScript function called  focusFirst() to focus on the first visible element.  It uses jQuery, so is more robust than this example.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again an onload Function is needed for this tasks. I have done it the DOM way with compatibility to IE6/7.&lt;br /&gt;
&lt;br /&gt;
Put the following code into the startpage.pstpl of your template, right before the &amp;lt;/head&amp;gt; closing tag:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   function focusFirst(Event)&lt;br /&gt;
&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
       var i=0;&lt;br /&gt;
&lt;br /&gt;
       while(document.forms[0].elements[i].type == &amp;quot;hidden&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           i++;&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       document.forms[0].elements[i].focus();&lt;br /&gt;
&lt;br /&gt;
       return;&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(ie)&lt;br /&gt;
&lt;br /&gt;
   { window.attachEvent(&amp;quot;onload&amp;quot;, focusFirst); }&lt;br /&gt;
&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
   { document.addEventListener(&amp;quot;load&amp;quot;, focusFirst, true); }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; I am using this with version 1.80. As changes happened to the templates in the last release, you might need to add the following before the code, if your template is older than 1.80 stable and does not include this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   var ie = false;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will need this for the var ie to be set. Without this var, the function will not work with ie.&lt;br /&gt;
&lt;br /&gt;
=Answer questions by keypress=&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Tested with: IE7, Firefox 3&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
This workaround allow to answer the question on key 0-9 (0 is for the 10 answer).&lt;br /&gt;
&lt;br /&gt;
Follow issues are supported at the moment:&lt;br /&gt;
*Yes-No Questions&lt;br /&gt;
*List Questions (radio)&lt;br /&gt;
*other radio questions&lt;br /&gt;
&lt;br /&gt;
In lists the answer limit is ten.&lt;br /&gt;
&lt;br /&gt;
You supply the template &amp;quot;endpage&amp;quot; of your template with the following script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   jQuery(document).bind(&#039;keypress&#039;, function(e){&lt;br /&gt;
&lt;br /&gt;
       if (48 &amp;lt;= e.which &amp;amp;&amp;amp; e.which &amp;lt;= 57) {&lt;br /&gt;
&lt;br /&gt;
           jQuery(&#039;input:radio&#039;).each(function() {&lt;br /&gt;
&lt;br /&gt;
               var v = jQuery(this).val();&lt;br /&gt;
&lt;br /&gt;
               var c = (e.which &amp;lt;u&amp;gt; 48) ? 10 : e.which - 48;&lt;br /&gt;
&lt;br /&gt;
               if(v &amp;lt;/u&amp;gt; &#039;Y&#039; || v &amp;lt;u&amp;gt; &#039;N&#039;) {&lt;br /&gt;
&lt;br /&gt;
                   v = (v &amp;lt;/u&amp;gt; &#039;Y&#039;) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               if(v == c) {&lt;br /&gt;
&lt;br /&gt;
                   jQuery(this).click();&lt;br /&gt;
&lt;br /&gt;
                   jQuery(&#039;#limesurvey input:submit&#039;).click();&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   })&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Math notation in LimeSurvey=&lt;br /&gt;
#download the js file from [http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html AsciiMath script]&lt;br /&gt;
#copy it in the /scripts/ folder in your installation&lt;br /&gt;
#modify the startpage.psptl of the template you want to use adding the reference to the script (if you use an older version make sure that you copy the template folder first!) for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;ASCIIMathML.js&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the notation where you need it!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you use internet explorer or safari you will need to download the plugin as well, but firefox does the lot for you.&lt;br /&gt;
&lt;br /&gt;
Finally, if you are confident with the limesurvey structure you could add the editor which support math notation and change the reference to the editor you want to use in the configuration file. here is the [http://www.imathas.com/editordemo/demo.html link for a TinyMCE with math support].&lt;br /&gt;
&lt;br /&gt;
=Reverse array_filter (for pre-1.90)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Version 1.91 natively supports this functionality via the array_filter_exclude advanced quation option.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used to filter the answers of an array question to be displayed based on the answers of a multi option question that were &#039;&#039;&#039;NOT&#039;&#039;&#039; selected. A possible application would be to have a multi-option question asking which products were purchased, followed by 2 array questions - one asking to rate the purchased products and another asking why the remaining products were not purchased. Another would be to ask about sessions attended at a conference as in [http://www.limesurvey.org/en/forum/5-can-i-do-this-with-limesurvey/27970-reverse-of-arrayfilter.html this forum thread] and pictured below. There is a live [http://www.partnersinc.biz/surveys//index.php?sid=43358&amp;amp;newtest=Y&amp;amp;lang=en demo here]&lt;br /&gt;
&lt;br /&gt;
[[File:sessions_645x344.gif]]&lt;br /&gt;
&lt;br /&gt;
We&#039;ll use the above example to explain the process as follows:&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsAttended&#039;&#039; multi-options question&lt;br /&gt;
#In group 1 - Create a &#039;&#039;SessionsNotAttended&#039;&#039; multi-options question with identical answers as &#039;&#039;SessionsAttended&#039;&#039; and hide it with styles or conditions&lt;br /&gt;
#In group 2 - Create a &#039;&#039;RateSessionsAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsAttended&#039;&#039;&lt;br /&gt;
#In group 2 - Create a &#039;&#039;ReasonNotAttended&#039;&#039; array question with an [http://docs.limesurvey.org/tiki-index.php?page=Question+attributes&amp;amp;structure;=English+Instructions+for+LimeSurvey#array_filter array_filter] based on &#039;&#039;SessionsNotAttended&#039;&#039;&lt;br /&gt;
#In group 1 - Place JavaScript/jQeury listeners on each of the checkboxes in &#039;&#039;SessionsAttended&#039;&#039; that would toggle the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
&lt;br /&gt;
The JavaScript/jQuery code used would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
       // The toggle function&lt;br /&gt;
&lt;br /&gt;
   function toggle(q1, q2) {&lt;br /&gt;
&lt;br /&gt;
       if ($(q1).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       else {&lt;br /&gt;
&lt;br /&gt;
           $(q2).attr(&#039;checked&#039;, false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // Initialize the SessionNotAttended checkboxes to &amp;quot;checked&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   // The jQuery listeners on the SessionAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   // that toggle the SessionNotAttended checkboxes&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X331&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X331&#039;, &#039;#answer11111X22X441&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X332&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X332&#039;, &#039;#answer11111X22X442&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X333&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X333&#039;, &#039;#answer11111X22X443&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   $(&#039;#answer11111X22X334&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
       toggle (&#039;#answer11111X22X334&#039;, &#039;#answer11111X22X444&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some notes about the code:&lt;br /&gt;
*The code is in an onload function defined in the first question of group 1 - see [[Workarounds#Custom_onload_function|here]]&lt;br /&gt;
*Both &#039;&#039;SessionsAttended&#039;&#039; and &#039;&#039;SessionsNotAttended&#039;&#039; must be in the same group for the toggling to work&lt;br /&gt;
*This case only uses 4 checkboxes but could be expanded as required&lt;br /&gt;
*In this case the survey ID is 11111, the group ID is 22, &#039;&#039;SessionsAttended&#039;&#039; ID is 33 and SessionsNotAttended ID is 44 - these would need to be modified for your survey&lt;br /&gt;
*The toggle function looks for the state of a checkbox in &#039;&#039;SessionsAttended&#039;&#039; and sets the corresponding checkbox in &#039;&#039;SessionsNotAttended&#039;&#039; to the opposite state&lt;br /&gt;
*The &amp;quot;Initialize&amp;quot; section sets the state of &#039;&#039;SessionsNotAttended&#039;&#039; checkboxes whenever we navigate to the group&lt;br /&gt;
*The &amp;quot;Listener&amp;quot; section uses jQuery listeners to detect any change in the &#039;&#039;SessionsAttended&#039;&#039; checkboxes and then toggle the corresponding &#039;&#039;SessionsNotAttended&#039;&#039; checkbox&lt;br /&gt;
&lt;br /&gt;
Some general notes about the questions:&lt;br /&gt;
*CSS can be used to hide &#039;&#039;SessionsNotAttended&#039;&#039; (div#question44 { display: none; }) if you don&#039;t want to use conditions (because maybe you&#039;ve got [[Optional settings#Survey Behavior|$deletenonvalues set to 1]])&lt;br /&gt;
*&#039;&#039;RateSessionsAttended&#039;&#039; and &#039;&#039;ReasonNotAttended&#039;&#039; are another group to avoid things popping in and out of existence as &#039;&#039;SessionsAttended&#039;&#039; is answered&lt;br /&gt;
*[[Setting conditions|Conditions]] are used to ensure that &#039;&#039;RateSessionsAttended&#039;&#039; only appears if some sessions are selected and &#039;&#039;ReasonNotAttended&#039;&#039; only appears if no sessions are selected&lt;br /&gt;
&lt;br /&gt;
=Filter Ranking Question With Multiple-Options (pre 1.92)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90, IE 7/8, FireFox 3/4, Safari 5.0, Chrome 10.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, most of this is easier to do using the the array_filter attribute, or relevance equations in general.  They all work on the same page, and fully support cascading relevance.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround applies a filter to a ranking question based on the checked boxes of a previous multiple-options question. There are two methods - one for filter and ranking questions being on the same page and a slightly different one for the filter question being on a page before the ranking question.&lt;br /&gt;
&lt;br /&gt;
There is a [http://www.partnersinc.biz/surveys//index.php?sid=96314&amp;amp;newtest=Y&amp;amp;lang=en demo of both methods here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH METHODS:&#039;&#039;&#039;&lt;br /&gt;
*[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
*Place the following script in your template.js file. This function will be accessed by either method.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// A function to filter choices in a ranking question&lt;br /&gt;
function rankFilter(q1ID, q2ID, prevPage) {&lt;br /&gt;
&lt;br /&gt;
	// If filter question is on a previous page, hide Q1 and check all &amp;quot;visible&amp;quot; boxes&lt;br /&gt;
	if(prevPage == 1) {&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; li[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;javatbd&amp;quot;]:visible input.checkbox&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039;&#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	handleChecked(q1ID, q2ID);&lt;br /&gt;
	$(&#039;#question&#039;+q1ID+&#039; input.checkbox&#039;).click(function() {&lt;br /&gt;
		handleChecked(q1ID, q2ID);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	function handleChecked(q1ID, q2ID) {&lt;br /&gt;
	&lt;br /&gt;
		// Find the survey and group IDs&lt;br /&gt;
		if($( &#039;input#fieldnames&#039; ).length != 0) {&lt;br /&gt;
			var fieldNames = $( &#039;input#fieldnames&#039; ).attr(&#039;value&#039;);&lt;br /&gt;
			var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
			var sID = tmp[0];&lt;br /&gt;
			var gID = tmp[1];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Loop through all Q1 options&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.checkbox&#039;).each(function(i) {&lt;br /&gt;
		&lt;br /&gt;
			// Find the answer code and value&lt;br /&gt;
			var tmp2 = $(this).attr(&#039;id&#039;).split(&#039;X&#039;+gID+&#039;X&#039;+q1ID+&#039;&#039;);&lt;br /&gt;
			var ansCode = tmp2[1];&lt;br /&gt;
			var ansTxt = $(this).next(&#039;label&#039;).text();&lt;br /&gt;
			&lt;br /&gt;
			// If option is checked and not in rank choices or output, add it to the rank choices&lt;br /&gt;
			if($(this).attr(&#039;checked&#039;) == true&lt;br /&gt;
						  &amp;amp;&amp;amp; $(&#039;#question&#039;+q2ID+&#039; select.select option[value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).length == 0&lt;br /&gt;
						  &amp;amp;&amp;amp; $(&#039;#question&#039;+q2ID+&#039; .output input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;][value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).length == 0) {&lt;br /&gt;
				$(&#039;&amp;lt;option value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;&amp;gt;&#039;+ansTxt+&#039;&amp;lt;/option&amp;gt;&#039;).appendTo(&#039;#question&#039;+q2ID+&#039; select.select&#039;);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// If option is unchecked...&lt;br /&gt;
			else if($(this).attr(&#039;checked&#039;) == false) {&lt;br /&gt;
				// Remove it from the rank choices&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select option[value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).remove();&lt;br /&gt;
				// Remove it from the rank output and reset hidden values&lt;br /&gt;
$(&#039;#question&#039;+q2ID+&#039; .output input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;][value=&amp;quot;&#039;+ansCode+&#039;&amp;quot;]&#039;).attr(&#039;value&#039;, &#039;&#039;).siblings(&#039;input.text&#039;).val(&#039;&#039;).siblings(&#039;img&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Clean up empty inputs in the rank output table&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr&#039;).each(function(i) {&lt;br /&gt;
			var nextRow = $(this).next(&#039;tr&#039;);&lt;br /&gt;
			if($(&#039;input.text&#039;, this).val() == &#039;&#039; &amp;amp;&amp;amp; $(&#039;input.text&#039;, nextRow).val() != &#039;&#039;) {&lt;br /&gt;
				$(&#039;input.text&#039;, this).val($(&#039;input.text&#039;, nextRow).val());&lt;br /&gt;
				$(&#039;input.text&#039;, nextRow).val(&#039;&#039;);&lt;br /&gt;
				$(&#039;input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, this).attr(&#039;value&#039;, $(&#039;input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, nextRow).attr(&#039;value&#039;));&lt;br /&gt;
				$(&#039;input[id&amp;lt;/div&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;, nextRow).attr(&#039;value&#039;, &#039;&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Show the scissors for the last populated rank output row&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table img[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;cut_&amp;quot;]&#039;).hide();&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table input.text[value!=&amp;quot;&amp;quot;]:last&#039;).siblings(&#039;img[id&amp;lt;/div&amp;gt;=&amp;quot;cut_&amp;quot;]&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Hide extra rank output rows&lt;br /&gt;
		var optNum = $(&#039;#question&#039;+q1ID+&#039; input.checkbox:checked&#039;).length;&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr&#039;).hide();&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; .output table tr:lt(&#039;+(optNum+1)+&#039;)&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Hide and clear the ranking question if there are less than 2 checked options in Q1&lt;br /&gt;
		if(optNum &amp;lt; 2) {&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039;&#039;).hide();&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039; input.text&#039;).val(&#039;&#039;);&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039; input[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;fvalue_&amp;quot;]&#039;).attr(&#039;value&#039;, &#039;&#039;);&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#question&#039;+q2ID+&#039;&#039;).show();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// A workaround for the built in max-answers function&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; td.output tr:visible&#039;).each(function(i) {&lt;br /&gt;
			if($(&#039;input.text&#039;, this).val() == &#039;&#039;) {&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// A listener to work around the built in max-answers function&lt;br /&gt;
	$(&#039;#question&#039;+q2ID+&#039; td.rank&#039;).click(function (event) {&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, true);&lt;br /&gt;
		$(&#039;#question&#039;+q2ID+&#039; td.item input.text&#039;).each(function(i) {&lt;br /&gt;
			if ($(this).val() == &#039;&#039;) {&lt;br /&gt;
				$(&#039;#question&#039;+q2ID+&#039; select.select&#039;).attr(&#039;disabled&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH FILTER AND RANKING QUESTIONS ON SAME PAGE:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question and a ranking question on the same page (in the same group).&lt;br /&gt;
*Both questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Place the following script in the source of one of the questions.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;RR&amp;quot; with the ID of the ranking question.&lt;br /&gt;
*The function will hide the ranking question unless at least two options are selected in the multiple options question, in which case, it will only show the options selected.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		rankFilter(MM, RR);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR FILTER AND RANKING QUESTIONS ON SEPARATE PAGES:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question on page 1.&lt;br /&gt;
*Create a multiple options question and a ranking question on page 2.&lt;br /&gt;
*All three questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Set the multiple options on page 2 to be filtered by the multiple options on page 1.&lt;br /&gt;
*Place the following script in the source of one of the questions on page 2.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;RR&amp;quot; with the ID of the ranking question. Do not modify the &amp;quot;1&amp;quot;.&lt;br /&gt;
*The function will hide the multiple options question. If at least 2 options were selected in the multiple options on page 1, the corresponding options will be checked in the hidden multiple options question which will then be used to control the display of the ranking question.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		rankFilter(MM, RR, 1);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Filter &amp;quot;Array by Column&amp;quot; Question With &amp;quot;Multiple-Options&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, FireFox 3/4, Safari 5.0, Chrome 10.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround applies a filter to an &amp;quot;Array by Column&amp;quot; question based on the checked boxes of a previous multiple-options question. There are two methods - one for filter and array questions being on the same page and a slightly different one for the filter question being on a page before the array question.&lt;br /&gt;
&lt;br /&gt;
There is a [http://www.partnersinc.biz/surveys//index.php?sid=74213&amp;amp;newtest=Y&amp;amp;lang=en demo of both methods here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH METHODS:&#039;&#039;&#039;&lt;br /&gt;
*[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
*Place the following scripts in your template.js file. These functions will be accessed by either method.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
	function filterArrByCol(qMultiOpt, qArray, prevPage) {&lt;br /&gt;
	&lt;br /&gt;
		// If filter question is on a previous page, hide Q1 and check all &amp;quot;visible&amp;quot; boxes&lt;br /&gt;
		if(prevPage == 1) {&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039; li[id&amp;lt;/div&amp;gt;=&amp;quot;javatbd&amp;quot;]:visible input.checkbox&#039;).attr(&#039;checked&#039;, true);&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039;&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Assign classes to the answer cells&lt;br /&gt;
		$(&#039;#question&#039;+qArray+&#039; table.question tbody td&#039;).each(function(i){&lt;br /&gt;
			var classArr = $(this).attr(&#039;class&#039;).split(&#039;answer_cell_00&#039;);&lt;br /&gt;
			var ansCode = classArr[1];&lt;br /&gt;
			$(this).addClass(&#039;ans-&#039;+ansCode+&#039; filtered&#039;);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Assign classes to the answer label cells&lt;br /&gt;
		$(&#039;#question&#039;+qArray+&#039; table.question tbody tr:eq(0) td&#039;).each(function(i){&lt;br /&gt;
			var classArr2 = $(this).attr(&#039;class&#039;).split(&#039; ans-&#039;);&lt;br /&gt;
			var ansCode2 = classArr2[1];&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; table.question thead tr:eq(0) th:eq(&#039;+i+&#039;)&#039;).addClass(&#039;ans-&#039;+ansCode2+&#039;&#039;);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Fire the filter function on page load&lt;br /&gt;
		filterArr(qMultiOpt, qArray);&lt;br /&gt;
&lt;br /&gt;
		// Listener on multi-opt checkboxes to fire the filter function&lt;br /&gt;
		$(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox&#039;).click(function(){&lt;br /&gt;
			filterArr(qMultiOpt, qArray);&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// On submit, clear all hidden radios of array&lt;br /&gt;
		$(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; td.filtered:hidden&#039;).each(function(i){&lt;br /&gt;
				$(&#039;input.radio&#039;, this).attr(&#039;checked&#039;, false);&lt;br /&gt;
			});&lt;br /&gt;
			return true;&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function filterArr(qMultiOpt, qArray) {&lt;br /&gt;
	&lt;br /&gt;
		if($(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox:checked&#039;).length &amp;lt; 1) {&lt;br /&gt;
			// Hide the array if no multi-opt options are checked&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039;&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039;&#039;).show();&lt;br /&gt;
			&lt;br /&gt;
			// Hide all columns of array&lt;br /&gt;
			$(&#039;#question&#039;+qArray+&#039; table.question tbody td, #question&#039;+qArray+&#039; table.question thead th&#039;).hide();&lt;br /&gt;
			&lt;br /&gt;
			// Loop through multi-opt checkboxes and, if checked, show corresponding column of array&lt;br /&gt;
			$(&#039;#question&#039;+qMultiOpt+&#039; input.checkbox&#039;).each(function(i){&lt;br /&gt;
				if($(this).attr(&#039;checked&#039;) == true) {&lt;br /&gt;
					var classArr3 = $(this).attr(&#039;id&#039;).split(&#039;X&#039;+qMultiOpt);&lt;br /&gt;
					var ansCode3 = classArr3[1];&lt;br /&gt;
					$(&#039;#question&#039;+qArray+&#039; .ans-&#039;+ansCode3+&#039;&#039;).show();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR BOTH FILTER AND ARRAY QUESTIONS ON SAME PAGE:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question and an array-by-column question on the same page (in the same group).&lt;br /&gt;
*Both questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Place the following script in the source of one of the questions.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;AA&amp;quot; with the ID of the ranking question.&lt;br /&gt;
*The function will hide the array question unless at least one option is selected in the multiple-options question, in which case, it will only show the corresponding array column(s).&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		filterArrByCol(MM, AA);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FOR FILTER AND ARRAY QUESTIONS ON SEPARATE PAGES:&#039;&#039;&#039;&lt;br /&gt;
*Create a multiple options question on page 1.&lt;br /&gt;
*Create a multiple options question and an array-by-column question on page 2.&lt;br /&gt;
*All three questions &#039;&#039;&#039;MUST&#039;&#039;&#039; have identical sub-questions and sub-question codes.&lt;br /&gt;
*Set the multiple options on page 2 to be filtered by the multiple options on page 1.&lt;br /&gt;
*Place the following script in the source of one of the questions on page 2.&lt;br /&gt;
*Replace &amp;quot;MM&amp;quot; with the ID of the multiple options question and &amp;quot;AA&amp;quot; with the ID of the array question. Do not modify the &amp;quot;1&amp;quot;.&lt;br /&gt;
*The function will hide the multiple options question. If options were selected in the multiple options on page 1, the corresponding options will be checked in the hidden multiple options question which will then be used to control the display of the array columns.&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		filterArrByCol(MM, AA, 1);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Auto-tabbing between text input fields=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a workaround to facilitate auto-tabbing between text input questions in a single group using a [http://plugins.jquery.com/project/autotab jQuery plugin by Mathachew] and the Maximum characters attribute of questions.&lt;br /&gt;
&lt;br /&gt;
The behaviour will be: When the maximum number of characters has been entered into an input field, the focus (cursor) will be automatically moved to the next input field. When the backspace key is used to remove all characters from a field, the focus will be moved to the previous field. It&#039;s very useful in surveys having many text input questions to avoid having to manually tab or click between fields.&lt;br /&gt;
&lt;br /&gt;
You can view a small demo survey [http://www.partnersinc.biz/surveys//index.php?sid=11327&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Visit [http://plugins.jquery.com/autotabs http://plugins.jquery.com/autotabs], download the plugin script and save it as &#039;&#039;jquery.autotab-1.1b.js&#039;&#039; in the template folder.&lt;br /&gt;
#Link to the script by placing &#039;&#039;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autotab-1.1b.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&#039;&#039; within the &#039;&#039;&amp;lt;head&amp;gt;&#039;&#039; tag of startpage.pstpl.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Create the text based questions that auto-tabbing is to be applied to. (All must be in the same group if you&#039;re using group by group presentation)&lt;br /&gt;
#Define a Maximum characters attribute for all questions that the autotab is applied to.&lt;br /&gt;
{{QS:maximum_chars}}  &lt;br /&gt;
#In the source of the first question of the group that contains the auto-tabbed questions, add the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXAA&#039;).focus(); //initially focus on the first input&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXAA&#039;).autotab({ target: &#039;answerSSSSSXGGXBB&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXBB&#039;).autotab({ previous: &#039;answerSSSSSXGGXAA&#039;, target: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXCC&#039;).autotab({ previous: &#039;answerSSSSSXGGXBB&#039;, target: &#039;answerSSSSSXGGXDD&#039; });&lt;br /&gt;
&lt;br /&gt;
       $(&#039;#answerSSSSSXGGXDD&#039;).autotab({ previous: &#039;answerSSSSSXGGXCC&#039; });&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example has 4 fields to be auto-tabbed between - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
*SSSSS -&amp;gt; Survey ID&lt;br /&gt;
*GG -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Last question&lt;br /&gt;
&lt;br /&gt;
[[File:ids_343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;target&#039;&#039; parameter defines where the next input is and the &#039;&#039;previous&#039;&#039; parameter defines (you guessed it) the previous input.&lt;br /&gt;
&lt;br /&gt;
This plugin also has limited capability of formatting the input text - see comments in the plugin script.&lt;br /&gt;
&lt;br /&gt;
=Custom response listeners=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.85+ (7253), IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Listeners can be used to perform functions when a change in an input is detected. There are many uses such as the [[Workarounds#Reverse_array_filter|Reverse array_filter]] but a simple one would be to warn a respondent if they enter a value that may be too high.&lt;br /&gt;
&lt;br /&gt;
We can use the [http://docs.jquery.com/Events/change jQuery change( ) event] to fire a function whenever there is a change to the input. The function will look for an input value higher than 10 and, if found, will warn the respondent.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the script below in the source of one of the questions on the page where:&lt;br /&gt;
**11111 is the survey ID&lt;br /&gt;
**22 is the group ID&lt;br /&gt;
**33 is the question ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer11111X22X33&#039;).change(function() {&lt;br /&gt;
&lt;br /&gt;
			if ( $(&#039;#answer11111X22X33&#039;).val() &amp;gt; 10 ) {&lt;br /&gt;
				alert (&amp;quot;That&#039;s an awful lot. Are you sure?&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Text input masks=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number ((###) ###-####) or a Canadian postal code (A1A 1A1) The [http://plugins.jquery.com/project/meioMask jQuery meioMask plugin by fabiomcosta] can be used to do this.&lt;br /&gt;
&lt;br /&gt;
The plugin has several pre-defined masks and supports custom masks. It also allows for pasting of input, allows default values and can auto-focus the next form element when the current input is completely filled. See [http://www.meiocodigo.com/projects/meiomask/ http://www.meiocodigo.com/projects/meiomask/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
There is a small demo [http://www.partnersinc.biz/surveys//index.php?sid=36146&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo was as follows:&lt;br /&gt;
#Visit [http://www.meiocodigo.com/projects/meiomask/ http://www.meiocodigo.com/projects/meiomask/], download the latest plugin script and save it as jquery.meiomask.js in the template folder.&lt;br /&gt;
#Link to the script by placing &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.meiomask.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; within the &amp;lt;head&amp;gt; tag of startpage.pstpl.&lt;br /&gt;
#Turn off $filterxsshtml to allow insertion of JavaScript in the questions. ([http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects See documentation here])&lt;br /&gt;
#Create the text input questions that the masks are to be applied to&lt;br /&gt;
#In the source of the help section of the first question of the group that contains the masked inputs, add the following code. ([http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ See How to use script here]) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {	&lt;br /&gt;
						   &lt;br /&gt;
	// Define custom masks&lt;br /&gt;
	$.mask.masks = $.extend($.mask.masks,{&lt;br /&gt;
		customMask1:{ mask: &#039;a9a 9a9&#039; }, // Canadian postal code&lt;br /&gt;
		// Maximum input of 9,999.99, reverse input, default value of 0.00		&lt;br /&gt;
		customMask2:{ mask: &#039;99.999,9&#039;, type : &#039;reverse&#039;, defaultValue : &#039;000&#039; } &lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Set the &#039;alt&#039; attributes of the inputs&lt;br /&gt;
	$(&#039;#answer111111X22XAA&#039;).attr(&#039;alt&#039;, &#039;phone-us&#039;); // a pre-defined mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XBB&#039;).attr(&#039;alt&#039;, &#039;customMask1&#039;); // a custom mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XCC&#039;).attr(&#039;alt&#039;, &#039;customMask2&#039;); // a custom mask					   &lt;br /&gt;
	$(&#039;#answer111111X22XDD&#039;).attr(&#039;alt&#039;, &#039;cc&#039;); // a pre-defined mask for credit card&lt;br /&gt;
	&lt;br /&gt;
	// Tell the plugin to apply masks to these inputs&lt;br /&gt;
	$(&#039;input:#answer111111X22XAA&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XBB&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XCC&#039;).setMask();&lt;br /&gt;
	$(&#039;input:#answer111111X22XDD&#039;).setMask();	&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first section defines two custom masks to be used - one for Canadian postal code with a format of A#A #A# and a second for a maximum amount of 9999.99 with reverse input (useful for cost inputs) and a default value of 0.00.&lt;br /&gt;
&lt;br /&gt;
The next section sets the &amp;quot;alt&amp;quot; attributes for the text inputs. This will tell meioMask which mask we will be applying to each input. By default meioMask looks at the alt attribute to find which mask to apply however this can be changed using the [http://www.meiocodigo.com/projects/meiomask/#mm_options mask options].&lt;br /&gt;
&lt;br /&gt;
In the final section we apply the masks to the inputs.&lt;br /&gt;
&lt;br /&gt;
This example has 4 inputs with masks on them - all instances of the following must be replaced to be compatible with your survey (See image below):&lt;br /&gt;
&lt;br /&gt;
*11111 -&amp;gt; Survey ID&lt;br /&gt;
*22 -&amp;gt; Group ID&lt;br /&gt;
*AA -&amp;gt; First question&lt;br /&gt;
*BB -&amp;gt; Second question&lt;br /&gt;
*CC -&amp;gt; Third question&lt;br /&gt;
*DD -&amp;gt; Fourth question&lt;br /&gt;
&lt;br /&gt;
[[File:Ids 343x252.gif]]&lt;br /&gt;
&lt;br /&gt;
=Text input masks - second method=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91RC6+, FireFox 4.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There may be instances where you would like to place a mask on a text input - for example only allowing respondents to enter the correct characters for a North American phone number ((###) ###-####) or a US social security number (###-##-####). The jQuery meioMask plugin by fabiomcosta is no longer supported but an alternative exists. The DigitalBush Masked Input Plugin is updated and simple to implement in LimeSurvey. See [http://digitalbush.com/projects/masked-input-plugin/ http://digitalbush.com/projects/masked-input-plugin/] for more details on features and options.&lt;br /&gt;
&lt;br /&gt;
Implementation as follows:&lt;br /&gt;
&lt;br /&gt;
#Visit [http://digitalbush.com/projects/masked-input-plugin/ http://digitalbush.com/projects/masked-input-plugin/], download the latest plugin script and save it as jquery.maskedinput.js in the template folder.&lt;br /&gt;
#Link to the script by placing &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.maskedinput.js&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; within the &amp;lt;head&amp;gt; tag of startpage.pstpl.&lt;br /&gt;
#Turn off $filterxsshtml to allow insertion of JavaScript in the questions. ([http://docs.limesurvey.org/tiki-index.php?page=Optional+settings&amp;amp;structure=English+Instructions+for+LimeSurvey#Filtering_dangerous_HTML_tags_in_survey_objects See documentation here])&lt;br /&gt;
#Create the text input questions that the masks are to be applied to&lt;br /&gt;
#In the source of the help section of the first question of the group that contains the masked inputs, add the following code. ([http://docs.limesurvey.org/tiki-index.php?page=Workarounds&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._ See How to use script here])  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
	$(document).ready(function($) {	 &lt;br /&gt;
		$(&amp;quot;#answer55431X1X5&amp;quot;).mask(&amp;quot;999-99-9999&amp;quot;,{ placeholder:&amp;quot;#&amp;quot; });&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace the &amp;quot;#answer55431X1X5&amp;quot; with your survey ID, group ID, and question ID. You can change the mask format and change or eliminate the placeholder if you wish. If you have multiple questions in the same group, simply copy and paste the line that begins with &amp;quot;$&amp;quot; and change the code to what is needed for your application.&lt;br /&gt;
&lt;br /&gt;
=Select a random response to a &amp;quot;Multiple options&amp;quot; question for later use=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2, Chrome 2.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to randomly select one of the checked boxes in a &amp;quot;Multiple options&amp;quot; question and store it&#039;s label for later use in the survey. A possible use would be to have a question asking what products were purchased and then randomly selecting one of the products to ask further questions about.&lt;br /&gt;
&lt;br /&gt;
There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=81252&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Basically what we&#039;ve done here is to put listeners on all of the checkboxes. If a change of state is detected in any of them the &amp;quot;randomResponse&amp;quot; function is called which loops through all of the checkboxes and if it finds a checked state, that box&#039;s label is added to an array. Then a random item is pulled from the array and used to populate the hidden question. This hidden question can then be drawn upon later in the survey using [http://docs.limesurvey.org/tiki-index.php?page=Adding+a+Question#Information_from_previous_answers INSERTANS] or [http://docs.limesurvey.org/tiki-index.php?page=Setting+conditions&amp;amp;structure=English+Instructions+for+LimeSurvey Conditions].&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
#[http://docs.limesurvey.org/tiki-index.php?page=Workarounds%3A+Manipulating+a+survey+at+runtime+using+Javascript&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._in_LimeSurvey_ Set up your survey to use JavaScript].&lt;br /&gt;
#Create a &amp;quot;Multiple options&amp;quot; question that we&#039;re going to randomly pick a checked box from&lt;br /&gt;
#Create a text input question to store the label of the checked box in (we&#039;re going to hide this with JavaScript)&lt;br /&gt;
#Place the script below in the source of one of the questions on the page. &lt;br /&gt;
&lt;br /&gt;
The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
*EDIT HERE (1) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 44 -&amp;gt; hidden question ID.&lt;br /&gt;
*EDIT HERE (2) - 44 -&amp;gt; hidden question ID.&lt;br /&gt;
*EDIT HERE (3) - 11111 -&amp;gt; Survey ID, 22 -&amp;gt; Group ID, 33 -&amp;gt; multiple option question ID, A/B/C/D/E/F -&amp;gt; multiple option answer codes. Also add or remove CBs for more or less checkboxes.&lt;br /&gt;
*EDIT HERE (4) - add or remove CBs for more or less checkboxes.&lt;br /&gt;
*EDIT HERE (5) - add or remove CBs for more or less checkboxes. &lt;br /&gt;
&lt;br /&gt;
For more info on these IDs see [http://docs.limesurvey.org/tiki-index.php?page=SGQA+identifier&amp;amp;structure=English+Instructions+for+LimeSurvey SGQA identifier].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
				&lt;br /&gt;
		//// Identify the hidden question input&lt;br /&gt;
		//// EDIT HERE (1) - replace with your hidden question input ID&lt;br /&gt;
		var hiddenInput = &#039;#answer11111X22X44&#039;;&lt;br /&gt;
		&lt;br /&gt;
		//// Make the &amp;quot;hidden&amp;quot; question disappear&lt;br /&gt;
		//// EDIT HERE (2) - replace with your hidden question ID&lt;br /&gt;
		$(&#039;#question44&#039;).hide();&lt;br /&gt;
		&lt;br /&gt;
		//// Identify the checkboxes to be randomized&lt;br /&gt;
		//// EDIT HERE (3) - add or remove as required, &lt;br /&gt;
		//// replace with your checkbox IDs&lt;br /&gt;
		var CB1 = &#039;#answer11111X22X33A&#039;;&lt;br /&gt;
		var CB2 = &#039;#answer11111X22X33B&#039;;&lt;br /&gt;
		var CB3 = &#039;#answer11111X22X33C&#039;;&lt;br /&gt;
		var CB4 = &#039;#answer11111X22X33D&#039;;&lt;br /&gt;
		var CB5 = &#039;#answer11111X22X33E&#039;;&lt;br /&gt;
		var CB6 = &#039;#answer11111X22X33F&#039;;&lt;br /&gt;
		&lt;br /&gt;
		//// Create an array of all checkboxes to be randomized&lt;br /&gt;
		//// EDIT HERE (4) - add or remove CBs as required&lt;br /&gt;
		checkBoxes = new Array( CB1, CB2, CB3, CB4, CB5, CB6 );&lt;br /&gt;
		var checkBoxesLength = checkBoxes.length;&lt;br /&gt;
		&lt;br /&gt;
		//// The randomizing function - no editing required&lt;br /&gt;
		function randomResponse () {&lt;br /&gt;
			var boxLabels = new Array();&lt;br /&gt;
			&lt;br /&gt;
			// loop through all of the checkboxes and if they are checked, &lt;br /&gt;
			// add their label to the boxLabels array&lt;br /&gt;
			for( var i=0; i&amp;lt;checkBoxesLength; i++ ) {&lt;br /&gt;
				if ( $(checkBoxes[i]).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
					var cbid = checkBoxes[i].replace(&#039;#&#039;,&#039;&#039;);&lt;br /&gt;
					boxLabels.push( $( &#039;label[for=&#039; + cbid + &#039;]&#039; ).html() );&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// find a random index of the responses array&lt;br /&gt;
			var randomNum = Math.floor(Math.random() * boxLabels.length); &lt;br /&gt;
			&lt;br /&gt;
			// populate the hidden question input with the &lt;br /&gt;
			// random input value&lt;br /&gt;
			$(hiddenInput).val( boxLabels[randomNum] ); &lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		//// The listeners that will fire the randomize function if a &lt;br /&gt;
		//// change occurs in the checkboxes&lt;br /&gt;
		//// EDIT HERE (5) - add or remove CBs as required&lt;br /&gt;
		$(CB1).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB2).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB3).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB4).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB5).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});&lt;br /&gt;
		$(CB6).change(function() {&lt;br /&gt;
			randomResponse ();&lt;br /&gt;
		});	&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Display secondary options in a &amp;quot;Multiple options&amp;quot; question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to display secondary options in a &amp;quot;Multiple options&amp;quot; question if a primary option is checked as in the images below.&lt;br /&gt;
&lt;br /&gt;
Primary option not selected:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Secondary_options_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Primary option selected:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Secondary_options_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is a small demo of the above example [http://www.partnersinc.biz/surveys//index.php?sid=11491&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
We&#039;ve put a listener on the primary answer (&amp;quot;Option 1&amp;quot; in the demo) that shows or hides the secondary answers depending on the state of the primary.&lt;br /&gt;
&lt;br /&gt;
Implementation for this demo is as follows:&lt;br /&gt;
&lt;br /&gt;
#[http://docs.limesurvey.org/tiki-index.php?page=Workarounds%3A+Manipulating+a+survey+at+runtime+using+Javascript&amp;amp;structure=English+Instructions+for+LimeSurvey#How_to_use_Script_eg._JavaScript_etc._in_LimeSurvey_ Set up your survey to use JavaScript].&lt;br /&gt;
#Create a &amp;quot;Multiple options&amp;quot; question including both the primary and secondary answers (in the order that you would like them displayed if all shown)&lt;br /&gt;
#Add the following script to the source of the question.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		&lt;br /&gt;
		/**** &lt;br /&gt;
		The following code puts a listener on an answer in a multiple options&lt;br /&gt;
		question (the primary answer) and if that answer is checked, a secondary &lt;br /&gt;
		level of answers is displayed.&lt;br /&gt;
		****/&lt;br /&gt;
		&lt;br /&gt;
		// --- 1 --- Indent the secondary answers a bit&lt;br /&gt;
		$( &#039;#questionQQ li:eq(1)&#039; ).css({ &#039;margin-left&#039;:&#039;2.5em&#039; });&lt;br /&gt;
		$( &#039;#questionQQ li:eq(2)&#039; ).css({ &#039;margin-left&#039;:&#039;2.5em&#039; });&lt;br /&gt;
		&lt;br /&gt;
		// --- 2 --- When the page loads, see if the primary answer is checked and if not, &lt;br /&gt;
                //hide and un-check all secondary answers&lt;br /&gt;
		if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
			&lt;br /&gt;
			$( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
			$( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
			&lt;br /&gt;
			$( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
			$( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// --- 3 --- Now put a listener on the primary answer to show or hide secondary answers &lt;br /&gt;
		// We need to use .click instead of .change cause IE won&#039;t cooperate&lt;br /&gt;
		$(&#039;#answerSSSSSXGGXQQAA&#039;).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Have a look at the primary answer and hide/show the secondary answers accordingly&lt;br /&gt;
			if ($( &#039;#answerSSSSSXGGXQQAA&#039; ).attr(&#039;checked&#039;) == false ) {&lt;br /&gt;
			&lt;br /&gt;
				$( &#039;#questionQQ li:eq(1)&#039; ).hide();&lt;br /&gt;
				$( &#039;#questionQQ li:eq(2)&#039; ).hide();&lt;br /&gt;
				&lt;br /&gt;
				$( &#039;#answerSSSSSXGGXQQBB&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
				$( &#039;#answerSSSSSXGGXQQCC&#039; ).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				&lt;br /&gt;
				$( &#039;#questionQQ li:eq(1)&#039; ).show();&lt;br /&gt;
				$( &#039;#questionQQ li:eq(2)&#039; ).show();&lt;br /&gt;
			} &lt;br /&gt;
			&lt;br /&gt;
			// The original functions of the click event&lt;br /&gt;
			cancelBubbleThis(event);&lt;br /&gt;
			checkconditions(this.value, this.name, this.type);&lt;br /&gt;
		  }&lt;br /&gt;
		);&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following edits are required to implement this in your survey:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 1:&#039;&#039;&#039;&lt;br /&gt;
*This section indents the secondary answers to give the look of a list in a list when they&#039;re shown&lt;br /&gt;
*&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID&lt;br /&gt;
*&#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; are the index positions of your secondary options. Modify or add as necessary for the number and placement of secondary options in your question. Note that the index starts at 0 so &#039;&#039;&#039;eq(1)&#039;&#039;&#039; actually affects the second option in the full list and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; affects the third. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 2:&#039;&#039;&#039;&lt;br /&gt;
*This section checks the state of the primary question when the page is loaded and if necessary hides the secondary questions. We need this in case users navigate away from and then back to the page.&lt;br /&gt;
*Modify &#039;&#039;&#039;eq(1)&#039;&#039;&#039; and &#039;&#039;&#039;eq(2)&#039;&#039;&#039; as above.&lt;br /&gt;
*&#039;&#039;&#039;SSSSS&#039;&#039;&#039; is your survey ID.&lt;br /&gt;
*&#039;&#039;&#039;GG&#039;&#039;&#039; is your group ID.&lt;br /&gt;
*&#039;&#039;&#039;QQ&#039;&#039;&#039; is your question ID.&lt;br /&gt;
*&#039;&#039;&#039;AA&#039;&#039;&#039; is your primary answer code.&lt;br /&gt;
*&#039;&#039;&#039;BB&#039;&#039;&#039; and &#039;&#039;&#039;CC&#039;&#039;&#039; are your secondary answer codes (add as necessary). &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Section 3:&#039;&#039;&#039;&lt;br /&gt;
*This is the section that &amp;quot;listens&amp;quot; to the primary answer and reacts accordingly.&lt;br /&gt;
*Edit as in section 2.&lt;br /&gt;
&lt;br /&gt;
For more info on these IDs see SGQA identifier(external link).&lt;br /&gt;
&lt;br /&gt;
This code could be tidied up and shortened a bit but I left it this way to make it easier to follow.&lt;br /&gt;
&lt;br /&gt;
=Minimum number of required answers in an array (pre 1.92)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2,&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92 all array style questions have the min_answers and max_answers options, so this script is obsolete.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to specify a &#039;&#039;&#039;minimum number&#039;&#039;&#039; of answers required in an array question. It is an alternative to the &amp;quot;Mandatory&amp;quot; parameter which specifies that &#039;&#039;&#039;all&#039;&#039;&#039; answers are required. It could also be easily modified to specify a maximum number of answers.&lt;br /&gt;
&lt;br /&gt;
We accomplish this by placing an onload function in the source of the array question. This function hides the Next/Submit button and displays a warning element until it detects a minimum number of responses. It then hides the warning and shows the Next/Submit button.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=97166&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Set up the template to use custom onload functions. (See the [[Workarounds#Custom onload function|workaround here]])&lt;br /&gt;
#In the source of the array question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Modify the &#039;&#039;SETTINGS&#039;&#039; section of the code as required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	// Wait until the document is fully loaded&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
	&lt;br /&gt;
		/********************** SETTINGS **********************/&lt;br /&gt;
		// The text to appear in the warning element&lt;br /&gt;
		var warningText = &#039;Please answer at least 4 to continue&#039;;&lt;br /&gt;
		// The question ID&lt;br /&gt;
		var questionId = 137;&lt;br /&gt;
		// The minimum number of answers required&lt;br /&gt;
		var minNumber = 4;&lt;br /&gt;
		/******************************************************/&lt;br /&gt;
		&lt;br /&gt;
		// Create the warning element and place it after the submit button&lt;br /&gt;
		var el = document.createElement(&#039;div&#039;);&lt;br /&gt;
		el.setAttribute(&#039;id&#039;,&#039;warning&#039;);&lt;br /&gt;
		document.body.appendChild(el);&lt;br /&gt;
		$( &#039;#warning&#039; ).css({&lt;br /&gt;
			&#039;border&#039;:&#039;1px solid #333333&#039;,&lt;br /&gt;
			&#039;width&#039;:&#039;200px&#039;,&lt;br /&gt;
			&#039;padding&#039;:&#039;3px&#039;,&lt;br /&gt;
			&#039;color&#039;:&#039;red&#039;&lt;br /&gt;
		});&lt;br /&gt;
		$(&#039;#warning&#039;).html(warningText);&lt;br /&gt;
		$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).after($(&#039;#warning&#039;));&lt;br /&gt;
		&lt;br /&gt;
		// Detect the initial number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
		var inputInitCount = 0;&lt;br /&gt;
		$(&#039;#question&#039; + questionId + &#039; input&#039;).each(function(i) {&lt;br /&gt;
			if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
				inputInitCount++;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		if (inputInitCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
			$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
			$(&#039;#warning&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(&#039;#warning&#039;).show();&lt;br /&gt;
			$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Listener to detect number of checked answers &amp;amp; display Next/Submit button accordingly&lt;br /&gt;
		$(&#039;#question&#039; + questionId + &#039; input.radio, #question&#039;+questionId+&#039; tbody[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;javatbd&amp;quot;] td&#039;).click(function() {&lt;br /&gt;
			var inputCount = 0;&lt;br /&gt;
			$(&#039;#question&#039; + questionId + &#039; input.radio&#039;).each(function(i) {&lt;br /&gt;
				if ($( this ).attr(&#039;checked&#039;) == true ) {&lt;br /&gt;
					inputCount++;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
			if (inputCount &amp;gt; (minNumber - 1)) {&lt;br /&gt;
				$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).show();&lt;br /&gt;
				$(&#039;#warning&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;#warning&#039;).show();&lt;br /&gt;
				$(&#039;input[type=&amp;quot;submit&amp;quot;]&#039;).hide();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// The original functions of the click event&lt;br /&gt;
			checkconditions(this.value, this.name, this.type);&lt;br /&gt;
		});&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Minimum elapsed time before moving forward in survey=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, Firefox 7.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround interrupts the Next/Submit function and checks the amount of time elapsed since the page loaded. If the time is less than the minimum dictated, the respondent is alerted and not allowed to proceed. It is useful if you want to enforce a minimum amount of time spent viewing a page.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the script below in the source of one of the questions on the page, replacing &amp;quot;TT&amp;quot; with the minimum number of seconds required before advancing is allowed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		minTime(TT);&lt;br /&gt;
&lt;br /&gt;
		function minTime(minTime) {&lt;br /&gt;
&lt;br /&gt;
			var startTime = new Date();&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
				var endTime = new Date();&lt;br /&gt;
&lt;br /&gt;
				if((endTime - startTime)/1000 &amp;lt;= minTime) {&lt;br /&gt;
					alert (&#039;You must spend at least &#039;+minTime+&#039; seconds on the question.&#039;);&lt;br /&gt;
					return false;&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					return true;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Minimum number of characters in Long free text or Huge free text questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91, IE 7/8, Firefox 7.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.91, you can use regular expression masks (validation) to specify the minimum number of required characters.  However, even if the question is mandatory, it can still be blank.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version  1.92, if you make the question mandatory and use a validation mask to specify the minimum number of characters, then the user will be forced to answer the question.  Note that unlike 1.91, they can submit their current answers, even if partially invalid (so they are stored in the database), but they will not ber able to proceed to the next page until they have passed all mandatory and validity checks.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround interrupts the Next/Submit function and checks the number of characters entered in a Long free text or Huge free text question. If the number is less than the minimum dictated, the respondent is alerted and not allowed to proceed.&lt;br /&gt;
&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
&lt;br /&gt;
#Place the script below in the source of one of the questions on the page, replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;CC&amp;quot; with the minimum number of characters required before advancing is allowed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       minChar(QQ, CC);&lt;br /&gt;
&lt;br /&gt;
       function minChar(qID, minChars) {&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               if($(&#039;#question&#039;+qID+&#039; textarea&#039;).val().replace(/ /g,&#039;&#039;).length &amp;lt; minChars) {&lt;br /&gt;
&lt;br /&gt;
                   alert (&#039;You must enter at least &#039;+minChars+&#039; characters.&#039;);&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Variable Length Array (Multi Flexible Text) question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows a respondent to add or remove rows of an Array (Multi Flexible Text) question. It&#039;s useful to avoid the page being cluttered with unnecessary array rows.&lt;br /&gt;
&lt;br /&gt;
A function is placed in the template.js file of your template (use template editor). This function hides all of the array rows except the first and inserts two elements that when clicked show or hide rows accordingly.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=53132&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
It must be noted that you can not make this question Mandatory as the respondent will have no way to complete hidden fields. If you want the displayed fields to be mandatory you will need to validate them in another function or modify this function to only allow the addition of rows if all fields in the last row are completed and then disable those fields - that, however, is a little over the top for this example.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
#Set up your survey to use JavaScript (See instructions [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|here]])&lt;br /&gt;
&lt;br /&gt;
#Add the following script to your &#039;&#039;template.js&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end with the question ID.&lt;br /&gt;
&lt;br /&gt;
#Create one or more Array (Multi Flexible Text) questions&lt;br /&gt;
&lt;br /&gt;
#If you want to apply it to more arrays on the same page simply add more calls with the appropriate question IDs. (eg. varLengthArray(1); varLengthArray(2);...)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   // A function to add or remove rows of an Array (Multi Flexible)(Text) question&lt;br /&gt;
	function varLengthArray(qID) {&lt;br /&gt;
&lt;br /&gt;
		if ($(&#039;#question&#039;+qID+&#039;&#039;).length &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
			// The HTML content of the Add/Remove elements - modify as you wish&lt;br /&gt;
			var addContent = &#039;[+]&#039;;&lt;br /&gt;
			var removeContent = &#039;[-]&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Create the Add and Remove elements &amp;amp; insert them&lt;br /&gt;
			var el1 = document.createElement(&#039;div&#039;);&lt;br /&gt;
			el1.setAttribute(&#039;id&#039;,&#039;addButton&#039;+qID);&lt;br /&gt;
			document.body.appendChild(el1);&lt;br /&gt;
			var el2 = document.createElement(&#039;div&#039;);&lt;br /&gt;
			el2.setAttribute(&#039;id&#039;,&#039;removeButton&#039;+qID);&lt;br /&gt;
			document.body.appendChild(el2);&lt;br /&gt;
&lt;br /&gt;
			// Move them to after the array&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).appendTo($( &#039;#question&#039; + qID + &#039; table.question&#039; ).parent());&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).appendTo($( &#039;#question&#039; + qID + &#039; table.question&#039; ).parent());&lt;br /&gt;
&lt;br /&gt;
			// Insert their HTML&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).html( addContent );&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).html( removeContent );&lt;br /&gt;
&lt;br /&gt;
			// Style the elements - you can modify here if you wish&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).css({&lt;br /&gt;
				&#039;margin&#039;:&#039;10px 0 0 10px&#039;,&lt;br /&gt;
				&#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
				&#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
				&#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
				&#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
				&#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
				&#039;float&#039;:&#039;left&#039;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).css({&lt;br /&gt;
				&#039;margin&#039;:&#039;10px 0 0 10px&#039;,&lt;br /&gt;
				&#039;padding&#039;:&#039;1px&#039;,&lt;br /&gt;
				&#039;text-align&#039;:&#039;center&#039;,&lt;br /&gt;
				&#039;font-weight&#039;:&#039;bold&#039;,&lt;br /&gt;
				&#039;width&#039;:&#039;auto&#039;,&lt;br /&gt;
				&#039;cursor&#039;:&#039;pointer&#039;,&lt;br /&gt;
				&#039;float&#039;:&#039;left&#039;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Initially hide the Remove element&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).hide();&lt;br /&gt;
&lt;br /&gt;
			// Call the functions below when clicked&lt;br /&gt;
			$( &#039;div#addButton&#039;+qID ).click(function (event) {&lt;br /&gt;
				addRow(qID);&lt;br /&gt;
			});&lt;br /&gt;
			$( &#039;div#removeButton&#039;+qID ).click(function (event) {&lt;br /&gt;
				removeRow(qID);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Function to add a row, also shows the Remove element and hides the&lt;br /&gt;
			//Add element if all rows are shown&lt;br /&gt;
			function addRow(qID) {&lt;br /&gt;
				var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
				var rowCount = $( arrayRow ).size() - 1;&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
				$( &#039;div#removeButton&#039;+qID ).show();&lt;br /&gt;
				if ( $( arrayRow + &#039;:eq(&#039; + rowCount + &#039;)&#039; ).attr(&#039;name&#039;) == &#039;visible&#039; )  {&lt;br /&gt;
					$( &#039;div#addButton&#039;+qID ).hide();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Function to remove a row, also clears the contents of the removed row,&lt;br /&gt;
			// shows the Add element if the last row is hidden and hides the Remove&lt;br /&gt;
			// element if only the first row is shown&lt;br /&gt;
			function removeRow(qID) {&lt;br /&gt;
				var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
				var rowCount = $( arrayRow ).size() - 1;&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last input[type=&amp;quot;text&amp;quot;]&#039; ).val(&#039;&#039;);&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;visible&amp;quot;]:last&#039; ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
				$( &#039;div#addButton&#039;+qID ).show();&lt;br /&gt;
				if ( $( arrayRow + &#039;:eq(1)&#039; ).attr(&#039;name&#039;) == &#039;hidden&#039; )  {&lt;br /&gt;
					$( &#039;div#removeButton&#039;+qID ).hide();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// Just some initialization stuff&lt;br /&gt;
			var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody&#039;;&lt;br /&gt;
			var rowCount = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Initially hide all except first row or any rows with populated inputs&lt;br /&gt;
			$( arrayRow ).each(function(i) {&lt;br /&gt;
				if ( i &amp;gt; 0 ) {&lt;br /&gt;
					// We also need to give the hidden rows a name cause IE doesn&#039;t&lt;br /&gt;
					// recognize jQuery :visible selector consistently&lt;br /&gt;
					$( this ).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
					$(&#039;input[type=text]&#039;, this).each(function(i) {&lt;br /&gt;
						if ($(this).attr(&#039;value&#039;) != &#039;&#039;) {&lt;br /&gt;
							$(this).parents(&#039;tbody:eq(0)&#039;).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
							$( &#039;div#removeButton&#039;+qID ).show();&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
					rowCount = i;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Call the function with a question ID&lt;br /&gt;
	varLengthArray(QQ);&lt;br /&gt;
&lt;br /&gt;
});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expandable Array=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to present an array question incrementally. That is to say that initially only the first option (row) in the array is shown. When that option is answered the next is shown and so-on.&lt;br /&gt;
&lt;br /&gt;
A JavaScript function is placed in the source of the array question. This function hides all of the array rows except the first and then displays them as options are answered.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=94958&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
The workaround supports following question types:&lt;br /&gt;
*Array (flexible labels)&lt;br /&gt;
*Array (flexible labels) by column&lt;br /&gt;
*Array (Yes/No/Uncertain)&lt;br /&gt;
*Array (Increase, Same, Decrease)&lt;br /&gt;
*Array (Flexible Labels) dual scale&lt;br /&gt;
*Array (10 point choice)&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Set up your survey to use JavaScript. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|documentation here]])&lt;br /&gt;
#Create one or more Array questions&lt;br /&gt;
#In the source of the first array question add the following script.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in the function call at the end of the script with the question ID of the array you would like to manipulate.&lt;br /&gt;
#If you want to apply it to more arrays on the same page, simply add more calls with the appropriate question IDs. (eg. expandingArray(1); expandingArray(2);...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// A function to show subsequent rows of an array as options are checked&lt;br /&gt;
		function expandingArray(qID) {&lt;br /&gt;
&lt;br /&gt;
			// Build an array of the question rows&lt;br /&gt;
			var arrayRow = &#039;#question&#039; + qID + &#039; table.question tbody tr&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Initially hide all rows unless an input was previously checked&lt;br /&gt;
			$( arrayRow ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
				if ( $( arrayRow  + &#039;:eq(&#039; + i + &#039;) input.radio:checked&#039; ).length != 0 ) {&lt;br /&gt;
					$(this).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					$(this).attr(&#039;name&#039;, &#039;hidden&#039;).hide();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Now show the first hidden row&lt;br /&gt;
			addRow();&lt;br /&gt;
&lt;br /&gt;
			// Add another row when an option is checked for the first time&lt;br /&gt;
			$( &#039;#question&#039; + qID + &#039; td.answer input.radio&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
				if ($(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;) != &#039;clickedRow&#039;) {&lt;br /&gt;
					addRow();&lt;br /&gt;
					$(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				// The original function of the click event&lt;br /&gt;
				checkconditions(this.value, this.name, this.type);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Add another row when an table cell is clicked for the first time&lt;br /&gt;
			$( &#039;#question&#039; + qID + &#039; table.question tbody td&#039; ).click(function (event) {&lt;br /&gt;
&lt;br /&gt;
				if ($(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;) != &#039;clickedRow&#039;) {&lt;br /&gt;
					addRow();&lt;br /&gt;
					$(this).parents(&#039;tr:eq(0)&#039;).attr(&#039;name&#039;, &#039;clickedRow&#039;);&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Function to add a row&lt;br /&gt;
			function addRow() {&lt;br /&gt;
				$( arrayRow + &#039;[name=&amp;quot;hidden&amp;quot;]:first&#039; ).attr(&#039;name&#039;, &#039;visible&#039;).show();&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with a question ID&lt;br /&gt;
		expandingArray(QQ);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions - ENHANCED=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping as many answers at the end of the list as specified by the var insertitems=n, where n is the number of answers you want left unrandomized. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the 5th to 7th displayed last as in the image below (assuming you assigned the number 3 to insertitems):&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [[Optional settings#Survey Behavior|$shownoanswer option]] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Set var insertitems=n (n = the number of items you want un-randomized)&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
Onload code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Function to allow randomization of all answers except the last one in Multiple options and List/radio questions&lt;br /&gt;
&lt;br /&gt;
       function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
           //var to define how many lists to be added at the end&lt;br /&gt;
&lt;br /&gt;
           var insertitems=3;&lt;br /&gt;
&lt;br /&gt;
           // Find the number of answers&lt;br /&gt;
&lt;br /&gt;
           var ansCount = &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
           lastitems=new Array();&lt;br /&gt;
&lt;br /&gt;
           var liid=new Array();&lt;br /&gt;
&lt;br /&gt;
           var $ul;&lt;br /&gt;
&lt;br /&gt;
           var j=0;&lt;br /&gt;
&lt;br /&gt;
           $( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                           ansCount = (i + 1);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
                           if(i&amp;gt;ansCount-(insertitems+1)){&lt;br /&gt;
&lt;br /&gt;
                             lastitems[j]=$(this).html();&lt;br /&gt;
&lt;br /&gt;
                             liid[j]=$(this).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                             j++;&lt;br /&gt;
&lt;br /&gt;
                             $(this).remove();&lt;br /&gt;
&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$( &#039;#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
// get current ul&lt;br /&gt;
&lt;br /&gt;
$ul = $(this).parent();&lt;br /&gt;
&lt;br /&gt;
// get array of list items in current ul&lt;br /&gt;
&lt;br /&gt;
var $liArr = $ul.children(&#039;li&#039;);&lt;br /&gt;
&lt;br /&gt;
// sort array of list items in current ul randomly&lt;br /&gt;
&lt;br /&gt;
$liArr.sort(function(a,b){&lt;br /&gt;
&lt;br /&gt;
// Get a random number between 0 and 100&lt;br /&gt;
&lt;br /&gt;
var temp = parseInt( Math.random()*100 );&lt;br /&gt;
&lt;br /&gt;
// Get 1 or 0, whether temp is odd or even&lt;br /&gt;
&lt;br /&gt;
var isOddOrEven = temp%2;&lt;br /&gt;
&lt;br /&gt;
// Get +1 or -1, whether temp greater or smaller than 5&lt;br /&gt;
&lt;br /&gt;
var isPosOrNeg = temp&amp;gt;5 ? 1 : -1;&lt;br /&gt;
&lt;br /&gt;
// Return -1, 0, or +1&lt;br /&gt;
&lt;br /&gt;
return( isOddOrEven*isPosOrNeg );&lt;br /&gt;
&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
// append list items to ul&lt;br /&gt;
&lt;br /&gt;
.appendTo($ul);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$.each(lastitems,function(i){&lt;br /&gt;
&lt;br /&gt;
$( $ul ).append(&amp;quot;&amp;lt;li id=&amp;quot;+liid[i]+&amp;quot;&amp;gt;&amp;quot;+this+&amp;quot;&amp;lt;/li&amp;gt;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
       // Call the function with the SID, GID and QID&lt;br /&gt;
&lt;br /&gt;
       partRand(SSSSS, GG, QQ);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple Options &amp;amp; List (radio) questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows the answers of Multiple Options &amp;amp; List (radio) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last as in the image below:&lt;br /&gt;
&lt;br /&gt;
[[File:random_336x179gif.gif]]&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
Some conditions on the use of this are:&lt;br /&gt;
*For Select/radio type questions it will only work if the [[Optional settings#Survey Behavior|$shownoanswer option]] is set to 0 in config.php. (&amp;quot;No answer&amp;quot; is removed from the end of questions)&lt;br /&gt;
*You must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple Options or List (radio) questions with sequential response codes. Set the [[Advanced question settings#random_order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRand(11111, 22, 1); partRand(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers except the last one in Multiple options and List/radio questions&lt;br /&gt;
		function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; td.answer li&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = (i + 1);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list&lt;br /&gt;
			$( &#039;input#answer&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).parent().appendTo($( &#039;#question&#039; + qID + &#039; td.answer ul&#039; ));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
			partRand(SSSSS, GG, QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - List (dropdown) questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, FireFox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the one above, allows the answers of List (dropdown) questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
There is a demo [http://www.partnersinc.biz/surveys//index.php?sid=89344&amp;amp;newtest=Y&amp;amp;lang=en here].&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more List (dropdown) questions with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers&lt;br /&gt;
		//except the last one in List/dropdown questions&lt;br /&gt;
		function partRandDD(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; select option&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = i;&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list&lt;br /&gt;
			$( &#039;option[value=&amp;quot;&#039; + ansCount + &#039;&amp;quot;]&#039; ).appendTo($( &#039;div#question&#039; + qID + &#039; select&#039; ));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
		partRandDD(89344, 72, 244);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Partially Randomized Answers - Multiple numerical input=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, Safari 5.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround, similar to the ones above, allows the answers of Multiple numerical input questions to be randomized while always keeping one answer at the end of the list. It&#039;s useful if you want to randomize, say, the first 4 of your answers but always have the fifth displayed last.&lt;br /&gt;
&lt;br /&gt;
An onload function is placed in the source of a question. After the randomizing has occurred this function moves the answer with the highest answer code to the end of the list.&lt;br /&gt;
&lt;br /&gt;
A condition is that you must use sequential numbers, starting at 1 as response codes. (See image below)&lt;br /&gt;
&lt;br /&gt;
[[File:random_700x154.png]]&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions. (See [[Optional settings#Security|documentation here]])&lt;br /&gt;
#Create one or more Multiple numerical input question with sequential response codes. Set the [[Advanced question settings#random order|random_order question attribute]] to 1.&lt;br /&gt;
#In the source of the first question add the following onload function. (See [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]])&lt;br /&gt;
#Replace &amp;quot;SSSSS&amp;quot;, &amp;quot;GG&amp;quot;, &amp;quot;QQ&amp;quot; in the function call at the end with the survey ID, group ID and question ID respectively.&lt;br /&gt;
#If you want to apply it to more questions on the same page simply add more calls with the appropriate IDs. (eg. partRandDD(11111, 22, 1); partRandDD(11111, 22, 2); ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Function to allow randomization of all answers except the last one in multiple numeric input questions&lt;br /&gt;
		function partRand(sID, gID, qID) {&lt;br /&gt;
&lt;br /&gt;
			// Find the number of answers&lt;br /&gt;
			var ansCount = &#039;&#039;&lt;br /&gt;
			$( &#039;div#question&#039; + qID + &#039; div.answers li&#039; ).each(function(i) {&lt;br /&gt;
				ansCount = (i - 1);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Place the last answer created at the end of the list - but before the first helping sum&lt;br /&gt;
			$( &#039;li#javatbd&#039; + sID + &#039;X&#039; + gID + &#039;X&#039; + qID + ansCount + &#039;&#039; ).insertBefore($( &#039;div#question&#039; + qID + &#039; div.answers li.multiplenumerichelp&#039; ).first());&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Call the function with the SID, GID and QID&lt;br /&gt;
		partRand(SID, GID, QID);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using this solution for Multiple numerical input questions might be a bit more complicated than for other question types. All answers are organized in an unordered list (&amp;lt;nowiki&amp;gt;&amp;lt;ul&amp;gt;&amp;lt;/nowiki&amp;gt;) structure. However, if advanced question settings like &#039;&#039;Equals sum value&#039;&#039; are used, LimeSurvey adds helping information (e.g. sum of all entries and remainder) to the same unordered list using the class &#039;&#039;multiplenumerichelp&#039;&#039; for these additional list items. The above example  assumes that at least one of these list items is present and moves the last answer to the position right above the first helper item. Without such advanced settings, the code will most certainly need adaptation.&lt;br /&gt;
&lt;br /&gt;
=Making one (or more) rows of an array mandatory=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7, Firefox 3.0, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround allows you to define one or more rows of an array question as mandatory (instead of all of them which the &amp;quot;Mandatory&amp;quot; question setting does). It is [http://www.partnersinc.biz/surveys//index.php?sid=26842&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
A JavaScript function interrupts the submit function and checks if the inputs in the mandatory row(s) are populated. If not, an alert is popped up, the offending inputs are turned pink and the submit is aborted. Otherwise the submit goes ahead.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Turn off &#039;&#039;$filterxsshtml&#039;&#039; to allow insertion of JavaScript in the questions (see [[Optional settings#Security|documentation here]]).&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following script (see [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]]).&lt;br /&gt;
#Modify the warningText (line10)as required.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; (lines 13 and 14)  with the question ID and add calls as necessary for more rows - the example code renders rows 1 and 3 mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function () {&lt;br /&gt;
&lt;br /&gt;
		// Interrupt the submit function&lt;br /&gt;
		$(&#039;form#limesurvey&#039;).submit(function () {&lt;br /&gt;
&lt;br /&gt;
			// Override the built-in &amp;quot;disable navigation buttons&amp;quot; feature&lt;br /&gt;
			$(&#039;#moveprevbtn, #movenextbtn, #movesubmitbtn&#039;).attr(&#039;disabled&#039;, &#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
			var empty = 0;&lt;br /&gt;
			var warningText = &#039;Please complete the highlighted inputs.&#039;;&lt;br /&gt;
&lt;br /&gt;
			// Call the mandatory row function with question IDs and row numbers&lt;br /&gt;
			mandatoryRow(QQ, 1);&lt;br /&gt;
			mandatoryRow(QQ, 3);&lt;br /&gt;
&lt;br /&gt;
			// A function to render rows of an array mandatory&lt;br /&gt;
			function mandatoryRow(qID, rowNum) {&lt;br /&gt;
&lt;br /&gt;
				$(&#039;div#question&#039; + qID + &#039; table.question tbody[id&amp;lt;/div&amp;gt;=&amp;quot;javatbd&amp;quot;]:eq(&#039; + Number(rowNum - 1) + &#039;) input[type=&amp;quot;text&amp;quot;]&#039;).each(function (i) {&lt;br /&gt;
&lt;br /&gt;
					if ($(this).val() == &#039;&#039;) {&lt;br /&gt;
						$(this).css(&#039;background-color&#039;, &#039;pink&#039;);&lt;br /&gt;
						empty = 1;&lt;br /&gt;
					} &lt;br /&gt;
					else {&lt;br /&gt;
						$(this).css(&#039;background-color&#039;, &#039;#FFFFFF&#039;);&lt;br /&gt;
					}&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (empty == 1) {&lt;br /&gt;
				alert(warningText);&lt;br /&gt;
				return false;&lt;br /&gt;
			} &lt;br /&gt;
			else {&lt;br /&gt;
				return true;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Randomly displaying one of a few YouTube videos, and recording which was displayed=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland has created and documented a method to randomly display one of a number of youtube videos in a single question, and save which one was displayed.&lt;br /&gt;
&lt;br /&gt;
http://www.aptigence.com.au/home/archives/23-Random-display-of-videos-in-a-question-2-YouTube.html&lt;br /&gt;
&lt;br /&gt;
=Randomly displaying one of a few pictures, and recording which was displayed=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.91+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The following steps allow you to randomly display one of a few pictures and record in the dataset which picture was displayed. We use four pictures in this example, but you can easily adapt these scripts according to your needs.&lt;br /&gt;
&lt;br /&gt;
1. Create a new sub-directory &#039;&#039;&#039;pic&#039;&#039;&#039; in your LimeSurvey folder.&lt;br /&gt;
&lt;br /&gt;
2. Copy four pictures (named &#039;&#039;1.jpg&#039;&#039;, &#039;&#039;2.jpg&#039;&#039;, &#039;&#039;3.jpg&#039;&#039;, and &#039;&#039;4.jpg&#039;&#039;) in this pic sub-directory.&lt;br /&gt;
&lt;br /&gt;
3. Deactivate the &#039;&#039;Filter HTML for XSS&#039;&#039; function in LimeSurvey&#039;s &#039;&#039;Global Settings&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
4. Create a &#039;&#039;&#039;Short free text&#039;&#039;&#039; question where you want these pictures to be displayed.&lt;br /&gt;
&lt;br /&gt;
5. Figure out the [[SGQA identifier|SGQA Identifier]] of this question (e.g., 12345X67X89).&lt;br /&gt;
&lt;br /&gt;
6. Paste the following code as question text after activating the editor&#039;s &#039;&#039;Source&#039;&#039; view and replace both SSSSSXGGXQQ strings with your SGQA identifier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please have a look at this picture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(&lt;br /&gt;
&lt;br /&gt;
function(){&lt;br /&gt;
&lt;br /&gt;
// Find a random number (here between 1 and 4)&lt;br /&gt;
&lt;br /&gt;
var randNumber = Math.floor(Math.random()*4 + 1);&lt;br /&gt;
&lt;br /&gt;
// Save the number as answer of this question&lt;br /&gt;
&lt;br /&gt;
$(&#039;input#answerSSSSSXGGXQQ&#039;).val(randNumber);&lt;br /&gt;
&lt;br /&gt;
// Hide this answer field&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&amp;quot;answerSSSSSXGGXQQ&amp;quot;).style.display=&#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
// Show the picture&lt;br /&gt;
&lt;br /&gt;
picString = &#039;&amp;lt;img src=&amp;quot;pic/&#039; + String(randNumber) + &#039;.jpg&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;pic&#039;).innerHTML = picString;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
);&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;pic&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to display the number of this picture in a later question, use the following code as question text (don&#039;t forget to replace the SSSSSXGGXQQ string acordingly):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You saw picture number {INSERTANS:SSSSSXGGXQQ}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perhaps you want to display the same picture again in a later question, but a little bit smaller (100px width, 100px height)? Just paste the following code as question text after activating the editor&#039;s &#039;&#039;Source&#039;&#039; view, and replace the SSSSSXGGXQQ string acordingly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here you see the picture again: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(&lt;br /&gt;
&lt;br /&gt;
function(){&lt;br /&gt;
&lt;br /&gt;
// Get the picture number from previous question&lt;br /&gt;
&lt;br /&gt;
var randNumber = &amp;quot;{INSERTANS:SSSSSXGGXQQ}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Show picture&lt;br /&gt;
&lt;br /&gt;
picString = &#039;&amp;lt;img width=&amp;quot;100&amp;quot; height=&amp;quot;100&amp;quot; src=&amp;quot;pic/&#039; + String(randNumber) + &#039;.jpg&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;pic&#039;).innerHTML = picString;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
);&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;pic&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple numerical input with max_num_value defined in token (personalized limit)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested in 1.85+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, max_num_value can be an experession, so you can simply enter the {TOKEN} or other variable in that question attribute.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make personalized survey with multiple numerical input when max_num_value (Maximum sum value) is different for each user and is loaded from the token use following tricks:&lt;br /&gt;
*Create 1st group with numerical input field (1000X10X11). &amp;quot;Limit&amp;quot;&lt;br /&gt;
*Add java script into this question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Custom_On_Load(){&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&#039;answer1000X10X11&#039;).value=&#039;{TOKEN:ATTRIBUTE_1}&#039;;&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&#039;answer1000X10X11&#039;).readOnly=1;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
TOKEN:ATTRIBUTE_1 is individual limit defined in token.&lt;br /&gt;
&lt;br /&gt;
readOnly=1 // user shouldn&#039;t change it.&lt;br /&gt;
*Create 2nd group with multiple numerical input and add &amp;quot;Max value from SGQA&amp;quot; with 1000X10X11 as argument.&lt;br /&gt;
&lt;br /&gt;
Note: If you don&#039;t want to show first field with numerical input (and show definied limit in different way) you can add 2 lines to above script to hide whole question:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;question85&#039;).style.display=&#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;display85&#039;).value=&#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
question85 and display85 are field names.&lt;br /&gt;
&lt;br /&gt;
Note: It&#039;s no possible to create it into one group, because all SGQA references can only refer to data on a previous page because when clicking next the answer is stored at the DB and the SGQA is replaced by querying the database.&lt;br /&gt;
&lt;br /&gt;
=Default values in array questions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.87+ (7557), IE 6/7, Firefox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of Version 1.92, many more question types support default values.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to allow you to pre-check default answers in all sub-questions of an array type question. You can select a column of the array to be checked as the page loads. The script first checks to see if a sub-question has already been answered and, if not, checks the default answer.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use script]].&lt;br /&gt;
#Create the array question.&lt;br /&gt;
#In the source of the array question add the following script.&lt;br /&gt;
#Replace&amp;quot;QQ&amp;quot; with the question ID and &amp;quot;CC&amp;quot; with the column number to be checked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // A function to pre-check a column of an array&lt;br /&gt;
&lt;br /&gt;
       function checkedDefault(qID, column) {&lt;br /&gt;
&lt;br /&gt;
           var checkedCol = column - 1;&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039; + qID + &#039; table.question tbody tr&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
               if ($(&#039;input.radio[checked=true]&#039;, this).length == 0) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;input.radio:eq(&#039; + checkedCol + &#039;)&#039;, this).attr(&#039;checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
       // Call the function with a question ID and column number&lt;br /&gt;
&lt;br /&gt;
       checkedDefault(QQ, CC);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Record group view time=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.87+ (8518), IE 6/7, Firefox 3.5, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, group view time is accurately recorded in the timings table if you choose the Record Timings survey option.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to populate a hidden question with the total time that a respondent views a group. If used in a group with only one question, it could be used to track the amount of time required to answer the question.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#In the group, create a short-text question. We will hide this later with JavaScript and populate it with the elapsed time.&lt;br /&gt;
#Place the following script in the source of the short-text question.&lt;br /&gt;
#Replace &amp;quot;QQ&amp;quot; in line 6 with the ID of the short-text question.&lt;br /&gt;
&lt;br /&gt;
The script populates the hidden question with the elapsed time since the group was opened. If a respondent leaves the group and then returns, the timer continues up from the elapsed time of the last visit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
       // call the functions with the hidden timer question ID&lt;br /&gt;
&lt;br /&gt;
       runTimer(QQ);&lt;br /&gt;
&lt;br /&gt;
       function runTimer(timeQID) {&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+timeQID).hide();&lt;br /&gt;
&lt;br /&gt;
           var initSec = &#039;0&#039;;&lt;br /&gt;
&lt;br /&gt;
           // Check for elapsed time from previous visits&lt;br /&gt;
&lt;br /&gt;
           if ($(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val()) {&lt;br /&gt;
&lt;br /&gt;
               var initTime = $(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               initTimeArr = initTime.split(&#039;:&#039;);&lt;br /&gt;
&lt;br /&gt;
               initSec = Number[[initTimeArr[0]*3600]]+Number[[initTimeArr[1]*60]]+Number(initTimeArr[2]);&lt;br /&gt;
&lt;br /&gt;
           }&lt;br /&gt;
&lt;br /&gt;
           // Run the timer update function&lt;br /&gt;
&lt;br /&gt;
           recordTime(initSec, timeQID);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
   // Timer update function&lt;br /&gt;
&lt;br /&gt;
   function recordTime(elapsedSec, timeQID){&lt;br /&gt;
&lt;br /&gt;
       elapsedSec++;&lt;br /&gt;
&lt;br /&gt;
       var h = Math.floor(elapsedSec / 3600);&lt;br /&gt;
&lt;br /&gt;
       var m = Math.floor(elapsedSec % 3600 / 60);&lt;br /&gt;
&lt;br /&gt;
       var s = Math.floor(elapsedSec % 3600 % 60);&lt;br /&gt;
&lt;br /&gt;
       var elapsedTime = [[h &amp;gt; 0 ? h + &amp;quot;:&amp;quot; : &amp;quot;00:&amp;quot;) + (m &amp;gt; 0 ? (m &amp;lt; 10 ? &amp;quot;0&amp;quot; : &amp;quot;&amp;quot;) + m + &amp;quot;:&amp;quot; : &amp;quot;00:&amp;quot;) + (s &amp;lt; 10 ? &amp;quot;0&amp;quot; : &amp;quot;&amp;quot;) + s);&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#question&#039;+timeQID+&#039; input.text&#039;).val(elapsedTime);&lt;br /&gt;
&lt;br /&gt;
        // Run the timer update function every second&lt;br /&gt;
&lt;br /&gt;
        setTimeout(&#039;recordTime(&#039;+elapsedSec+&#039;, &#039;+timeQID+&#039;)&#039;,1000);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Toggle visibility of groups=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to toggle the visibility of groups in an &amp;quot;all in one&amp;quot; survey. Initially the groups are hidden and there are links inserted to display the groups. It&#039;s useful to avoid the page being cluttered with many groups and lets the respondent focus on one at a time.&lt;br /&gt;
&lt;br /&gt;
It&#039;s [http://www.partnersinc.biz/surveys//index.php?sid=33613&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Set the survey to run in &amp;quot;all in one&amp;quot; mode.&lt;br /&gt;
#Add your groups and questions.&lt;br /&gt;
#Place the following script in the source of one of the questions in the first group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The comments in the script are pretty self-explanatory but it does the following:&lt;br /&gt;
&lt;br /&gt;
#initially hides all of the groups&lt;br /&gt;
#inserts a link above each one to toggle its display&lt;br /&gt;
#some styles are added to the clickable links but these could be done in template.css instead&lt;br /&gt;
#shows any groups that have an unanswered mandatory after a submit attempt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
		// Insert show/hide divs before all group wrapper divs&lt;br /&gt;
		$(&#039;&amp;lt;div class=&amp;quot;groupToggler&amp;quot;&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;).insertBefore(&#039;div[id^=&amp;quot;group-&amp;quot;]&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Add some text to the show/hide divs&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).each(function(i) {&lt;br /&gt;
			($( this ).text(&#039;Show/Hide Group &#039;+(i+1)+&#039;&#039;));&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Add some styles to the show/hide divs&lt;br /&gt;
		$(&#039;.groupToggler&#039;).css({&lt;br /&gt;
			&#039;padding&#039;:&#039;5px 0 10px 0&#039;,&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).css({&lt;br /&gt;
			&#039;text-decoration&#039;:&#039;underline&#039;,			&lt;br /&gt;
			&#039;cursor&#039;:&#039;pointer&#039;&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		// Add some hover effects to the show/hide divs&lt;br /&gt;
		$(&amp;quot;.groupToggler span&amp;quot;).hover(&lt;br /&gt;
			function () {&lt;br /&gt;
				$(this).css({&lt;br /&gt;
					&#039;text-decoration&#039;:&#039;none&#039;,&lt;br /&gt;
					&#039;font-weight&#039;:&#039;bold&#039;&lt;br /&gt;
				});&lt;br /&gt;
			}, &lt;br /&gt;
			function () {&lt;br /&gt;
				$(this).css({&lt;br /&gt;
					&#039;text-decoration&#039;:&#039;underline&#039;,&lt;br /&gt;
					&#039;font-weight&#039;:&#039;normal&#039;&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
		);&lt;br /&gt;
		&lt;br /&gt;
		// Initially hide all of the groups&lt;br /&gt;
		// Toggle their visibility when the show/hide is clicked&lt;br /&gt;
		$(&#039;.groupToggler span&#039;).click(function() {&lt;br /&gt;
			$(this).parent().next().toggle();&lt;br /&gt;
			return false;&lt;br /&gt;
		}).parent().next().hide();&lt;br /&gt;
		&lt;br /&gt;
		// Display any groups that have unanswered mandatories&lt;br /&gt;
		$(&#039;.errormandatory&#039;).parents(&#039;div[id^=&amp;quot;group-&amp;quot;]&#039;).show();&lt;br /&gt;
		&lt;br /&gt;
		// Some tidying up&lt;br /&gt;
		$(&#039;h1&#039;).next().next().hide();&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).css({&#039;margin-bottom&#039;:&#039;10px&#039;});&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).next().hide();&lt;br /&gt;
		$(&#039;.surveywelcome&#039;).next().next().hide();&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use jQuery Autocomplete plugin to suggest answers for text inputs=&lt;br /&gt;
&lt;br /&gt;
== 1.90 and previous versions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://docs.jquery.com/Plugins/Autocomplete jQuery Autocomplete] plugin to provide a respondent a list of suggested answers that the they can select from as they type in a text input.&lt;br /&gt;
&lt;br /&gt;
Although the plugin allows for much more complex applications, the two that I use most frequently are outlined below. The first method uses a relatively small list of suggestions that is stored in an array locally. The second is a little more complex - it uses a remote CSV file of suggestions that is accessed through AJAX an PHP.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve put together a small demonstration [http://www.partnersinc.biz/surveys//index.php?sid=78611&amp;amp;newtest=Y&amp;amp;lang=en here] and implementation is as follows.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Both methods:&#039;&#039;&#039;&lt;br /&gt;
*[http://docs.jquery.com/Plugins/Autocomplete Download the plugin]&lt;br /&gt;
*Place the files &#039;&#039;jquery.autocomplete.css&#039;&#039; and &#039;&#039;jquery.autocomplete.js&#039;&#039; in your template directory&lt;br /&gt;
*Add the following code inside the &amp;lt;head&amp;gt; element of startpage.pstpl&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.autocomplete.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;{TEMPLATEURL}jquery.autocomplete.css&amp;quot; /&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 1 (&amp;quot;States&amp;quot; question in the demo):&#039;&#039;&#039;&lt;br /&gt;
*Create a text input question&lt;br /&gt;
*Add the following script to the source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace the states with your list of suggestions (comma separated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var q1ID = QQ;&lt;br /&gt;
&lt;br /&gt;
		var states = &amp;quot;Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware, District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky, Louisiana,Maine,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York, North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Maryland,Massachusetts,Michigan, Minnesota,Mississippi,Missouri,Pennsylvania,Rhode Island,South Carolina,South Dakota, Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming&amp;quot;.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.text&#039;).autocomplete(states, {&lt;br /&gt;
			matchContains: true,&lt;br /&gt;
			minChars: 0&lt;br /&gt;
		});&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 2 (&amp;quot;Countries&amp;quot; question in the demo):&#039;&#039;&#039;&lt;br /&gt;
*Place the CSV file of suggestions in your template directory. &lt;br /&gt;
*Place a PHP file containing the code below in your template directory&lt;br /&gt;
*Replace &amp;quot;countries2.csv&amp;quot; with your CSV filename (you could make this more universal by passing the filename in the URL)&lt;br /&gt;
*This file will grab the contents of the CSV and encode them in JSON format that the JavaScript can use&lt;br /&gt;
*Place the JavaScript code below in ths source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace &amp;quot;templates/yourTemplate/countries.php&amp;quot; with the path to the PHP file (from LimeSurvey root)&lt;br /&gt;
*This script will grab the jsonized data from the PHP file and load it into an array that the plugin can use&lt;br /&gt;
&lt;br /&gt;
PHP code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
	$countriesArr = array();&lt;br /&gt;
&lt;br /&gt;
	$file_handle = fopen(&amp;quot;countries2.csv&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	while (!feof($file_handle) ) {&lt;br /&gt;
		$line_of_text = fgetcsv($file_handle);&lt;br /&gt;
		array_push($countriesArr, $line_of_text[0]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose($file_handle);&lt;br /&gt;
&lt;br /&gt;
	echo json_encode($countriesArr);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qID = QQ;&lt;br /&gt;
		var url = &amp;quot;templates/yourTemplate/countries.php&amp;quot;;&lt;br /&gt;
		var countriesArr = new Array();&lt;br /&gt;
&lt;br /&gt;
		$.getJSON(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			$(data).each(function(i, item){&lt;br /&gt;
				countriesArr.push(item);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#question&#039;+qID+&#039; input.text&#039;).autocomplete(countriesArr, {&lt;br /&gt;
				matchContains: true,&lt;br /&gt;
				minChars: 0&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.91 and later versions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://jqueryui.com/demos/autocomplete/ Autocomplete widget] included with jQuery UI to provide a respondent a list of suggested answers that the they can select from as they type in a text input.&lt;br /&gt;
&lt;br /&gt;
Although the plugin allows for much more complex applications, the two that I use most frequently are outlined below. The first method uses a relatively small list of suggestions that is stored in an array locally. The second is a little more complex - it uses a remote CSV file of suggestions that is accessed through AJAX an PHP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Both methods:&#039;&#039;&#039;&lt;br /&gt;
*Add the following styles to the end of your &#039;template.css&#039; file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;/* Autocomplete styles */&lt;br /&gt;
&lt;br /&gt;
ul.ui-autocomplete {&lt;br /&gt;
	width: 250px !important;&lt;br /&gt;
	padding: 5px 10px;&lt;br /&gt;
	list-style: none;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 1 (use local JavaScript array for data):&#039;&#039;&#039;&lt;br /&gt;
*Create a text input question&lt;br /&gt;
*Add the following script to the source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace the states with your list of suggestions (comma separated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var q1ID = QQ;&lt;br /&gt;
&lt;br /&gt;
		var states = &amp;quot;Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware, District of Columbia,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky, Louisiana,Maine,Montana,Nebraska,Nevada,New Hampshire,New Jersey,New Mexico,New York, North Carolina,North Dakota,Ohio,Oklahoma,Oregon,Maryland,Massachusetts,Michigan, Minnesota,Mississippi,Missouri,Pennsylvania,Rhode Island,South Carolina,South Dakota, Tennessee,Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming&amp;quot;.split(&#039;,&#039;);&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#question&#039;+q1ID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
			source: states&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method 2 (use remote CSV file for data):&#039;&#039;&#039;&lt;br /&gt;
*Place the CSV file of suggestions in your template directory&lt;br /&gt;
*Place a PHP file containing the code below in your template directory&lt;br /&gt;
*Replace &amp;quot;countries2.csv&amp;quot; with your CSV filename (you could make this more universal by passing the filename in the URL)&lt;br /&gt;
*This file will grab the contents of the CSV and encode them in JSON format that the JavaScript can use&lt;br /&gt;
*Place the JavaScript code below in ths source of the text question&lt;br /&gt;
*Replace &amp;quot;QQ&amp;quot; with the ID of the text input question&lt;br /&gt;
*Replace &amp;quot;templates/yourTemplate/countries.php&amp;quot; with the path to the PHP file (from LimeSurvey root)&lt;br /&gt;
*This script will grab the jsonized data from the PHP file and load it into an array that the plugin can use&lt;br /&gt;
&lt;br /&gt;
PHP code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
	$countriesArr = array();&lt;br /&gt;
&lt;br /&gt;
	$file_handle = fopen(&amp;quot;countries2.csv&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	while (!feof($file_handle) ) {&lt;br /&gt;
		$line_of_text = fgetcsv($file_handle);&lt;br /&gt;
		array_push($countriesArr, $line_of_text[0]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose($file_handle);&lt;br /&gt;
&lt;br /&gt;
	echo json_encode($countriesArr);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qID = QQ;&lt;br /&gt;
		var url = &amp;quot;templates/yourTemplate/countries.php&amp;quot;;&lt;br /&gt;
		var dataArr = [];&lt;br /&gt;
&lt;br /&gt;
		$.getJSON(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			$.each(data,function(i, item){&lt;br /&gt;
				dataArr.push(item);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			$(&#039;#question&#039;+qID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
				source: dataArr&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Use autocomplete to populate several fields==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, IE 7/8/9, Firefox 18&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses the [http://jqueryui.com/demos/autocomplete/ Autocomplete widget] included with jQuery UI and the [https://code.google.com/p/jquery-csv/source/browse/jquery.csv.js?r=f13189b2550a770ccaa777f1d747bc860b943fe7 jquery.csv.js] plugin to provide a respondent with a list of suggested answers as they type in a text input and then to automatically populate other fields depending on the selection.&lt;br /&gt;
&lt;br /&gt;
For example, if you have 3 questions - &amp;quot;Name&amp;quot;, &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; - you can use this workaround to autocomplete the &amp;quot;Name&amp;quot; question and then the &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; questions can be automatically populated with values associated with the selected name.&lt;br /&gt;
*Download the [https://code.google.com/p/jquery-csv/source/browse/jquery.csv.js?r=f13189b2550a770ccaa777f1d747bc860b943fe7 jquery.csv.js] plugin and place it in your template folder&lt;br /&gt;
*If using LimeSurvey 1.9x, add the following line to your startpage.pstpl BEFORE the tag for template.js, if using 2.x, add it AFTER the {TEMPLATEJS} placeholder&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.csv.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Create your CSV file with 3 columns (name, ID, email) as in this example and place it in your template folder&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;Bob,    Bob&#039;s ID,    Bob&#039;s email&lt;br /&gt;
&lt;br /&gt;
Andy,    Andy&#039;s ID,    Andy&#039;s email&lt;br /&gt;
&lt;br /&gt;
Sam,    Sam&#039;s ID,    Sam&#039;s email&lt;br /&gt;
&lt;br /&gt;
Tony,    Tony&#039;s ID,    Tony&#039;s email&lt;br /&gt;
&lt;br /&gt;
Fred,    Fred&#039;s ID,    Fred&#039;s email&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Create your 3 questions - &amp;quot;Name&amp;quot;, &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot;. They must be in the same group/page.&lt;br /&gt;
*Add the following styles to the end of your &#039;template.css&#039; file&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;/* Autocomplete styles */&lt;br /&gt;
&lt;br /&gt;
ul.ui-autocomplete {&lt;br /&gt;
&lt;br /&gt;
   width: 250px !important;&lt;br /&gt;
&lt;br /&gt;
   padding: 5px 10px;&lt;br /&gt;
&lt;br /&gt;
   list-style: none;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Add the following script to the source of one of the questions&lt;br /&gt;
*Replace:&lt;br /&gt;
**&amp;quot;NN&amp;quot; with the &amp;quot;Name&amp;quot; question ID&lt;br /&gt;
**&amp;quot;II&amp;quot; with the &amp;quot;ID&amp;quot; question ID&lt;br /&gt;
**&amp;quot;EE&amp;quot; with the &amp;quot;Email&amp;quot; question ID&lt;br /&gt;
*Modify the path to your CSV file&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		var qNameID = NN;&lt;br /&gt;
&lt;br /&gt;
		var qIDID = II;&lt;br /&gt;
&lt;br /&gt;
		var qEmailID = EE;&lt;br /&gt;
&lt;br /&gt;
		var url = &amp;quot;upload/templates/yourTemplate/yourCsvFile.csv&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		// Create an array to hold the names&lt;br /&gt;
		var namesArr = new Array();&lt;br /&gt;
&lt;br /&gt;
		// Grab the CSV contents&lt;br /&gt;
		$.get(url,function(data){&lt;br /&gt;
&lt;br /&gt;
			// Convert CSV contents to an array of arrays&lt;br /&gt;
			fullArray = $.csv.toArrays(data);&lt;br /&gt;
&lt;br /&gt;
			// Load the names array&lt;br /&gt;
			$(fullArray).each(function(i, item){&lt;br /&gt;
				namesArr.push(item[0]);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			// Initialise the autocomplete plugin&lt;br /&gt;
			$(&#039;#question&#039;+qNameID+&#039; input.text&#039;).autocomplete({&lt;br /&gt;
				source: namesArr,&lt;br /&gt;
				// Event fired when a selection is made (ui.item.value refers to the selected item)&lt;br /&gt;
				select: function(event, ui) {&lt;br /&gt;
					// Find the &amp;quot;ID&amp;quot; and &amp;quot;Email&amp;quot; values associated with the selected name value and load those questions&lt;br /&gt;
					$(fullArray).each(function(i, item){&lt;br /&gt;
						if(item[0] == ui.item.value) {&lt;br /&gt;
							// The value from column 2 of the CSV&lt;br /&gt;
							$(&#039;#question&#039;+qIDID+&#039; input.text&#039;).val(item[1]);&lt;br /&gt;
							// The value from column 3 of the CSV&lt;br /&gt;
							$(&#039;#question&#039;+qEmailID+&#039; input.text&#039;).val(item[2]);&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Drag and Drop Rankings {{Deprecated|2.0}} =&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }} &lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking - Version 1.90 to 1.92==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+ &amp;amp; 1.91RC4, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }} &lt;br /&gt;
&lt;br /&gt;
This workaround is a modification of the workaround below and also uses [http://jqueryui.com/demos/sortable/#connect-lists JQuery connected sortables]. Thanks to the author of that workaround.&lt;br /&gt;
&lt;br /&gt;
[[File:Untitled-12.png]]&lt;br /&gt;
&lt;br /&gt;
Modifications include:&lt;br /&gt;
*Allow for multiple drag-n-drop ranking questions on a page&lt;br /&gt;
*Handle minimum and maximum answers settings&lt;br /&gt;
*Allow double clicking of items to add or remove them from the ranking list&lt;br /&gt;
*Work with the new shipped jQuery UI&lt;br /&gt;
&lt;br /&gt;
There is a &#039;&#039;&#039;[http://www.partnersinc.biz/surveys//index.php?sid=36981&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the large script below in your template.js file.&lt;br /&gt;
#Place the small script below in the source a ranking question, (this applies the &amp;quot;dragDropRank&amp;quot; function to the question). Replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID].&lt;br /&gt;
**Note: the LimeSurvey translations will be automatically used for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; header labels but can be overridden with custom labels - see the example calls below.&lt;br /&gt;
#Insert the CSS below at the end of template.css (these styles are for the default template).&lt;br /&gt;
&lt;br /&gt;
NOTE: I have not tested this workaround with conditions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code for template.js:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
function dragDropRank(qID, choiceText, rankText) {&lt;br /&gt;
&lt;br /&gt;
	if(!choiceText) {&lt;br /&gt;
		choiceText = $(&#039;#question&#039;+qID+&#039; td.label label&#039;).text();&lt;br /&gt;
	}&lt;br /&gt;
	if(!rankText) {&lt;br /&gt;
		rankText = $(&#039;#question&#039;+qID+&#039; td.output tr:first td:eq(1)&#039;).text();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Add a class to the question&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039;&#039;).addClass(&#039;dragDropRanking&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Hide the original question in LimeSurvey (so that we can replace with drag and drop)&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; .rank, #question&#039;+qID+&#039; .questionhelp&#039;).hide();&lt;br /&gt;
	&lt;br /&gt;
	// Turn off display of question (to override error checking built into LimeSurvey ranking question)&lt;br /&gt;
	//$(&#039;#display&#039;+qID).val(&#039;off&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Add connected sortables elements to the question&lt;br /&gt;
	var htmlCode = &#039;&amp;lt;table class=&amp;quot;dragDropTable&amp;quot;&amp;gt; \&lt;br /&gt;
		&amp;lt;tbody&amp;gt; \&lt;br /&gt;
			&amp;lt;tr&amp;gt; \&lt;br /&gt;
				&amp;lt;td&amp;gt; \&lt;br /&gt;
					&amp;lt;span class=&amp;quot;dragDropHeader choicesLabel&amp;quot;&amp;gt;&#039;+choiceText+&#039;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt; \&lt;br /&gt;
					&amp;lt;div class=&amp;quot;ui-state-highlight dragDropChoices&amp;quot;&amp;gt; \&lt;br /&gt;
						&amp;lt;ul id=&amp;quot;sortable1&#039;+qID+&#039;&amp;quot; class=&amp;quot;connectedSortable&#039;+qID+&#039; dragDropChoiceList&amp;quot;&amp;gt; \&lt;br /&gt;
							&amp;lt;li&amp;gt;Choices&amp;lt;/li&amp;gt; \&lt;br /&gt;
						&amp;lt;/ul&amp;gt; \&lt;br /&gt;
					&amp;lt;/div&amp;gt; \&lt;br /&gt;
				&amp;lt;/td&amp;gt; \&lt;br /&gt;
				&amp;lt;td&amp;gt; \&lt;br /&gt;
					&amp;lt;span class=&amp;quot;dragDropHeader rankingLabel&amp;quot;&amp;gt;&#039;+rankText+&#039;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt; \&lt;br /&gt;
					&amp;lt;div class=&amp;quot;ui-state-highlight dragDropRanks&amp;quot;&amp;gt; \&lt;br /&gt;
						&amp;lt;ol id=&amp;quot;sortable2&#039;+qID+&#039;&amp;quot; class=&amp;quot;connectedSortable&#039;+qID+&#039; dragDropRankList&amp;quot;&amp;gt; \&lt;br /&gt;
							&amp;lt;li&amp;gt;Ranks&amp;lt;/li&amp;gt; \&lt;br /&gt;
						&amp;lt;/ol&amp;gt; \&lt;br /&gt;
					&amp;lt;/div&amp;gt; \&lt;br /&gt;
				&amp;lt;/td&amp;gt; \&lt;br /&gt;
			&amp;lt;/tr&amp;gt; \&lt;br /&gt;
		&amp;lt;/tbody&amp;gt; \&lt;br /&gt;
					&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
	$(htmlCode).insertAfter(&#039;#question&#039;+qID+&#039; table.rank&#039;);&lt;br /&gt;
	&lt;br /&gt;
	// Remove placeholder list items (have to have one item so that LimeSurvey doesn&amp;quot;t remove the &amp;lt;ul&amp;gt;)&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li, #sortable2&#039;+qID+&#039; li&#039;).remove();&lt;br /&gt;
	&lt;br /&gt;
	// Load any previously-set values&lt;br /&gt;
	loadDragDropRank(qID);&lt;br /&gt;
	&lt;br /&gt;
	// Find the number of LimeSurvey ranking inputs (&amp;quot;Maximum answers&amp;quot;)&lt;br /&gt;
	var maxAnswer = $(&#039;#question&#039;+qID+&#039; td.output input.text&#039;).length;&lt;br /&gt;
	&lt;br /&gt;
	// Set up the connected sortable&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039;, #sortable2&#039;+qID+&#039;&#039;).sortable({&lt;br /&gt;
		connectWith: &#039;.connectedSortable&#039;+qID+&#039;&#039;,&lt;br /&gt;
		placeholder: &#039;ui-sortable-placeholder&#039;,&lt;br /&gt;
		helper: &#039;clone&#039;,&lt;br /&gt;
		revert: 50,&lt;br /&gt;
		receive: function(event, ui) {&lt;br /&gt;
			if($(&#039;#sortable2&#039;+qID+&#039; li&#039;).length &amp;gt; maxAnswer) {&lt;br /&gt;
				alert (&#039;You can only rank a maximum of &#039;+maxAnswer+&#039; choices.&#039;);&lt;br /&gt;
				$(ui.sender).sortable(&#039;cancel&#039;);&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		stop: function(event, ui) {&lt;br /&gt;
			$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			updateDragDropRank(qID);&lt;br /&gt;
		}&lt;br /&gt;
	}).disableSelection();&lt;br /&gt;
	&lt;br /&gt;
	// Get the list of choices from the LimeSurvey question and copy them as items into the sortable choices list&lt;br /&gt;
	$(&#039;#CHOICES_&#039; + qID).children().each(function(index, Element) {&lt;br /&gt;
		var liCode = &#039;&amp;lt;li class=&amp;quot;ui-state-default&amp;quot; id=&amp;quot;choice_&#039; + $(this).attr(&amp;quot;value&amp;quot;) + &#039;&amp;quot;&amp;gt;&#039; + this.text + &#039;&amp;lt;/li&amp;gt;&#039;&lt;br /&gt;
		$(liCode).appendTo(&#039;#sortable1&#039;+qID+&#039;&#039;);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Allow users to double click to move to selections from list to list&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li&#039;).live(&#039;dblclick&#039;, function() {&lt;br /&gt;
		if($(&#039;#sortable2&#039;+qID+&#039; li&#039;).length == maxAnswer) {&lt;br /&gt;
			alert (&#039;You can only rank a maximum of &#039;+maxAnswer+&#039; choices.&#039;);&lt;br /&gt;
			return false;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(this).appendTo(&#039;#sortable2&#039;+qID+&#039;&#039;);&lt;br /&gt;
			$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
			updateDragDropRank(qID);&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	$(&#039;#sortable2&#039;+qID+&#039; li&#039;).live(&#039;dblclick&#039;, function() {&lt;br /&gt;
		$(this).appendTo(&#039;#sortable1&#039;+qID+&#039;&#039;);&lt;br /&gt;
		$(&#039;#sortable2&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
		$(&#039;#sortable1&#039;+qID+&#039;&#039;).sortable(&#039;refresh&#039;);&lt;br /&gt;
		updateDragDropRank(qID);&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function copies the drag and drop sortable data into the LimeSurvey ranking list.&lt;br /&gt;
function updateDragDropRank(qID) {&lt;br /&gt;
&lt;br /&gt;
	// Reload the LimeSurvey choices select element&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	$(&#039;#sortable2&#039;+qID+&#039; li&#039;).each(function(index) {&lt;br /&gt;
		$(this).attr(&#039;value&#039;, index+1);&lt;br /&gt;
		&lt;br /&gt;
		// Get value of ranked item&lt;br /&gt;
		var liID = $(this).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Save to an array&lt;br /&gt;
		rankees[rankees.length] = { &amp;quot;r_name&amp;quot;:$(this).text(),&amp;quot;r_value&amp;quot;:liIDArray[1] };&lt;br /&gt;
	});&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
		if (rankees.length &amp;gt; index) {&lt;br /&gt;
			$(this).val(rankees[index].r_name);&lt;br /&gt;
			$(this).next(&#039;input&#039;).attr(&#039;value&#039;, rankees[index].r_value);&lt;br /&gt;
		} else {&lt;br /&gt;
			$(this).val(&#039;&#039;);&lt;br /&gt;
			$(this).next().val(&#039;&#039;);&lt;br /&gt;
		}&lt;br /&gt;
	 });&lt;br /&gt;
	 &lt;br /&gt;
	// Reload the LimeSurvey choices select element (we need this for &amp;quot;Minimum answers&amp;quot; code)&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; td.label select option&#039;).remove();&lt;br /&gt;
	$(&#039;#sortable1&#039;+qID+&#039; li&#039;).each(function(index) {&lt;br /&gt;
		var liText = $(this).text();&lt;br /&gt;
		var liID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		var optionCode = &#039;&amp;lt;option value=&amp;quot;&#039;+liIDArray[1]+&#039;&amp;quot;&amp;gt;&#039;+liText+&#039;&amp;lt;/option&amp;gt;&#039;;&lt;br /&gt;
		$(optionCode).appendTo(&#039;#question&#039;+qID+&#039; td.label select&#039;);&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Hack for IE6&lt;br /&gt;
	if ($.browser.msie &amp;amp;&amp;amp; $.browser.version.substr(0,1)&amp;lt;7) {&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; select&#039;).show();&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; select&#039;).hide();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function is called on page load to see if there are any items already ranked (from a previous visit&lt;br /&gt;
// or cached due to a page change.  If so, the already-ranked items are loaded into the sortable list&lt;br /&gt;
function loadDragDropRank(qID) {&lt;br /&gt;
&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	&lt;br /&gt;
	// Loop through each item in the built-in LimeSurvey ranking list looking for non-empty values&lt;br /&gt;
	$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;/div&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
	&lt;br /&gt;
		// Check to see if the current item has a value&lt;br /&gt;
		if ($(this).val()) {&lt;br /&gt;
		&lt;br /&gt;
			// Item has a value - save to the array&lt;br /&gt;
			// Use this element to contain the name and the next for the value (numeric)&lt;br /&gt;
			rankees[rankees.length] = { &amp;quot;r_name&amp;quot;:$(this).val(),&amp;quot;r_value&amp;quot;:$(this).next().val() };&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Now that we have a list of all the pre-ranked items, populate the sortable list&lt;br /&gt;
	// Note that the items *won&amp;quot;t* appear in the main list because LimeSurvey has removed them.&lt;br /&gt;
	$.each(rankees, function(index, value) {&lt;br /&gt;
	&lt;br /&gt;
		// Create the items in the sortable&lt;br /&gt;
		var liCode = &#039;&amp;lt;li class=&amp;quot;ui-state-default&amp;quot; id=&amp;quot;choice_&#039; + value.r_value + &#039;&amp;quot;&amp;gt;&#039; + value.r_name + &#039;&amp;lt;/li&amp;gt;&#039;;&lt;br /&gt;
		$(liCode).appendTo(&#039;#sortable2&#039;+qID+&#039;&#039;);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s) using the LimeSurvey translations for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; element header labels&#039;&#039;&#039; (replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRank(QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix for later versions of 1.91+&#039;&#039;&#039;&lt;br /&gt;
In my version of LimeSurvey 1.91+, build 11026, this drag-n-drop workaround was not saving the selections properly. I&#039;m not sure if that&#039;s because of my template, or other jquery uses, but I fixed it by making the following modifications to the above code placed into template.js.&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having problems (and it&#039;s definitely worth testing that the rankings are actually saving into your response table before proceeding with the survey) give this a try.&lt;br /&gt;
&lt;br /&gt;
In the &#039;updateDragDropRank(qID)&#039; function, replace the line:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&amp;lt;script&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&amp;lt;script&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name^=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the &#039;loadDragDropRank(qID) function, replace the line:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&amp;lt;script&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name&amp;lt;/div&amp;gt;=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&amp;lt;script&amp;gt;&lt;br /&gt;
$(&#039;#question&#039;+qID+&#039; input[name^=&amp;quot;RANK_&amp;quot;]&#039;).each(function(index) {&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s) using custom text for the &amp;quot;Choices&amp;quot; and &amp;quot;Rankings&amp;quot; element header labels&#039;&#039;&#039; (replace &amp;quot;QQ&amp;quot; with the ranking [http://docs.limesurvey.org/SGQA+identifier&amp;amp;structure;=English+Instructions+for+LimeSurvey#General_Description question ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRank(QQ, &#039;Custom Choices Label&#039;, &#039;Custom Rankings Label&#039;);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Styles for template.css:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
/* Drag-n-drop ranking styles */&lt;br /&gt;
.dragDropTable {&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable td {&lt;br /&gt;
	vertical-align: top;&lt;br /&gt;
	width: 50%;&lt;br /&gt;
	padding-right: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropHeader {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoices,&lt;br /&gt;
.dragDropTable .dragDropRanks {&lt;br /&gt;
	margin: 5px 0 0 0;&lt;br /&gt;
	background: transparent none;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoiceList,&lt;br /&gt;
.dragDropTable .dragDropRankList {&lt;br /&gt;
	float: left;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	min-height: 2.4em;&lt;br /&gt;
	_height: 2.4em; /* IE6 and below hack */&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	list-style-type: none;&lt;br /&gt;
	background: #FBFBFB none;&lt;br /&gt;
	border: 1px solid #CCCCCC;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.dragDropTable .dragDropChoiceList li,&lt;br /&gt;
.dragDropTable .dragDropRankList li {&lt;br /&gt;
	margin: 3px;&lt;br /&gt;
	*margin-left: -13px; /* IE7 and below */&lt;br /&gt;
	padding: 3px;&lt;br /&gt;
	min-height: 1.3em;&lt;br /&gt;
	_height: 1.3em; /* IE6 and below hack */&lt;br /&gt;
	font-weight: normal;&lt;br /&gt;
	cursor: move;&lt;br /&gt;
	display: block; /* Force the li to full width */&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking using Images - Version 1.90 to 1.92==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+ &amp;amp; 1.91RC4, IE 6/7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }}&lt;br /&gt;
&lt;br /&gt;
This workaround works in conjunction with the above workaround to allow ranking of images.&lt;br /&gt;
&lt;br /&gt;
[[File:Untitled-11.png]]&lt;br /&gt;
&lt;br /&gt;
There is a &#039;&#039;&#039;[http://www.partnersinc.biz/surveys//index.php?sid=36981&amp;amp;newtest=Y&amp;amp;lang=en demonstrated here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
1) Follow the above workaround to get basic drag-n-drop functionality in your ranking question.&lt;br /&gt;
&lt;br /&gt;
2) Insert your images in the ranking question text or help section after any text that you wish to have there (we&#039;ll move them later with JavaScript).&lt;br /&gt;
&lt;br /&gt;
3) Give the images &#039;&#039;&#039;EXACTLY&#039;&#039;&#039; the same IDs as the answer code you would like them to be associated with:[[File:Untitled-8.png]]&lt;br /&gt;
&lt;br /&gt;
4) Place the first script below in your template.js file.&lt;br /&gt;
&lt;br /&gt;
5) Place the second script below in the source the ranking question &#039;&#039;&#039;AFTER&#039;&#039;&#039; the initial call for the dragDropRank function from the workaround above. Replace &amp;quot;QQ&amp;quot; with the ID of the ranking question (this applies the &amp;quot;dragDropRankImages&amp;quot; function to the question).&lt;br /&gt;
&lt;br /&gt;
6) Insert the CSS below at the end of template.css. Replace &amp;quot;11&amp;quot; with your question ID. These styles are for the default template using 50x50px images (as in the demo) and may need to be modified for other templates or image sizes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code for template.js:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function dragDropRankImages(qID) {&lt;br /&gt;
&lt;br /&gt;
	$(&#039;.connectedSortable&#039;+qID+&#039; li&#039;).each(function(i) {&lt;br /&gt;
&lt;br /&gt;
		// Remove any text in the sortable choice or rank items&lt;br /&gt;
		$(this).text(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Move the images into the appropriate sortable list item&lt;br /&gt;
		var liID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		liIDArray = liID.split(&#039;_&#039;);&lt;br /&gt;
		$(&#039;#question&#039;+qID+&#039; img#&#039;+liIDArray[1]+&#039;&#039;).appendTo(this);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code in the source of the question(s):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		dragDropRankImages(QQ);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Styles for template.css:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Drag-n-drop for ranking images */&lt;br /&gt;
#question11 .dragDropTable {&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable .dragDropChoiceList,&lt;br /&gt;
#question11 .dragDropTable .dragDropRankList {&lt;br /&gt;
	min-height: 60px;&lt;br /&gt;
	_height: 60px; /* IE6 and below hack */&lt;br /&gt;
	width: auto;&lt;br /&gt;
	min-width: 60px;&lt;br /&gt;
	_width: 60px; /* IE6 and below hack */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable li {&lt;br /&gt;
	background: 0 none;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
	height: 50px;&lt;br /&gt;
	width: 50px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#question11 .dragDropTable li img {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	border: 0 none;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking for iPad - Version 1.91 and newer==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LimeSurvey 1.91, iPad 2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround extends the above workarounds to work with the touch interface on iPads.&lt;br /&gt;
&lt;br /&gt;
1) Follow the [[Workarounds: Manipulating a survey at runtime using Javascript#Drag and Drop Ranking - Version 1.90 and newer|Drag and Drop Ranking - Version 1.90 and newer]] workaround above to get basic drag-n-drop functionality in your ranking question.&lt;br /&gt;
&lt;br /&gt;
2) Download the [https://github.com/furf/jquery-ui-touch-punch jQuery.ui.touch-punch.js plugin] and save it in your template directory.&lt;br /&gt;
&lt;br /&gt;
3) Replace this line in your startpage.pstpl:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}template.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;With this:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}jquery.ui.touch-punch.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;{TEMPLATEURL}template.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drag and Drop Ranking - Version 1.86==&lt;br /&gt;
&lt;br /&gt;
Tested with 1.86 on IE 7,8, FireFox 3, Chrome, and Safari 4&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=In 2.0 and up, this system Ranking question use jqueryui-sortable. This workaround is deprecated. }}&lt;br /&gt;
&lt;br /&gt;
This workaround uses [http://jqueryui.com/demos/sortable/#connect-lists JQuery connected sortables] to modify a ranking question and allow the survey taker to drag and drop choices instead of clicking.  The nice thing is that the choices can be easily re-arranged or removed from the ranking, all by drag and drop.&lt;br /&gt;
&lt;br /&gt;
I used it for a voting application and some of the element names reflect that use.&lt;br /&gt;
&lt;br /&gt;
It looks best when some CSS is added to control the appearance of the boxers around each choice.&lt;br /&gt;
&lt;br /&gt;
[[File:drag-n-drop.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
	// Question ID global variable&lt;br /&gt;
	var questionID;&lt;br /&gt;
	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
	&lt;br /&gt;
		// Grab the question ID[[File:drag-n-drop.png]]&lt;br /&gt;
		// This is something with a class of &amp;quot;ranking&amp;quot; and an ID that starts with &amp;quot;questionXXXXX&amp;quot;.  The X&#039;s represent the question ID&lt;br /&gt;
		var entire_questionID = $(&amp;quot;.ranking[id&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&#039;question&#039;]&amp;quot;).attr(&#039;id&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Get just the question number (ID)&lt;br /&gt;
		var patt=/\d+$/;&lt;br /&gt;
		questionID=patt.exec(entire_questionID);&lt;br /&gt;
		&lt;br /&gt;
		// Hide the original quetion in LimeSurvey (so that we can replace with drag and drop)&lt;br /&gt;
		$(&amp;quot;.rank, .questionhelp&amp;quot;).hide();&lt;br /&gt;
		&lt;br /&gt;
		// Turn off display of question (to override error checking built into LimeSurvey ranking question)&lt;br /&gt;
		$(&amp;quot;#display&amp;quot;+questionID).val(&amp;quot;off&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Add connected sortables to the question&lt;br /&gt;
		var html_code = &amp;quot;&amp;lt;table style=&#039;border: medium none ; width: 770px; margin-left: auto; \&lt;br /&gt;
								margin-right: auto;&#039;&amp;gt;&amp;lt;tbody&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td style=&#039;width: 590px; vertical-align: top;&#039;&amp;gt;&amp;lt;h3&amp;gt;List of Candidates:&amp;lt;/h3&amp;gt; \&lt;br /&gt;
								&amp;lt;div class=&#039;ui-state-highlight&#039; style=&#039;margin: 5px; float: left;&#039; id=&#039;ballot_list&#039;&amp;gt; \&lt;br /&gt;
								&amp;lt;ul id=&#039;sortable1&#039; class=&#039;connectedSortable&#039;&amp;gt;&amp;lt;li&amp;gt;Candidates&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt; \&lt;br /&gt;
								&amp;lt;td style=&#039;vertical-align: top;&#039;&amp;gt;&amp;lt;h3&amp;gt;Your selections:&amp;lt;/h3&amp;gt;&amp;lt;div class=&#039;ui-state-highlight&#039; \&lt;br /&gt;
								style=&#039;margin: 5px; float: left;&#039; id=&#039;voting_selections&#039;&amp;gt;&amp;lt;ol id=&#039;sortable2&#039; class=&#039;connectedSortable&#039;&amp;gt; \&lt;br /&gt;
								&amp;lt;li&amp;gt;Voting Area&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;;&lt;br /&gt;
		$(html_code).appendTo(&amp;quot;#question&amp;quot; + questionID);&lt;br /&gt;
		&lt;br /&gt;
		// Remove list items (have to have one item so that LimeSurvey doesn&#039;t remove the &amp;lt;ul&amp;gt;)&lt;br /&gt;
		$(&amp;quot;#sortable1 li, #sortable2 li&amp;quot;).remove();&lt;br /&gt;
		&lt;br /&gt;
		// Load any previously-set values&lt;br /&gt;
		loadRanking();&lt;br /&gt;
		&lt;br /&gt;
		// Load jQuery UI&lt;br /&gt;
		$.getScript(&amp;quot;/scripts/jquery/jquery-ui.js&amp;quot;, function() {&lt;br /&gt;
		&lt;br /&gt;
			// After JQuery UI finishes loading, set up the connected sortable.&lt;br /&gt;
			$(&amp;quot;#sortable1, #sortable2&amp;quot;).sortable({&lt;br /&gt;
				connectWith: &#039;.connectedSortable&#039;,&lt;br /&gt;
				placeholder: &#039;ui-sortable-placeholder&#039;,&lt;br /&gt;
				stop: function(event, ui) {&lt;br /&gt;
					$(&amp;quot;#sortable1&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
					$(&amp;quot;#sortable2&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
					updateRanking();&lt;br /&gt;
					}&lt;br /&gt;
			}).disableSelection();&lt;br /&gt;
			&lt;br /&gt;
			// Get the list of candidates from the built-in LimeSurvey question and copy them as items in sortable1&lt;br /&gt;
			$(&amp;quot;#CHOICES_&amp;quot; + questionID).children().each(function(index, Element) {&lt;br /&gt;
				li_tag = &amp;quot;&amp;lt;li class=&#039;ui-state-default&#039; id=&#039;choice_&amp;quot; + $(this).attr(&#039;value&#039;) + &amp;quot;&#039;&amp;gt;&amp;quot; + this.text + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;&lt;br /&gt;
				$(li_tag).appendTo(&amp;quot;#sortable1&amp;quot;); }	);&lt;br /&gt;
				&lt;br /&gt;
			// Make sure the submit button is showing&lt;br /&gt;
			$(&amp;quot;:submit[value|=&#039; Submit&#039;]&amp;quot;).show();&lt;br /&gt;
			&lt;br /&gt;
			// Show a confirmation alert upon submit&lt;br /&gt;
			$(&amp;quot;form&amp;quot;).submit(function() {&lt;br /&gt;
			&lt;br /&gt;
				// Override the built-in &amp;quot;disable navigation buttons&amp;quot; feature&lt;br /&gt;
				$(&#039;#moveprevbtn, #movenextbtn, #movesubmitbtn&#039;).attr(&#039;disabled&#039;, &#039;&#039;);&lt;br /&gt;
				var validated = confirm(&amp;quot;Cast your ballot now?&amp;quot;);&lt;br /&gt;
				if (validated) { return true; } else { return false; }&lt;br /&gt;
			});&lt;br /&gt;
			&lt;br /&gt;
			// Allow users to double click to move to selection list&lt;br /&gt;
			$(&amp;quot;#sortable1 li&amp;quot;).assignDblClick();&lt;br /&gt;
		});  // End of JQuery UI loading&lt;br /&gt;
		&lt;br /&gt;
	}); // End of JQuery ready function&lt;br /&gt;
	&lt;br /&gt;
// Define the actions when an item is double clicked&lt;br /&gt;
$.fn.assignDblClick = function() {&lt;br /&gt;
	$(this).dblclick(function(){&lt;br /&gt;
		$(this).appendTo(&#039;#sortable2&#039;);&lt;br /&gt;
		$(&amp;quot;#sortable1&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
		$(&amp;quot;#sortable2&amp;quot;).sortable(&amp;quot;refresh&amp;quot;);&lt;br /&gt;
		updateRanking();&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function copies the drag and drop sortable data into the standard LimeSurvey ranking structure.&lt;br /&gt;
function updateRanking() {&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	$(&#039;#sortable2 li&#039;).each(function(index) {&lt;br /&gt;
	$(this).attr(&amp;quot;value&amp;quot;, index+1);&lt;br /&gt;
	&lt;br /&gt;
		// Get value of person&lt;br /&gt;
		li_tag = $(this).attr(&#039;id&#039;);&lt;br /&gt;
		li_tag_array = li_tag.split(&amp;quot;_&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		// Save to an array&lt;br /&gt;
		rankees[rankees.length] = { &#039;r_name&#039;:$(this).text(),&#039;r_value&#039;:li_tag_array[1] };&lt;br /&gt;
	});&lt;br /&gt;
	$(&amp;quot;input[name&amp;lt;/div&amp;gt;=&#039;RANK_&#039;]&amp;quot;).each(function(index) {&lt;br /&gt;
		if (rankees.length &amp;gt; index) {&lt;br /&gt;
			$(this).val(rankees[index].r_name);&lt;br /&gt;
			$(this).next().val(rankees[index].r_value);&lt;br /&gt;
		} else {&lt;br /&gt;
			$(this).val(&amp;quot;&amp;quot;);&lt;br /&gt;
			$(this).next().val(&amp;quot;&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	 });&lt;br /&gt;
	 &lt;br /&gt;
	// Re-assign double click action to first list items and remove&lt;br /&gt;
	// double click action from section list items&lt;br /&gt;
	$(&#039;#sortable1 li&#039;).unbind(&#039;dblclick&#039;).assignDblClick();&lt;br /&gt;
	$(&#039;#sortable2 li&#039;).unbind(&#039;dblclick&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// This function is called on page load to see if there are any items already ranked (from a previous visit&lt;br /&gt;
// or cached due to a page change.  If so, the already-ranked items are loaded into the sortable list&lt;br /&gt;
function loadRanking() {&lt;br /&gt;
	var rankees = [];&lt;br /&gt;
	&lt;br /&gt;
	// Loop through each item in the built-in LimeSurvey ranking list looking for non-empty values&lt;br /&gt;
	$(&amp;quot;input[name&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;=&#039;RANK_&#039;]&amp;quot;).each(function(index) {&lt;br /&gt;
	&lt;br /&gt;
		// Check to see if the current item has a value&lt;br /&gt;
		if ($(this).val()) {&lt;br /&gt;
			// Item has a value - save to the array&lt;br /&gt;
			// Use this element to contain the name and the next for the value (numeric)&lt;br /&gt;
			rankees[rankees.length] = { &#039;r_name&#039;:$(this).val(),&#039;r_value&#039;:$(this).next().val() };&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// Now that we have a list of all the pre-ranked items, populate the sortable list&lt;br /&gt;
	// Note that the items *won&#039;t* appear in the main list because LimeSurvey has removed them.&lt;br /&gt;
	$.each(rankees, function(index, value) {&lt;br /&gt;
		// Create the items in the sortable&lt;br /&gt;
		li_tag = &amp;quot;&amp;lt;li class=&#039;ui-state-default&#039; id=&#039;choice_&amp;quot; + value.r_value + &amp;quot;&#039;&amp;gt;&amp;quot; + value.r_name + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
		$(li_tag).appendTo(&amp;quot;#sortable2&amp;quot;);&lt;br /&gt;
	});&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Create MaxDiff question type=&lt;br /&gt;
&lt;br /&gt;
See the [[Workarounds: Question design, layout and templating|Question design, layout and templating]] section for a workaround that uses JavaScript to convert an &#039;&#039;&#039;&#039;&#039;Array (flexible labels) by column&#039;&#039;&#039;&#039;&#039; question into a [http://en.wikipedia.org/wiki/MaxDiff MaxDiff] question type.&lt;br /&gt;
&lt;br /&gt;
[[File:max_diff_596x253.gif]]&lt;br /&gt;
&lt;br /&gt;
=In a checkbox matrix, have the &#039;none&#039; option in a row disable all other columns in that row=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: LimeSurvey 1.90+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The questionId parameter is the base ID of the question matrix (multiflexible).&lt;br /&gt;
&lt;br /&gt;
numColumns and numRows speak for themselves&lt;br /&gt;
&lt;br /&gt;
specialColumns is an array of the columns that have the special ability that when one of them&lt;br /&gt;
&lt;br /&gt;
is checked, none of the others can be checked. E.g., a &#039;none of these&#039; and/or a &#039;do now know&#039; option.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
numColumns=13;&lt;br /&gt;
&lt;br /&gt;
numRows=18;&lt;br /&gt;
&lt;br /&gt;
questionId=&#039;28417X2X24&#039;;&lt;br /&gt;
&lt;br /&gt;
specialColumns=[1,12,13];&lt;br /&gt;
&lt;br /&gt;
function action(obj){&lt;br /&gt;
&lt;br /&gt;
   locator=obj.id.replace(&#039;cbox_&#039;+questionId, &#039;&#039;).split(&#039;_&#039;);&lt;br /&gt;
&lt;br /&gt;
   row=locator[0];&lt;br /&gt;
&lt;br /&gt;
   column=locator[1];&lt;br /&gt;
&lt;br /&gt;
   //alert(&#039;Action for row,column=&#039;+row+&#039;,&#039;+column);&lt;br /&gt;
&lt;br /&gt;
   my_id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+column+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   if($(my_id).attr(&#039;checked&#039;) == false) {&lt;br /&gt;
&lt;br /&gt;
       for( var i=1; i&amp;lt;=numColumns; i++ ) {&lt;br /&gt;
&lt;br /&gt;
           if(i==column) continue;&lt;br /&gt;
&lt;br /&gt;
           id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;disabled&#039;,false);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   } else {&lt;br /&gt;
&lt;br /&gt;
       for( var i=1; i&amp;lt;=numColumns; i++ ) {&lt;br /&gt;
&lt;br /&gt;
           if(i==column) continue;&lt;br /&gt;
&lt;br /&gt;
           id=&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           aid=&#039;#answer&#039;+questionId+row+&#039;_&#039;+i&lt;br /&gt;
&lt;br /&gt;
           $(aid).val(0);&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;checked&#039;,false);&lt;br /&gt;
&lt;br /&gt;
           $(id).attr(&#039;disabled&#039;,true);&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function customOnLoad(){&lt;br /&gt;
&lt;br /&gt;
   for( var row=1; row&amp;lt;=numRows; row++ ) {&lt;br /&gt;
&lt;br /&gt;
       for( var k=0; k&amp;lt;specialColumns.length; k++ )&lt;br /&gt;
&lt;br /&gt;
       {&lt;br /&gt;
&lt;br /&gt;
           column=specialColumns[k];&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#cbox_&#039;+questionId+row+&#039;_&#039;+column).change(function() {&lt;br /&gt;
&lt;br /&gt;
               action(this);&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jQuery(document).ready(&lt;br /&gt;
&lt;br /&gt;
   function(){&lt;br /&gt;
&lt;br /&gt;
   customOnLoad();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Last Option In Array (Numbers) (Checkboxes) Row Excludes All Others=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 2.05, IE 7-10, Firefox&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to make the last option of each Array (Numbers) (Checkboxes) row exclude all other options in the same row.&lt;br /&gt;
&lt;br /&gt;
The script will uncheck all options in a row if the last option is checked and uncheck the last option in a row if any other options are checked.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following script in the source of the array question.&lt;br /&gt;
&lt;br /&gt;
NOTE: Care should be taken when using this script and conditional questions on the same page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Call the exclude function using question ID&lt;br /&gt;
		excludeOpt ({QID});&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
	// A function to make the last option in each array row exclusive&lt;br /&gt;
	function excludeOpt (qID) {&lt;br /&gt;
		&lt;br /&gt;
		var thisQuestion = $(&#039;#question&#039;+qID)&lt;br /&gt;
&lt;br /&gt;
		// Add some classes to the checkbox cells&lt;br /&gt;
		$(&#039;table.question tbody td&#039;, thisQuestion).addClass(&#039;normalOpt&#039;);&lt;br /&gt;
		$(&#039;table.question tbody tr&#039;, thisQuestion).each(function(i) {&lt;br /&gt;
			$(&#039;.normalOpt:last&#039;, this).removeClass(&#039;normalOpt&#039;).addClass(&#039;exlusiveOpt&#039;)&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// A listener on the checkbox cells&lt;br /&gt;
		$(&#039;table.question tbody td&#039;, thisQuestion).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Set some vars&lt;br /&gt;
			var thisRow = $(this).closest(&#039;tr&#039;);&lt;br /&gt;
&lt;br /&gt;
			// Uncheck the appropriate boxes in a row&lt;br /&gt;
			if ($(this).hasClass(&#039;normalOpt&#039;)) {&lt;br /&gt;
				$(&#039;.exlusiveOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;.normalOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// A listener on the checkboxes&lt;br /&gt;
		$(&#039;table.question tbody td input[type=checkbox]&#039;, thisQuestion).click(function (event) {&lt;br /&gt;
			&lt;br /&gt;
			// Set some vars&lt;br /&gt;
			var thisRow = $(this).closest(&#039;tr&#039;);&lt;br /&gt;
			var thisCell = $(this).closest(&#039;td&#039;);&lt;br /&gt;
&lt;br /&gt;
			// Uncheck the appropriate boxes in a row&lt;br /&gt;
			if ($(thisCell).hasClass(&#039;normalOpt&#039;)) {&lt;br /&gt;
				$(&#039;.exlusiveOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				$(&#039;.normalOpt input[type=checkbox]&#039;, thisRow).attr(&#039;checked&#039;, false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Add Navigation Buttons (Next and Previous) To Top Of Page=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.90+, IE 7/8, Firefox 3.6, Safari 3.2&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add the following to the end of template.js. It will insert a new div after the progress bar and then insert clones of the nav buttons in the new div.&lt;br /&gt;
&lt;br /&gt;
This example is for the default template in 1.90 or 1.91. The placement of the new div may need to be modified for other templates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Insert a new div after the progress bar&lt;br /&gt;
		$(&#039;&amp;lt;div id=&amp;quot;navigator2&amp;quot; /&amp;gt;&#039;).insertAfter(&#039;#progress-wrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Style the new div&lt;br /&gt;
		$(&#039;#navigator2&#039;).css({&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// Insert clones of the nav buttons in the new div&lt;br /&gt;
		$(&#039;input.submit:eq(0)&#039;).clone().appendTo(&#039;#navigator2&#039;);&lt;br /&gt;
		$(&#039;input.submit:eq(2)&#039;).clone().appendTo(&#039;#navigator2&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Give the new buttons some new IDs&lt;br /&gt;
		$(&#039;#navigator2 input.submit&#039;).each(function(i) {&lt;br /&gt;
			var oldID = $(this).attr(&#039;id&#039;);&lt;br /&gt;
			var newID = oldID + &#039;2&#039;;&lt;br /&gt;
			$(this).attr(&#039;id&#039;, newID)&lt;br /&gt;
		});&lt;br /&gt;
	});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:extra_buttons.png]]&lt;br /&gt;
&lt;br /&gt;
=How to &#039;&#039;add&#039;&#039; an opt out link to your survey=&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.91+, Firefox 5.0&lt;br /&gt;
&lt;br /&gt;
This javascript inserts a link to opt out of the survey above the progress bar.&lt;br /&gt;
&lt;br /&gt;
[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|How to use script here]]&lt;br /&gt;
&lt;br /&gt;
Then insert the following code into to the source of a group description or a question. I used the group description.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt; &amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
		// Find the survey ID&lt;br /&gt;
		if($(&#039;input#fieldnames&#039;).length != 0) {&lt;br /&gt;
			var fieldNames = $(&#039;input#fieldnames&#039;).attr(&#039;value&#039;);&lt;br /&gt;
			var tmp = fieldNames.split(&#039;X&#039;);&lt;br /&gt;
			var sID = tmp[0];&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Insert a new div after the progress bar&lt;br /&gt;
		$(&#039;&amp;lt;div id=&amp;quot;optOutLink&amp;quot; /&amp;gt;&#039;).insertBefore(&#039;#progress-wrapper&#039;);&lt;br /&gt;
&lt;br /&gt;
		// Style the new div&lt;br /&gt;
		$(&#039;#optOutLink&#039;).css({&lt;br /&gt;
			&#039;text-align&#039;:&#039;center&#039;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		// Insert opt out url in the new div&lt;br /&gt;
		$(&#039;#optOutLink&#039;).html(&#039;&amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;optout.php?lang=en&amp;amp;sid;=&#039;+sID+&#039;&amp;amp;token;={TOKEN}&amp;quot;&amp;gt;Click here to opt out of this survey.&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;br&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Anonymously track respondents answers across multiple surveys=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+ and 1.92+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to enable tracking of respondents across multiple surveys ensuring anonymity (it does not use tokens).&lt;br /&gt;
&lt;br /&gt;
To do this you have to use this question in all the surveys you want to link respondents answers.&lt;br /&gt;
&lt;br /&gt;
This workaround create an ID by asking some partial personal information (like initials, birth month ...). The ID will be encrypted using a one-way function (in this case SHA-1) and stored in a short text answer.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following code in the source of a short text question.&lt;br /&gt;
#Optional: you can also add other select field to avoid collisions (e.g. for large population sample)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This answers are used to generate your ID. These information will be encrypted, it will not be possible in any case to identify you neither from your answers nor from your ID.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;Initial of your name&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select id=&amp;quot;field1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;A&amp;quot;&amp;gt;A&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;B&amp;quot;&amp;gt;B&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;C&amp;quot;&amp;gt;C&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;D&amp;quot;&amp;gt;D&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;E&amp;quot;&amp;gt;E&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;F&amp;quot;&amp;gt;F&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;G&amp;quot;&amp;gt;G&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;H&amp;quot;&amp;gt;H&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;I&amp;quot;&amp;gt;I&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;J&amp;quot;&amp;gt;J&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;K&amp;quot;&amp;gt;K&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;L&amp;quot;&amp;gt;L&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;M&amp;quot;&amp;gt;M&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;N&amp;quot;&amp;gt;N&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;O&amp;quot;&amp;gt;O&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;P&amp;quot;&amp;gt;P&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Q&amp;quot;&amp;gt;Q&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;R&amp;quot;&amp;gt;R&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;S&amp;quot;&amp;gt;S&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;T&amp;quot;&amp;gt;T&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;U&amp;quot;&amp;gt;U&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;V&amp;quot;&amp;gt;V&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;W&amp;quot;&amp;gt;W&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;X&amp;quot;&amp;gt;X&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Y&amp;quot;&amp;gt;Y&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;Z&amp;quot;&amp;gt;Z&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;Your birth month&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;select id=&amp;quot;field2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;01&amp;quot;&amp;gt;January&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;02&amp;quot;&amp;gt;February&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;03&amp;quot;&amp;gt;March&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;04&amp;quot;&amp;gt;April&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;05&amp;quot;&amp;gt;May&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;06&amp;quot;&amp;gt;June&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;07&amp;quot;&amp;gt;July&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;08&amp;quot;&amp;gt;August&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;09&amp;quot;&amp;gt;September&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;10&amp;quot;&amp;gt;October&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;11&amp;quot;&amp;gt;November&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;option value=&amp;quot;12&amp;quot;&amp;gt;December&amp;lt;/option&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/sha1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
   $(&amp;quot;#answer{SGQ}&amp;quot;).attr(&#039;readonly&#039;, &#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
   //$(&amp;quot;#answer{SGQ}&amp;quot;).css(&#039;display&#039;, &#039;none&#039;); //uncomment this line for not displaying the code&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(&#039;#field1, #field2&#039;).bind(&#039;change keyup&#039;, function() {&lt;br /&gt;
&lt;br /&gt;
   if ($(&amp;quot;#field1&amp;quot;).val()==&#039;&#039; || $(&amp;quot;#field2&amp;quot;).val()==&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;#answer{SGQ}&amp;quot;).val(&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
   else {&lt;br /&gt;
&lt;br /&gt;
       var sha1 = CryptoJS.algo.SHA1.create();&lt;br /&gt;
&lt;br /&gt;
       sha1.update($(&amp;quot;#field1&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       sha1.update($(&amp;quot;#field2&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       // sha1.update($(&amp;quot;#otherfield&amp;quot;).val());&lt;br /&gt;
&lt;br /&gt;
       var hash = sha1.finalize();&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;#answer{SGQ}&amp;quot;).val(hash);&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Check validity of international phone number in subquestion=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.91+, Firefox 8, Chrome 15&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As of version 1.92, you can use the core Validation querstion option to validate multiple short text and array text questions. Any question that fails that validation check will have its background color changed to red.&lt;br /&gt;
&lt;br /&gt;
Note, the below workaround will fail in version 1.92 because it contains a regular expression with curly braces.  However, as described above, support for this feature is now built-in to version 1.92&lt;br /&gt;
&lt;br /&gt;
This workaround uses javascript to check the validity of an international phone number in a subquestion of multiple short text.&lt;br /&gt;
&lt;br /&gt;
Add the following code to the source of your question.&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;NN&amp;quot; with the row number that you want to validate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the phone function with the question ID and the row number&lt;br /&gt;
&lt;br /&gt;
       phoneTest(QQ, NN);&lt;br /&gt;
&lt;br /&gt;
       function phoneTest(qID, inputNum) {&lt;br /&gt;
&lt;br /&gt;
           // Interrupt next/submit function&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               // Some vars - modify as required&lt;br /&gt;
&lt;br /&gt;
               var phoneMatch = /^[0-9,+,(), ,]{1,}(,[0-9]+){0,}$/;&lt;br /&gt;
&lt;br /&gt;
               var msg1 = &#039;Please enter a valid phone number.&#039;;&lt;br /&gt;
&lt;br /&gt;
               // Test the input&lt;br /&gt;
&lt;br /&gt;
               var phoneInput = $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               if(phoneInput != &#039;&#039; &amp;amp;&amp;amp; !phoneMatch.test(phoneInput)) {&lt;br /&gt;
&lt;br /&gt;
                   alert(msg1);&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;pink&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The regex is from: [http://www.regexlib.com/REDetails.aspx?regexp_id=1136 regexlib.com blank]&lt;br /&gt;
&lt;br /&gt;
=Check validity of email address in subquestion=&lt;br /&gt;
&lt;br /&gt;
&#039;Tested with: 1.91+, Firefox 8, Chrome 15&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;As of version 1.92, you can use the core Validation querstion option to validate multiple short text and array text questions. Any question that fails that validation check will have its background color changed to red.&amp;lt;br /&amp;gt;Note, the below workaround will fail in version 1.92 because it contains a regular expression with curly braces.  However, as described above, support for this feature is now built-in to version 1.92&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This workaround uses javascript to check the validity of an email address in a subquestion of multiple short text.&lt;br /&gt;
&lt;br /&gt;
Add the following code to the source of your question.&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;QQ&amp;quot; with the question ID and &amp;quot;NN&amp;quot; with the row number that you want to validate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the email function with the question ID and the row number&lt;br /&gt;
&lt;br /&gt;
       emailTest(QQ, NN);&lt;br /&gt;
&lt;br /&gt;
       function emailTest(qID, inputNum) {&lt;br /&gt;
&lt;br /&gt;
           // Interrupt next/submit function&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#movenextbtn, #movesubmitbtn&#039;).click(function(){&lt;br /&gt;
&lt;br /&gt;
               // Some vars - modify as required&lt;br /&gt;
&lt;br /&gt;
               var emailMatch = /^[a-zA-Z0-9\_\-]+[a-zA-Z0-9\.\_\-]*@([a-zA-Z0-9\_\-]+\.)+([a-zA-Z]{2,4}|travel|museum)$/;&lt;br /&gt;
&lt;br /&gt;
               var msg1 = &#039;Please enter a valid email address.&#039;;&lt;br /&gt;
&lt;br /&gt;
               // Test the input&lt;br /&gt;
&lt;br /&gt;
               var emailInput = $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).val();&lt;br /&gt;
&lt;br /&gt;
               if(emailInput != &#039;&#039; &amp;amp;&amp;amp; !emailMatch.test(emailInput)) {&lt;br /&gt;
&lt;br /&gt;
                   alert(msg1);&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;pink&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return false;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
               else {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; li:eq(&#039;+(inputNum-1)+&#039;) input.text&#039;).css({ &#039;background&#039;:&#039;&#039; });&lt;br /&gt;
&lt;br /&gt;
                   return true;&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The regex is from: [http://www.regexlib.com/REDetails.aspx?regexp_id=1653 regexlib.com blank]&lt;br /&gt;
&lt;br /&gt;
=Hiding the help-text when it&#039;s empty=&lt;br /&gt;
&lt;br /&gt;
Tested with: 1.91+&lt;br /&gt;
&lt;br /&gt;
I had made a style in my template putting a border around my help-text. To avoid empty help-text to show up (and have lines instead of just &#039;nothing&#039; when there was no help text, I used this piece of code in question.pstpl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                   var questionhelp=&amp;quot;{QUESTIONHELP}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
                   if (questionhelp==&amp;quot;&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
                          document.write(&amp;quot;&amp;quot;);}&lt;br /&gt;
&lt;br /&gt;
                   else {&lt;br /&gt;
&lt;br /&gt;
                   document.write(&#039;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;survey-question-help&amp;quot;&amp;gt;&#039;+ questionhelp +&#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;);}&lt;br /&gt;
&lt;br /&gt;
               &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
it can probably be optimized but it worked for me&lt;br /&gt;
&lt;br /&gt;
=Disable or hide selected fields in a matrix question=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+, IE 7/8/9, FireFox 12/13&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
TASK&lt;br /&gt;
&lt;br /&gt;
Hide or disable selected fields in a Matrix, so that users cannot make any input.&lt;br /&gt;
&lt;br /&gt;
(See example, where users should not make input into red framed fields)&lt;br /&gt;
&lt;br /&gt;
[[File:snap035.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Prevent users from input into first two fields (as an example)&lt;br /&gt;
&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
First find the name of the fields you want to hide / disable. In my case I used Firebug with firefox to figure that out.&lt;br /&gt;
&lt;br /&gt;
[[File:snap037.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 2: Figure out the name(s) of the field(s)&lt;br /&gt;
&lt;br /&gt;
Then put the following script-code into the HTML-source code as described above:&lt;br /&gt;
&lt;br /&gt;
Note: you have to change the code to match the names of your fields!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&#039;input[name=&amp;quot;69965X2X10SQ001_SQ001&amp;quot;]&#039;).attr(&#039;disabled&#039;, &#039;disabled&#039;);&lt;br /&gt;
&lt;br /&gt;
       $(&#039;input[name=&amp;quot;69965X2X10SQ001_SQ002&amp;quot;]&#039;).attr(&#039;hidden&#039;, &#039;hidden&#039;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:snap039.gif]]&lt;br /&gt;
&lt;br /&gt;
Fig. 3: Result: first field is diabled (&amp;quot;greyed out&amp;quot;), second one is completely hidden&lt;br /&gt;
&lt;br /&gt;
I think this way one can apply many other attributes to a field like color etc. But did not try that myself.&lt;br /&gt;
&lt;br /&gt;
Thanks to roB2009 for the input in the forum!&lt;br /&gt;
&lt;br /&gt;
=Add prefix or suffix to question type &amp;quot;Array (Texts)&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
TASK&lt;br /&gt;
&lt;br /&gt;
Add a prefix or suffix to the text fields in questions of the &amp;quot;Array (Texts)&amp;quot; type.&lt;br /&gt;
&lt;br /&gt;
[[File:suffix.png]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Suffix&lt;br /&gt;
&lt;br /&gt;
[[File:prefix.png]]&lt;br /&gt;
&lt;br /&gt;
Fig. 1: Prefix&lt;br /&gt;
&lt;br /&gt;
SOLUTION&lt;br /&gt;
*Set up your survey to use JavaScript.&lt;br /&gt;
*Add the following script to the source of the array. Replace &amp;quot;12345&amp;quot; with the array question ID and modify the suffixes/prefixes as required.&lt;br /&gt;
*The function call must consist of a question ID followed by the suffixes for each column. Suffixes/Prefixes must be enclosed in quotes and comma separated.&lt;br /&gt;
*In this example question ID 12345 will get an &amp;quot;in &amp;amp;euro;&amp;quot; suffix in the first column and an &amp;quot;in %&amp;quot; in the next 3 columns.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   $(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       // Call the function with the question ID followed by a comma-separated list of suffixes&lt;br /&gt;
&lt;br /&gt;
       addSuffix(12345, &#039;in &amp;amp;euro;&#039;, &#039;in %&#039;, &#039;in %&#039;, &#039;in %&#039;);&lt;br /&gt;
&lt;br /&gt;
       function addSuffix() {&lt;br /&gt;
&lt;br /&gt;
           var qID = $(arguments)[0];&lt;br /&gt;
&lt;br /&gt;
           // Assign some column-specific classes&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+qID+&#039; table.question tbody tr&#039;).each(function(i){&lt;br /&gt;
&lt;br /&gt;
               $(&#039;td&#039;, this).each(function(i){&lt;br /&gt;
&lt;br /&gt;
                   $(this).addClass(&#039;answerCol-&#039;+(i+1)+&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
               });&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Some styling&lt;br /&gt;
&lt;br /&gt;
           $(&#039;#question&#039;+qID+&#039; table.question tbody input[type=&amp;quot;text&amp;quot;]&#039;).css({&lt;br /&gt;
&lt;br /&gt;
               &#039;width&#039;: &#039;50%&#039;&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
           // Insert the suffixes&lt;br /&gt;
&lt;br /&gt;
           $(arguments).each(function(i, val){&lt;br /&gt;
&lt;br /&gt;
               if(i &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
                   $(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).append(val);&lt;br /&gt;
&lt;br /&gt;
               }&lt;br /&gt;
&lt;br /&gt;
           });&lt;br /&gt;
&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For adding a prefix you need to substitute the following line in the code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).append(val);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;$(&#039;#question&#039;+qID+&#039; td.answerCol-&#039;+i+&#039; label&#039;).prepend(val);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Time question (Date question-like)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript/jQuery to build a Time question just like to the Date one.&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
#Download the file at [http://trentrichardson.com/examples/timepicker/jquery-ui-timepicker-addon.js trentrichardson.com/examples/timepicker/jquery-ui-timepicker-addon.js] and upload it to your survey.&lt;br /&gt;
#[[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
#Place the following code in the source of a short text question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;/upload/surveys/{SID}/jquery-ui-timepicker-addon.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	$(document).ready(function(){&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer{SGQ}&#039;).timepicker({&lt;br /&gt;
			timeText: &#039;Time&#039;, //here translation&lt;br /&gt;
			hourText: &#039;hour&#039;, //here translation&lt;br /&gt;
			minuteText: &#039;minute&#039;, //here translation&lt;br /&gt;
			closeText: &#039;Done&#039; //here translation&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		$(&#039;#answer{SGQ}&#039;).attr(&#039;readonly&#039;, &#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
		$( &amp;quot;&amp;lt;style&amp;gt;&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-widget-header, .ui-datepicker-current { display:none; }&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }&amp;quot;&lt;br /&gt;
		+&amp;quot;.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }&amp;quot;&lt;br /&gt;
		+&amp;quot; }&amp;quot;&lt;br /&gt;
		+&amp;quot;&amp;lt;/style&amp;gt;&amp;quot;).appendTo( &amp;quot;head&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Calculating date difference=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 1.92+ Build 120909&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround explains how calculate difference between two dates (in: days, weeks, months and years) and is based on this [http://ditio.net/2010/05/02/javascript-date-difference-calculation/ resource external].&lt;br /&gt;
&lt;br /&gt;
Requieres 2 groups and &#039;group by group&#039; or &#039;question by question&#039; presentation.&lt;br /&gt;
&lt;br /&gt;
Group 1 (2 date questions)&lt;br /&gt;
*1st question - Question code: &amp;quot;DD&amp;quot;&lt;br /&gt;
*2nd question - Question code: &amp;quot;D2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Group 2&lt;br /&gt;
*1 numerical input question.&lt;br /&gt;
&lt;br /&gt;
This question retrieves the number of days between the 2 dates, and check if D2 is posterior than DD.&lt;br /&gt;
&lt;br /&gt;
All the requiered code have to be added in the source of this numerical question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
Adapted from http://ditio.net/2010/05/02/javascript-date-difference-calculation/&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var DateDiff = {&lt;br /&gt;
&lt;br /&gt;
   inDays: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var t2 = d2.getTime();&lt;br /&gt;
&lt;br /&gt;
       var t1 = d1.getTime();&lt;br /&gt;
&lt;br /&gt;
       return parseInt[[t2-t1)/(24*3600*1000]];&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inWeeks: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var t2 = d2.getTime();&lt;br /&gt;
&lt;br /&gt;
       var t1 = d1.getTime();&lt;br /&gt;
&lt;br /&gt;
       return parseInt[[t2-t1)/(24*3600*1000*7]];&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inMonths: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       var d1Y = d1.getFullYear();&lt;br /&gt;
&lt;br /&gt;
       var d2Y = d2.getFullYear();&lt;br /&gt;
&lt;br /&gt;
       var d1M = d1.getMonth();&lt;br /&gt;
&lt;br /&gt;
       var d2M = d2.getMonth();&lt;br /&gt;
&lt;br /&gt;
       return (d2M+12*d2Y)-(d1M+12*d1Y);&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   inYears: function(d1, d2) {&lt;br /&gt;
&lt;br /&gt;
       return d2.getFullYear()-d1.getFullYear();&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
d1 = new Date({substr(DD,0,4)}, {substr(DD,5,2)}, {substr(DD,8,2)});&lt;br /&gt;
&lt;br /&gt;
d2 = new Date({substr(D2,0,4)}, {substr(D2,5,2)}, {substr(D2,8,2)});&lt;br /&gt;
&lt;br /&gt;
// Displays result&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;days&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inDays(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;weeks&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inWeeks(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;months&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inMonths(d1, d2));&lt;br /&gt;
&lt;br /&gt;
document.write(&amp;quot;&amp;lt;br /&amp;gt;Number of &amp;lt;b&amp;gt;years&amp;lt;/b&amp;gt;: &amp;quot;+DateDiff.inYears(d1, d2));&lt;br /&gt;
&lt;br /&gt;
// filled the numerical input with number of days (or nights)&lt;br /&gt;
&lt;br /&gt;
var nDays = +DateDiff.inDays(d1, d2);&lt;br /&gt;
&lt;br /&gt;
    jQuery(document).ready(function() {&lt;br /&gt;
&lt;br /&gt;
       $(&amp;quot;.numeric:eq(0) input.text&amp;quot;).val(nDays);&lt;br /&gt;
&lt;br /&gt;
               $(&amp;quot;.numeric:eq(0) input.text&amp;quot;).attr(&#039;readonly&#039;,&#039;readonly&#039;);&lt;br /&gt;
&lt;br /&gt;
// check if d2 &amp;gt; d1&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#movenextbtn&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               $(&#039;#movesubmitbtn&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
               if(nDays &amp;gt;= 0){&lt;br /&gt;
&lt;br /&gt;
       // automatic submit (uncomment if needed)&lt;br /&gt;
&lt;br /&gt;
               // document.limesurvey.submit();&lt;br /&gt;
&lt;br /&gt;
               // $(&#039;body&#039;).hide();&lt;br /&gt;
&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
               else alert(&amp;quot;Check out date must be posterior than Check in\nPlease return to the previous page and edit your answers&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   });&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How to set minDate/maxDate based on other Datequestions=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039; tested with Version 2.00+ Build 130708&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
QQ1 and QQ2 are the question identifiers. QQ2 gets as maxDate today and as minDate the date set in QQ1. The onClose event is needed because on document.ready the value of QQ1 is not yet known, although the value of today is.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    $(document).ready(function () {&lt;br /&gt;
        &#039;use strict&#039;;&lt;br /&gt;
        var qID1 = QQ1,&lt;br /&gt;
            qID2 = QQ2,&lt;br /&gt;
            q1 = $(&#039;#question&#039; + &#039;QQ1&#039; + &#039; .popupdate&#039;), &lt;br /&gt;
            q2 = $(&#039;#question&#039; + &#039;QQ2&#039; + &#039; .popupdate&#039;);&lt;br /&gt;
	&lt;br /&gt;
        //if q1 loses focus, its value is taken and used as minDate in q2   &lt;br /&gt;
        q1.datepicker(&amp;quot;option&amp;quot;, &amp;quot;onClose&amp;quot;, function (datum){&lt;br /&gt;
            q2.datepicker( &amp;quot;option&amp;quot;, &amp;quot;minDate&amp;quot;, datum );&lt;br /&gt;
        });&lt;br /&gt;
        //q2 gets today as its maxDate&lt;br /&gt;
        q2.datepicker( &#039;option&#039;, &#039;maxDate&#039;, new Date() );&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Remove Question Help if empty=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Version 2.00+ Build 130513&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Change your question.pstpl in your Template Editor so that the line looks like below. I&#039;ve added the ID tag help_{question_number}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;survey-question-help&amp;quot; id=help_{QUESTION_NUMBER}&amp;gt;{QUESTIONHELP}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add the following javascript at the end of question.pstpl. If the contents of the help tag is empty then hide the element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
$(document).ready(function(){&lt;br /&gt;
  if($(&#039;#help_{QUESTION_NUMBER}&#039;).is(&#039;:empty&#039;)){&lt;br /&gt;
  $(&#039;#help_{QUESTION_NUMBER}&#039;).hide();&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Implicit Association Test (IAT)=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with: 2.0, IE 7-10, Firefox, Chrome, iPad&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This workaround uses JavaScript to insert an IAT interface into an Array (Texts) question. The workaround prompts respondents to assign words or phrases using the &amp;quot;E&amp;quot; or &amp;quot;I&amp;quot; keys. In mobile devices, &amp;quot;E&amp;quot; and &amp;quot;I&amp;quot; buttons are provided.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Iat_1.png]]&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download a [[Media:Demo_IAT_Concept.zip|working template]] and [[Media:Demo_iat_concept.lss|working survey]].&lt;br /&gt;
&lt;br /&gt;
Implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
1) [[Workarounds: Manipulating a survey at runtime using Javascript#How to use Script (eg. JavaScript etc.) in LimeSurvey?|Set up your survey to use JavaScript]].&lt;br /&gt;
&lt;br /&gt;
2) Create your Array (Texts) with sub-questions as follows:&amp;lt;br /&amp;gt;&lt;br /&gt;
- Y scale - all of your &amp;quot;attribut&amp;quot; words or phrases&amp;lt;br /&amp;gt;&lt;br /&gt;
- X scale - &amp;quot;Key Pressed&amp;quot; and &amp;quot;Elapsed Time (ms)&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Iat_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
3) Insert your association terms and the other text elements for the interface into the Question Help section as depicted below. The text strings must be separated with &amp;quot;double pipes&amp;quot; (||) and you will need to place them in the following order:&amp;lt;br /&amp;gt;&lt;br /&gt;
- Left association term&amp;lt;br /&amp;gt;&lt;br /&gt;
- Right association term&amp;lt;br /&amp;gt;&lt;br /&gt;
- Instructional text&amp;lt;br /&amp;gt;&lt;br /&gt;
- Finished text&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Iat_3.png]]&lt;br /&gt;
&lt;br /&gt;
4) Add the following to the end of template.js:&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
// A plugin to insert an IAT interface&lt;br /&gt;
function implicitAssociation(el, showAnswers) {&lt;br /&gt;
		&lt;br /&gt;
	$(el).each(function() {&lt;br /&gt;
			&lt;br /&gt;
		var thisQuestion = $(this);&lt;br /&gt;
		var thisQuestionHelp = $(&#039;img[src$=&amp;quot;help.gif&amp;quot;]&#039;, thisQuestion).parent();&lt;br /&gt;
		var thisQuestionAnswers = $(&#039;table.question&#039;, thisQuestion).parent();&lt;br /&gt;
		var startTime = &#039;&#039;;&lt;br /&gt;
		var endTime = &#039;&#039;;	&lt;br /&gt;
		var agent = navigator.userAgent.toLowerCase();&lt;br /&gt;
		var mobile = false;&lt;br /&gt;
		if( /android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent) ) { // Mobile devices&lt;br /&gt;
			mobile = true;&lt;br /&gt;
		}&lt;br /&gt;
		mobile = true;&lt;br /&gt;
		&lt;br /&gt;
		// Some classes&lt;br /&gt;
		$(thisQuestion).addClass(&#039;iatQuestion&#039;);&lt;br /&gt;
		$(&#039;.subquestion-list&#039;).addClass(&#039;unanswered&#039;);&lt;br /&gt;
		&lt;br /&gt;
		// Hide the question help element&lt;br /&gt;
		$(thisQuestionHelp).hide();&lt;br /&gt;
		&lt;br /&gt;
		// Hide the answers&lt;br /&gt;
		if(showAnswers != true) {&lt;br /&gt;
			$(&#039;table.question&#039;, thisQuestion).hide();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Insert IAT display&lt;br /&gt;
		var iatTexts = $(thisQuestionHelp).text().split(&#039;||&#039;);&lt;br /&gt;
		var iatDisplayHTML = &#039;&amp;lt;div class=&amp;quot;iatWrapper&amp;quot;&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatLeftLabel&amp;quot;&amp;gt;&#039;+iatTexts[0]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatRightLabel&amp;quot;&amp;gt;&#039;+iatTexts[1]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatWord&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatInstructions&amp;quot;&amp;gt;&#039;+iatTexts[2]+&#039;&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;div class=&amp;quot;iatMobileButtonWrapper&amp;quot;&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatButton iatLeftButton&amp;quot;&amp;gt;E&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div class=&amp;quot;iatButton iatRightButton&amp;quot;&amp;gt;I&amp;lt;/div&amp;gt;\&lt;br /&gt;
								&amp;lt;div style=&amp;quot;width:100%; clear:both;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;\&lt;br /&gt;
							&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
		$(thisQuestionAnswers).prepend(iatDisplayHTML);&lt;br /&gt;
		&lt;br /&gt;
		// Show a word&lt;br /&gt;
		function iatShowWord() {&lt;br /&gt;
			$(&#039;div.iatWord&#039;, thisQuestion).text($(&#039;.subquestion-list.unanswered:first .answertext&#039;, thisQuestion).text());&lt;br /&gt;
			startTime = new Date();&lt;br /&gt;
			&lt;br /&gt;
			$(document).bind(&#039;keypress.iatKeypress&#039;, function(e) {&lt;br /&gt;
				if(e.which == 101 || e.which == 105) {&lt;br /&gt;
					var thisRow = $(&#039;.subquestion-list.unanswered:eq(0)&#039;, thisQuestion);&lt;br /&gt;
					$(thisRow).removeClass(&#039;unanswered&#039;);&lt;br /&gt;
					endTime = new Date();&lt;br /&gt;
					$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(1)&#039;, thisRow).val(endTime.valueOf() - startTime.valueOf());&lt;br /&gt;
					if(e.which == 101) {&lt;br /&gt;
						$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val(&#039;E&#039;);&lt;br /&gt;
					}&lt;br /&gt;
					else {&lt;br /&gt;
						$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val(&#039;I&#039;);&lt;br /&gt;
					}&lt;br /&gt;
					$(document).unbind(&#039;keypress.iatKeypress&#039;);&lt;br /&gt;
					if($(&#039;.subquestion-list.unanswered&#039;, thisQuestion).length &amp;gt; 0) {&lt;br /&gt;
						iatShowWord();&lt;br /&gt;
					}&lt;br /&gt;
					else {&lt;br /&gt;
						$(&#039;.iatLeftLabel, .iatWord, .iatRightLabel, .iatInstructions&#039;, thisQuestion).fadeOut(&#039;slow&#039;, function() {&lt;br /&gt;
							$(&#039;div.iatWord&#039;, thisQuestion).text(iatTexts[3]);&lt;br /&gt;
							$(&#039;.iatWord&#039;, thisQuestion).addClass(&#039;done&#039;).fadeIn(&#039;slow&#039;);&lt;br /&gt;
						});&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		function iatShowWordMobile() {&lt;br /&gt;
			$(&#039;div.iatWord&#039;, thisQuestion).text($(&#039;.subquestion-list.unanswered:first .answertext&#039;, thisQuestion).text());&lt;br /&gt;
			startTime = new Date();&lt;br /&gt;
			&lt;br /&gt;
			$(&#039;.iatButton&#039;, thisQuestion).bind(&#039;click.iatButtonClick&#039;, function(e) {&lt;br /&gt;
				var thisRow = $(&#039;.subquestion-list.unanswered:eq(0)&#039;, thisQuestion);&lt;br /&gt;
				$(thisRow).removeClass(&#039;unanswered&#039;);&lt;br /&gt;
				endTime = new Date();&lt;br /&gt;
				$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(1)&#039;, thisRow).val(endTime.valueOf() - startTime.valueOf());&lt;br /&gt;
				$(&#039;input[type=&amp;quot;text&amp;quot;]:eq(0)&#039;, thisRow).val($(this).text());&lt;br /&gt;
				$(&#039;.iatButton&#039;, thisQuestion).unbind(&#039;click.iatButtonClick&#039;);&lt;br /&gt;
				if($(&#039;.subquestion-list.unanswered&#039;, thisQuestion).length &amp;gt; 0) {&lt;br /&gt;
					iatShowWordMobile();&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					$(&#039;.iatLeftLabel, .iatWord, .iatRightLabel, .iatInstructions, .iatMobileButtonWrapper&#039;, thisQuestion).fadeOut(&#039;slow&#039;, function() {&lt;br /&gt;
						$(&#039;div.iatWord&#039;, thisQuestion).text(iatTexts[3]);&lt;br /&gt;
						$(&#039;.iatWord&#039;, thisQuestion).addClass(&#039;done&#039;).fadeIn(&#039;slow&#039;);&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// Start the IAT display&lt;br /&gt;
		if(mobile == true) { // Mobile devices&lt;br /&gt;
			$(&#039;.iatMobileButtonWrapper&#039;, thisQuestion).show();&lt;br /&gt;
			$(&#039;.iatButton&#039;, thisQuestion).bind(&#039;click.iatStartMobile&#039;, function(e) {&lt;br /&gt;
				$(&#039;.iatButton&#039;, thisQuestion).unbind(&#039;click.iatStartMobile&#039;);&lt;br /&gt;
				iatShowWordMobile();&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			$(document).bind(&#039;keypress.iatStart&#039;, function(e) { // Non-mobile devices&lt;br /&gt;
				if(e.which == 101 || e.which == 105) {&lt;br /&gt;
					$(document).unbind(&#039;keypress.iatStart&#039;);&lt;br /&gt;
					iatShowWord();&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;5) Add the following to the end of template.css:&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
/* IAT questions */&lt;br /&gt;
&lt;br /&gt;
.iatWrapper {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	width: 600px;&lt;br /&gt;
	height: 300px;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
	background-color: #000000;&lt;br /&gt;
	font-size: 21px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatLeftLabel {&lt;br /&gt;
	float: left;&lt;br /&gt;
	padding: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatRightLabel {&lt;br /&gt;
	float: right;&lt;br /&gt;
	padding: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatWord {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	top: 35%;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	font-size: 36px;&lt;br /&gt;
	color:#0F0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatWord.done {&lt;br /&gt;
	color:#FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatInstructions {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	bottom: 0px;&lt;br /&gt;
	padding-bottom: 10px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatMobileButtonWrapper {&lt;br /&gt;
	display: none;&lt;br /&gt;
	position: relative;&lt;br /&gt;
	width: 600px;&lt;br /&gt;
	font-size: 36px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatButton {&lt;br /&gt;
	float: left;&lt;br /&gt;
	margin: 20px;&lt;br /&gt;
	width: 100px;&lt;br /&gt;
	padding: 2px 0 5px 0;&lt;br /&gt;
	border: 5px solid #999;&lt;br /&gt;
	-moz-border-radius: 10px;&lt;br /&gt;
	-webkit-border-radius: 10px;&lt;br /&gt;
	-khtml-border-radius: 10px;&lt;br /&gt;
	border-radius: 10px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	line-height: normal;&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatLeftButton {&lt;br /&gt;
	float: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.iatRightButton {&lt;br /&gt;
	float: right;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;6) To apply the plugin, add one of the two scripts below to the question source:&amp;lt;br /&amp;gt;&lt;br /&gt;
- With hidden answer table (for normally activated survey)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Apply the IAT plugin to this question&lt;br /&gt;
		implicitAssociation(&#039;#question{QID}&#039;);&lt;br /&gt;
	});	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
- With visible answer table (for testing purposes)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;	&lt;br /&gt;
	$(document).ready(function() {&lt;br /&gt;
		// Apply the IAT plugin to this question&lt;br /&gt;
		implicitAssociation(&#039;#question{QID}&#039;, true);&lt;br /&gt;
	});	&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Make multiple choice easier=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tested with Version 2.00 in Chrome, FF, Safar, IE&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The problem:&lt;br /&gt;
We often have multiple choice question, where the user has to select 4 elements out of 78 possible answers or 3 out of 25 and so on.&lt;br /&gt;
If we use pen and paper version for this questions, we noticed that the participants go through the whole list and if an answer doesn&#039;t suit on the first sight, they cross it out.&lt;br /&gt;
&lt;br /&gt;
The solution:&lt;br /&gt;
The script gives the participant the possibility to cross out this answers in a digital way. The script adds a small &amp;quot;X&amp;quot; before the checkbox. When it is clicked, the label text of the checkbox turns grey.&lt;br /&gt;
(see the attached screenshot for an example)&lt;br /&gt;
&lt;br /&gt;
Here is the script, just add it to help text&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
* Small script that adds a &amp;quot;X&amp;quot; before a checkbox. &lt;br /&gt;
* On click the text color of the label of the checkbox turns grey&lt;br /&gt;
* If the user has to choose some answers from many options, he can &amp;quot;delete&amp;quot; answers, that on first sight looks wrong&lt;br /&gt;
* Add the script to the question in Limesurvey (for example within the source code of the help text)&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
//Define the X (standard is a X in capitals)&lt;br /&gt;
var x = &amp;quot;X&amp;quot;;&lt;br /&gt;
css_class = &amp;quot;x&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
/*&lt;br /&gt;
* Define the style of the X&lt;br /&gt;
* Of course you can define the style in the stylesheet - if so, the script ignores the following settings&lt;br /&gt;
* If there is a style, than set style var to 1&lt;br /&gt;
*/&lt;br /&gt;
var style = 0;&lt;br /&gt;
var size = &amp;quot;12px&amp;quot;;&lt;br /&gt;
var weight = &amp;quot;bold&amp;quot;;&lt;br /&gt;
var color = &amp;quot;red&amp;quot;;&lt;br /&gt;
var cursor = &amp;quot;pointer&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
//element type - standard is a span element&lt;br /&gt;
var type = &amp;quot;span&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
//Define the new font color of the checkbox label&lt;br /&gt;
label_color = &amp;quot;#bfbfbf&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
//End of configuration - start of the function&lt;br /&gt;
 &lt;br /&gt;
//Define the element that is added&lt;br /&gt;
if(style == 1) {&lt;br /&gt;
	ele = &amp;quot;&amp;lt;&amp;quot;+type+&amp;quot; class=&#039;&amp;quot;+css_class+&amp;quot;&#039;&amp;gt;&amp;quot;+x+&amp;quot;&amp;lt;/&amp;quot;+type+&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
	ele = &amp;quot;&amp;lt;&amp;quot;+type+&amp;quot; class=&#039;&amp;quot;+css_class+&amp;quot;&#039; style=&#039;font-size:&amp;quot;+size+&amp;quot;; font-weight:&amp;quot;+weight+&amp;quot;; color:&amp;quot;+color+&amp;quot;; cursor:&amp;quot;+cursor+&amp;quot;;&#039;&amp;gt;&amp;quot;+x+&amp;quot;&amp;lt;/&amp;quot;+type+&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
//Get the standard font-color of the used style&lt;br /&gt;
st_color = $(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
//insert the X before the checkboxes&lt;br /&gt;
$(document).ready(function() { &lt;br /&gt;
	$(&amp;quot;li&amp;quot;).each(function(){&lt;br /&gt;
		$(this).prepend(ele);&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
//bind an eventhandler on the X (delegate is used, because Limesurvey uses an old jQuery version)&lt;br /&gt;
var css_class_c = &amp;quot;.&amp;quot;+css_class;&lt;br /&gt;
$(document).delegate(css_class_c,&amp;quot;click&amp;quot;,function() {&lt;br /&gt;
	var color_check = $(this).siblings(&amp;quot;label&amp;quot;).data(&amp;quot;color&amp;quot;);&lt;br /&gt;
	if(color_check != &amp;quot;true&amp;quot;) {&lt;br /&gt;
    	$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,label_color).data(&amp;quot;color&amp;quot;,&amp;quot;true&amp;quot;);&lt;br /&gt;
    	$(this).siblings(&#039;input&#039;).attr(&#039;checked&#039;, false);&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,st_color).data(&amp;quot;color&amp;quot;,&amp;quot;false&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
$(&amp;quot;.checkbox&amp;quot;).click(function () {&lt;br /&gt;
	$(this).siblings(&amp;quot;label&amp;quot;).css(&amp;quot;color&amp;quot;,st_color).data(&amp;quot;color&amp;quot;,&amp;quot;false&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_Documentation_Wiki&amp;diff=17546</id>
		<title>LimeSurvey Documentation Wiki</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_Documentation_Wiki&amp;diff=17546"/>
		<updated>2013-04-19T06:08:55Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=LimeSurvey manual (1.85 and later)= &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
The LimeSurvey manual is available in the following languages (click on your language below to read the manual):&lt;br /&gt;
*[[File:gb.png]] &#039;&#039;&#039;[[English Instructions for LimeSurvey|English]] - This is the base language!&#039;&#039;&#039;&lt;br /&gt;
*[[File:cn.png]] [[Chinese (Simplified) Manual|Chinese (Simplified]])&lt;br /&gt;
*[[File:cn.png]] [[安装|Chinese (Traditional]])&lt;br /&gt;
*[[File:fr.png]] [[Instructions fran&amp;amp;ccedil;aises pour LimeSurvey|French]]&lt;br /&gt;
*[[File:de.png]] [[Deutsche Anleitung f&amp;amp;uuml;r LimeSurvey|German]]&lt;br /&gt;
*[[File:gr.png]] [[Greek Manual|Greek]]&lt;br /&gt;
*[[File:it.png]] [[Documentazione Italiano|Italian]]&lt;br /&gt;
*[[File:jp.png]] [[日本語マニュアル|Japanese]]&lt;br /&gt;
*[[File:pl.png]] [[Podręcznik obsługi|Polish]]&lt;br /&gt;
*[[File:pt.png]] [[Manual de Instru&amp;amp;ccedil;&amp;amp;otilde;es do LimeSurvey|Portuguese]]&lt;br /&gt;
*[[File:es.png]] [[Manual de Instrucciones en Espa&amp;amp;ntilde;ol|Spanish]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
Please note that not all translations are complete/up-to-date.  English is the base language (likely most complete and up-to-date). We always need help to translate pages from English to one of the other languages. If you would like to help, [[Creating, editing and translating LimeSurvey Wiki pages|start here]].&lt;br /&gt;
&lt;br /&gt;
=LimeSurvey development= &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
*[[Development overview]] - General pages about LimeSurvey development&lt;br /&gt;
*[[LimeSurvey 1.x development documentation]]&lt;br /&gt;
*[[LimeSurvey 2.x development documentation]]&lt;br /&gt;
&lt;br /&gt;
=Translating LimeSurvey= &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
If you want to &#039;&#039;&#039;add new translations&#039;&#039;&#039; or &#039;&#039;&#039;correct a translation&#039;&#039;&#039; please follow these instructions:&lt;br /&gt;
*[[Translating LimeSurvey|How to translate LimeSurvey 1.x/2.x]]&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code / Code-In participation= &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
*[[Project Ideas for GSoC 2013]]&lt;br /&gt;
*[[LimeSurvey Google Code-in 2012]]&lt;br /&gt;
*[[LimeSurvey Google Code-in 2011]]&lt;br /&gt;
*[[LimeSurvey GSoC 2011]]/[[GSoC getting started]]&lt;br /&gt;
*[[LimeSurvey GSoC 2010]]&lt;br /&gt;
*[[LimeSurvey GSoC 2009]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
Temporary: [[LimeSurvey Documentation|Shadow, Structured copy]] of this top level page&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_Documentation_Wiki&amp;diff=17544</id>
		<title>LimeSurvey Documentation Wiki</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_Documentation_Wiki&amp;diff=17544"/>
		<updated>2013-04-19T06:07:53Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=LimeSurvey manual (1.85 and later)= &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
The LimeSurvey manual is available in the following languages (click on your language below to read the manual):&lt;br /&gt;
*[[File:gb.png]] &#039;&#039;&#039;[[English Instructions for LimeSurvey|English]] - This is the base language!&#039;&#039;&#039;&lt;br /&gt;
*[[File:cn.png]] [[Chinese (Simplified) Manual|Chinese (Simplified]])&lt;br /&gt;
*[[File:cn.png]] [[安装|Chinese (Traditional]])&lt;br /&gt;
*[[File:fr.png]] [[Instructions fran&amp;amp;ccedil;aises pour LimeSurvey|French]]&lt;br /&gt;
*[[File:de.png]] [[Deutsche Anleitung f&amp;amp;uuml;r LimeSurvey|German]]&lt;br /&gt;
*[[File:gr.png]] [[Greek Manual|Greek]]&lt;br /&gt;
*[[File:it.png]] [[Documentazione Italiano|Italian]]&lt;br /&gt;
*[[File:jp.png]] [[日本語マニュアル|Japanese]]&lt;br /&gt;
*[[File:pl.png]] [[Podręcznik obsługi|Polish]]&lt;br /&gt;
*[[File:pt.png]] [[Manual de Instru&amp;amp;ccedil;&amp;amp;otilde;es do LimeSurvey|Portuguese]]&lt;br /&gt;
*[[File:es.png]] [[Manual de Instrucciones en Espa&amp;amp;ntilde;ol|Spanish]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
Please note that not all translations are complete/up-to-date.  English is the base language (likely most complete and up-to-date). We always need help to translate pages from English to one of the other languages. If you would like to help, [[Creating, editing and translating LimeSurvey Wiki pages|start here]].&lt;br /&gt;
&lt;br /&gt;
=LimeSurvey development= &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
*[[Development overview]] - General pages about LimeSurvey development&lt;br /&gt;
*[[LimeSurvey 1.x development documentation]]&lt;br /&gt;
*[[LimeSurvey 2.x development documentation]]&lt;br /&gt;
&lt;br /&gt;
=Translating LimeSurvey= &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
If you want to &#039;&#039;&#039;add new translations&#039;&#039;&#039; or &#039;&#039;&#039;correct a translation&#039;&#039;&#039; please follow these instructions:&lt;br /&gt;
*[[Translating LimeSurvey|How to translate LimeSurvey 1.x/2.x]]&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code / Code-In participation= &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
*[[LimeSurvey GSoC Ideas Page]]&lt;br /&gt;
*[[LimeSurvey Google Code-in 2012]]&lt;br /&gt;
*[[LimeSurvey Google Code-in 2011]]&lt;br /&gt;
*[[LimeSurvey GSoC 2011]]/[[GSoC getting started]]&lt;br /&gt;
*[[LimeSurvey GSoC 2010]]&lt;br /&gt;
*[[LimeSurvey GSoC 2009]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
Temporary: [[LimeSurvey Documentation|Shadow, Structured copy]] of this top level page&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translating_LimeSurvey&amp;diff=3452</id>
		<title>Translating LimeSurvey</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translating_LimeSurvey&amp;diff=3452"/>
		<updated>2012-09-13T11:21:44Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Translating LimeSurvey=&lt;br /&gt;
&lt;br /&gt;
Wouldn&#039;t it be great to have LimeSurvey completely translated to your mother-language? The LimeSurvey team is always on the look-out for new translations and for people who help to update the existing ones. Please read these instructions and don&#039;t hesitate to send email to translations@limesurvey.org if you are in doubt or have any other questions.&lt;br /&gt;
&lt;br /&gt;
~tc~&lt;br /&gt;
&lt;br /&gt;
(alias(LimeSurvey 1.x Translating LimeSurvey))&lt;br /&gt;
&lt;br /&gt;
~/tc~&lt;br /&gt;
&lt;br /&gt;
=How to translate - Step-by-Step instructions=&lt;br /&gt;
&lt;br /&gt;
==Updating an existing translation==&lt;br /&gt;
#Create a free user account on [http://www.limesurvey.org].&lt;br /&gt;
#Note: If you already have an account please log in once at [http://www.limesurvey.org] first!&lt;br /&gt;
#Go to [http://translate.limesurvey.org], login there with the same user name and password.&lt;br /&gt;
#Pick the LimeSurvey version you want to translate for and start translating. After your translation was approved it will automatically be released in the weekly stable release and your username will be credited in the change log.&lt;br /&gt;
#If you are interested  to become a prime translator for your language with the ability to approve newly translated string please contact us at translations@limesurvey.org . Such a position requires a maximum of about an hour of work per week - important to us is that you are reliable doing this.&lt;br /&gt;
&lt;br /&gt;
==Customize an existing translation==&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to modify an existing translation so it accommodates your particular survey situation better. In that case do the following:&lt;br /&gt;
#Go to http://translate.limesurvey.org (external link), pick the LimeSurvey version you want to translate for and the particular language you want to modify.&lt;br /&gt;
#On the bottom of the translation page you will find an option to export all strings as .po file. Do that and save it as *.po file to your local harddisk.&lt;br /&gt;
#Download and install [http://www.poedit.net/download.php poEDIT]&lt;br /&gt;
#Start poEdit end edit the downloaded *.po file - modify the particular translations.&lt;br /&gt;
#Save. When you save the .po file then automatically a .mo file is created too. That is the one LimeSurvey will read from.&lt;br /&gt;
#Place the particular .mo file in the right language folder in /locale by replacing the existing one - for example for French this would be /locale/fr/LC_MESSAGES/fr.po&lt;br /&gt;
#Done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Note: If you are using LimeService they will be happy to place the file for you. Just create a support ticket.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating a new translation==&lt;br /&gt;
#First of all get access to the development version of LimeSurvey. You can find detailed instructions how to get your hands on it on this page: [[Accessing the source code]]&lt;br /&gt;
#Download and install [http://www.poedit.net/download.php poEDIT]&lt;br /&gt;
#Now you have to find out the language-code for your language - you can search for your language-code in the [http://people.w3.org/rishida/utils/subtags/ IANA Language Subtag Registry].&lt;br /&gt;
#Go to the /locale directory and create a directory named after your language code.&lt;br /&gt;
#Inside that directory create a directory named LC_MESSAGES.&lt;br /&gt;
#Now create a language file with poEdit. Save the (yet) empty file to that dir (in the /locale/your_language_code/LC_MESSAGES/ folder). The file has to be be named according to your language-code. (look into the other directory for examples)&lt;br /&gt;
#In poEdit do the following:&lt;br /&gt;
##Open menu &#039;&#039;Catalog/Settings&#039;&#039;, enter the &#039;&#039;Paths&#039;&#039;-Tab&lt;br /&gt;
##Delete the existing path and add a new one pointing to the downloaded LimeSurvey sources&lt;br /&gt;
##Click on the &#039;&#039;Keywords&#039;&#039; tab, click on new item&lt;br /&gt;
##Add the keywords: &#039;gT&#039;, &#039;eT&#039;, &#039;neT:1,2&#039;, and &#039;ngT:1,2&#039; (without quotes).&lt;br /&gt;
##On the project info tab you will find &amp;quot;Plural Forms&amp;quot; at the bottom. Just copy &amp;amp; paste the following into this field: &#039;nplurals=2; plural=n != 1;&#039; (without quotes, again)&lt;br /&gt;
##Press &#039;OK&#039; to close the settings.&lt;br /&gt;
##Open the menu entry &#039;&#039;Catalog/Update from Sources&#039;&#039;&lt;br /&gt;
##If you did everything right it should now find all untranslated strings and add it to the .po file&lt;br /&gt;
#Translate everything you need to translate. The yellowish marked items are &#039;unclear&#039; translations and you should check/correct these first. Remember that is better to have no translation than a wrong one!&lt;br /&gt;
#To make LimeSurvey know about your language you must add it to the file classes/core/surveytranslator.php. Open that file with a text editor and add your language in the same way the other languages in that file are defined.&lt;br /&gt;
#Save. Send the new .po-File and the updated surveytranslator.php file to translations@limesurvey.org . If you want your name to be linked from/shown on the team-page please write so in the e-mail!&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Statistics&amp;diff=3264</id>
		<title>Statistics</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Statistics&amp;diff=3264"/>
		<updated>2012-03-28T06:26:47Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;The statistics feature is available from the menu of the browse screen, which - of course - is only available once a survey has been activated.&lt;br /&gt;
&lt;br /&gt;
This is a short [http://www.screencast.com/users/healthinformatics/folders/Jing/media/0a3c9a66-fb41-4a84-b7dc-c8af363c391f video tutorial], showing how to get to the statistics screen.&lt;br /&gt;
&lt;br /&gt;
=What is the statistics feature?=&lt;br /&gt;
&lt;br /&gt;
Let&#039;s say you&#039;ve got a survey running, or it is finished and you want to start analyzing the results. LimeSurvey can dump all the results into an Excel spreadsheet (or CSV file, or Microsoft Word file). You can do whatever takes your fancy with the data then. Alternatively you can use the statistics feature to have a look at your data and start getting some useful information from it.&lt;br /&gt;
&lt;br /&gt;
The statistics feature allows you to &#039;filter&#039; your data and retrieve numbers and summaries of different fields from it. The statistics script doesn&#039;t attempt to do highly complex filtering - but you&#039;d be surprised at the sort of information that can be easily obtained.&lt;br /&gt;
&lt;br /&gt;
=Viewing Results and Field Summaries=&lt;br /&gt;
&lt;br /&gt;
When you click the &amp;quot;Get statistics&amp;quot; button you will be presented with a list of all available questions. For each question there is a checkbox that can be selected in order to show a summary of this table, and an icon that when clicked (or if the mouse hovers over it) will give you the full text of the question. To view the results for a question or questions, check the checkbox(es) at the top of the question(s) and then click &amp;quot;View stats&amp;quot;. Alternatively to view the results for all available questions, check the &amp;quot;View summary of all available fields&amp;quot; box at the very top and then click &amp;quot;View stats&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You will then be given a &amp;quot;Results&amp;quot; table which will indicate the number of cases and a &amp;quot;Field Summary&amp;quot; table for each question selected which will summarize all possible answers in the question(s), their totals and their percentage.&lt;br /&gt;
&lt;br /&gt;
=Filtering data=&lt;br /&gt;
&lt;br /&gt;
Data can be filtered in several ways:&lt;br /&gt;
#By survey completion - use the dropdown at the top to select Completed, Incomplete or All records. For a discussion on incomplete responses see [[Browsing survey results]].&lt;br /&gt;
#By ID - use the inputs to filter by ID number&lt;br /&gt;
#By response - click on one or more responses in the list under each question to filter the data by those responses (use CTRL/click to select multiple responses in the same question). Note that if you choose to view summary of all available fields (checkbox at top) you will need to select your response filters before checking that box.&lt;br /&gt;
#By text - You can search the responses to a free text question type (and similar types) by entering a text. If you want to search for a partial string you can use the percentage sign (%) as wildcard. Example: If you look for &#039;Tom%&#039; it will find entries with &#039;Tomb&#039; and &#039;Tommy&#039;, etc.&lt;br /&gt;
&lt;br /&gt;
Selecting &amp;quot;View stats&amp;quot; will then give you the &amp;quot;Results&amp;quot; table, indicating the number of responses matching your criteria, and a &amp;quot;Field Summary&amp;quot; table for each question selected which will summarize all possible answers in the question(s), their totals and their percentage. It is important to note that these results are a subset of your total responses. So, for example, if your criteria display 146 records out of a total 180, the summary will show the breakdown of just those 146 records for that table.&lt;br /&gt;
&lt;br /&gt;
The images below indicate that I have elected to view the stats for &amp;quot;Employment status&amp;quot; of &#039;&#039;&#039;&#039;&#039;completed records/female/age 18-25&#039;&#039;&#039;&#039;&#039;. This gives me the results for 6 out of 14 records.&lt;br /&gt;
&lt;br /&gt;
[[File:stats_1_823x525.gif]]&lt;br /&gt;
&lt;br /&gt;
[[File:stats_2_823x504.gif]]&lt;br /&gt;
&lt;br /&gt;
Things to be cautious of&lt;br /&gt;
*If you set criteria on the same question that you ask for a summary, then that question will only present answers matching your criteria. So it is good practice not to set any criteria on the same question you are getting a summary of.&lt;br /&gt;
*To select multiple entries for a question hold down the CTRL button when clicking. To &#039;unselect&#039; the last criteria (if you want to clear all criteria from a question) click on the last highlighted answer with the CTRL button.&lt;br /&gt;
&lt;br /&gt;
=Browsing / Exporting filtered results=&lt;br /&gt;
&lt;br /&gt;
If you want to export the responses that match your criteria, click on the &amp;quot;export&amp;quot; button at the bottom of the &#039;Results&#039; table. This will bring up the usual export screen, however when you export the results you will only receive the responses that match your criteria. Similarly, click on browse to view the matching responses in the browse screen.&lt;br /&gt;
&lt;br /&gt;
=Graphs=&lt;br /&gt;
&lt;br /&gt;
For charting the library pChart is used which is completely included and usually doesn&#039;t have to be configured.&lt;br /&gt;
&lt;br /&gt;
However for some languages (like Chinese) the usual font used (Vera) does not cover the needed character set. In that case you can use the setting $chartfontfile to set a new TTF font file in config.php (Check out config-defaults.php for the right setting). For Chinese (Simplified and Traditional) we recommend to use the FireFlySung font which can be downloaded from [http://cle.linux.org.tw/fonts/FireFly/].&lt;br /&gt;
&lt;br /&gt;
After the graphs have been generated you can export these graphs easily. Use a right-mouse-click over the image and choose &amp;quot;Save image as&amp;quot; and save the graph as a .png-file to your chosen location. Normally all results are displayed as pie charts - only for question type &amp;quot;Multiple Options&amp;quot; bar graphs are used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:statistics_pie_chart.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:statistics_bar_chart.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;quot;incomplete responses&amp;quot;, &amp;quot;no answers&amp;quot; and not &amp;quot;completed/not displayed&amp;quot; counts=&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&#039;&#039;&#039;incomplete responses&#039;&#039;&#039;&amp;quot; counts: when the participant wasn&#039;t able to go till the end of the survey and thus haven&#039;t clicked the &amp;quot;Submit&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
Technically speaking, this is when there is no SubmitDate in the response table for this entry.&lt;br /&gt;
&lt;br /&gt;
A question with &amp;quot;&#039;&#039;&#039;no answer&#039;&#039;&#039;&amp;quot; counts: when the question was displayed, but the participant hasn&#039;t given an answer.&lt;br /&gt;
&lt;br /&gt;
Technically speaking, this is when the question is not mandatory, was displayed, received no answer and the user clicked Next or Submit: the consequence is that the database field for this answer is set to &amp;quot;&amp;quot; (empty string). This &amp;quot;no answer&amp;quot; status cannot be really computed for Date or pure Numerical questions where the database field cannot record a string.&lt;br /&gt;
&lt;br /&gt;
A question with &amp;quot;&#039;&#039;&#039;not completed/not displayed&#039;&#039;&#039;&amp;quot; counts: when the page containing the question was not displayed. This can be because of conditions, or just because the participant left the survey before this page was displayed (or just while this page is displayed, but without clicking the Next button).&lt;br /&gt;
&lt;br /&gt;
Technically speaking, the database field for this question is filled with a NULL value.&lt;br /&gt;
&lt;br /&gt;
=Public Statistics=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey includes functionality to display simple statistics to your participants after they have completed filling out an online survey.&lt;br /&gt;
&lt;br /&gt;
There are two steps involved in activating and displaying statistics to your participants. Firstly you must enable public statistics for your survey (by default this is turned off). This setting is in your main survey toolbar, General Settings &amp;amp;ndash; in the Presentation and Navigation Tab. Look for the setting &amp;amp;ldquo;Public Statistics&amp;amp;rdquo;. There is also a setting here called &amp;amp;ldquo;Show graphs in public statistics&amp;amp;rdquo; which &amp;amp;ndash; if turned on &amp;amp;ndash; will show graphs as well as the counts (by default only numerical statistics are displayed).&lt;br /&gt;
&lt;br /&gt;
Once you&amp;amp;rsquo;ve set your survey to display statistics, you need to indicate question-by-question which statistics are displayed to your participants. By default, no questions are selected for display.&lt;br /&gt;
&lt;br /&gt;
You choose which questions will be shown in the public statistics page by editing each question. In the Advanced Settings for each question is an option &amp;amp;ldquo;Show in public statistics&amp;amp;rdquo;. Once you set this advanced setting to &amp;amp;ldquo;Yes&amp;amp;rdquo; the question will be included on the public statistics page.&lt;br /&gt;
&lt;br /&gt;
[http://docs.limesurvey.org/Advanced+question+settings&amp;amp;structure;=English+Instructions+for+LimeSurvey&amp;amp;no;_bl=y#public_statistics * Additional question attribute &amp;quot;public_statistics&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What participants see&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Once you&amp;amp;rsquo;ve enabled public statistics, and selected some questions to display, an additional option will be visible to participants when they&amp;amp;rsquo;ve completed filling out your survey. In addition to the usual thank you, there will be a link to &amp;amp;ldquo;View the statistics for this survey&amp;amp;rdquo;&lt;br /&gt;
&lt;br /&gt;
If your participants click on this link they will be able to see a page detailing the responses to the questions you&amp;amp;rsquo;ve selected, and a graph (if you chose to display graphs too).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Changing the look of the public statistics page&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The public statistics page has a template of it&amp;amp;rsquo;s own that can be edited in the limesurvey template editor.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Project_Ideas_for_GSoC_2012&amp;diff=2514</id>
		<title>Project Ideas for GSoC 2012</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Project_Ideas_for_GSoC_2012&amp;diff=2514"/>
		<updated>2012-03-04T22:51:54Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Welcome=&lt;br /&gt;
&lt;br /&gt;
Welcome Google Summer of Code Student aspirants (:razz:)&lt;br /&gt;
&lt;br /&gt;
This page lists project ideas developed by the LimeSurvey Community. These tend to be areas that will get the most support as projects since they have been developed by people who know the project and what it needs the most. &#039;&#039;&#039;However&#039;&#039;&#039;, if you have your own idea for a project discuss your awesome idea with us in our [http://www.limesurvey.org/en/forum forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing list] or at [http://www.limesurvey.org/en/support/live-chat #limesurvey on irc.freenode.net]. Then submit your proposal. Good Luck (:biggrin:)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=Project ideas=&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Refactor all question types to a modular OOP format==&lt;br /&gt;
&lt;br /&gt;
If you look at the LimeSurvey source code (yii branch) you will notice that the code for the question types is strewn across the application.&lt;br /&gt;
&lt;br /&gt;
The goal of this task is to rewrite all question types to be objects, primarily inherited from one or more base question objects. A question type should have methods for display (several types of display like front ent/printable survey), response saving, configuration, statistics, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
*Extensive knowledge of PHP &amp;amp; Yii framework&lt;br /&gt;
*Very good kownledge of LimeSurvey inner workings&lt;br /&gt;
*Very good OOP knowledge&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
*Hard&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Implement a fully featured XMP-RPC API + API tests + unit test==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey urgently needs an API so all administration functions (and later even survey-taking functions) can be accessed without using the GUI. In addition you will be implementing an according unit test framework and implement unit &amp;amp; API tests across the whole application so we can make sure at any point in the development process that the application is functioning as it should.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
*Good PHP, SQL, Yii knowledge&lt;br /&gt;
*Good knowledge of the LimeSurvey administration and code&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
*Hard&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
c_schmitz&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==User Interface Improvements and Backend Tidy Ups==&lt;br /&gt;
&lt;br /&gt;
Help improve LimeSurvey&#039;s usability and flexibility through a range of small tasks such as:&lt;br /&gt;
* develop improved &#039;bulk&#039; question handling UI&lt;br /&gt;
* Tidy up input values on public surveys by moving required values from html inputs to javascript variables&lt;br /&gt;
&lt;br /&gt;
The idea is to provide ways of updating and modifying multiple questions, or multiple groups in one go. Often in a survey a user will need to make parallel changes to 5 or 6 questions all at once across a range of different groups. Being able to select various elements of questions, and then select a range of questions to edit would dramatically improve LimeSurvey&#039;s usability from the administrators perspective.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, Yii, Authentication protocols (openID, CAS, LDAP-bind, ...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jcleeland)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Implement a plugin framework for authentication/languages/ import/export modules==&lt;br /&gt;
&lt;br /&gt;
The idea is to design and implement a modular &amp;quot;framework&amp;quot; for LimeSurvey as well as convert the existing funcitonaly to according modules. The framework will define the API each plugin type must (or may) implement and propose basic methods that can be used by plugins (for instance how to store the plugins parameters in DB, etc.).&lt;br /&gt;
&lt;br /&gt;
The plugin framework should be in parts similar to the framework used by Joomla (XML description files in the plugin packages)&lt;br /&gt;
&lt;br /&gt;
Example description for authentication moduls:&lt;br /&gt;
&lt;br /&gt;
Currently authentication is only used for the survey-administration GUI and not the participants interface (tokens are used for this). With the new authentication framework it should be possible to define several authentication backends for frontend (survey participation) and backend (administration)&lt;br /&gt;
&lt;br /&gt;
A generic authentication framework must define the following services:&lt;br /&gt;
* User authentication: this interface must return the identity of the authenticated user if authentication is successful.&lt;br /&gt;
** Authentication may not always be based on a simple user/password form, so the proposed framework must be generic enough to enable authentication based on other schemes (using any numbers or interaction-pages between the server and the end-user or any other contextual parameter such as Referrer, session variable...&lt;br /&gt;
* User provisioning:&lt;br /&gt;
** when activated on the survey administration interface, an authentication module might be able to create a newly authenticated user into the LimeSurvey internal DB (which is required for setting the user rights on the platform). The newly created user can be assigned a default profile or a per-user profile (queried from an external database).&lt;br /&gt;
** when activated on the participants interface, the authentication module will provision the token table of the corresponding survey // alternatively the general-purpose cross-survey participants-database as described in the above GSoC idea.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, Yii&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Hard&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
c_schmitz&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Want to know more&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please read the [http://docs.limesurvey.org/tiki-index.php?page=GSOC+2010++Authentication+framework#FAQ FAQ about this project]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Custom Report Generation==&lt;br /&gt;
&lt;br /&gt;
The task is to make a module which will generate custom reports. Module should be able to do these things(at least) :-&lt;br /&gt;
*Creating various types of reports i.e. using tables, pie charts, graphs and bar-charts to name few.&lt;br /&gt;
*The resulting charts and other illustrations should be easy to read and understand, and should include the ability to export into standard office suites.&lt;br /&gt;
*Reports can be general or survey specific.&lt;br /&gt;
**General in the sense that it should show basic findings of a general survey graphically like number of users completing the survey, average time taken to complete the survey, average number of correct responses etc.&lt;br /&gt;
**Survey specific results should also be addressed properly e.g. how many users choose first option as there answer of a particular question, how many users didn&#039;t answer a specific question etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
OOP experience in PHP and experience with a PHP framework like CakePHP or CodeIgniter, jQuery. Strong mathematical background will help!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jcleeland)&lt;br /&gt;
&lt;br /&gt;
Diogo Gon&amp;amp;ccedil;alves (dionet)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Adding new questions/subquestions and groups dynamically==&lt;br /&gt;
&lt;br /&gt;
Currently in LimeSurvey once a survey is activate we can not&lt;br /&gt;
*Add or delete groups&lt;br /&gt;
*Add or delete questions&lt;br /&gt;
*Add or delete subquestions or change their codes&lt;br /&gt;
&lt;br /&gt;
The idea is to cover these shortcomings. And in addition, all those participants who have already taken that survey must also be notified about the changes. You should also work out in detail what happens to existing results when a survey is changed that way.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Experience with the PHP framework Yii and knowledge of inner working of LimeSurvey is must!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jcleeland)&lt;br /&gt;
&lt;br /&gt;
Diogo Gon&amp;amp;ccedil;alves (dionet)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Enhance Expression Manager==&lt;br /&gt;
&lt;br /&gt;
Starting with LimeSurvey 1.92, all of the front-end (survey-taking) processing is now managed using Expression Manager (EM).  EM implements a safe subset of PHP syntax so that authors can write complex equations.  It is integrated into LimeSuvey to control navigation (branching via relevance), validation, and tailoring/piping of content.  Although it is quite powerful, users are already asking for enhancements.&lt;br /&gt;
#Add a GUI for Expression Manager&lt;br /&gt;
**Background:  LimeSurvey has a nice GUI for building conditions, but it does not support complex equations such as those available within EM.  EM does have robust syntax highlighting after an equation is saved, which makes it easy to fix any syntax errors.  Hoever, users would like a GUI to ease authoring of equations.&lt;br /&gt;
**Strategy - use CodeMirror - see [http://bugs.limesurvey.org/view.php?id=5279 here]&lt;br /&gt;
***Create CodeMirror syntax file to do appropriate syntax highlighting (use C as base language), ensuring that CodeMirror knows the set of valid operators&lt;br /&gt;
***Use CodeMirror API to let it know the names of registered function and variable names&lt;br /&gt;
***Utilize auto-complete, ideally letting users see and choose among the availalbe function  syntaxes (e.g. when a function can take several paameters).&lt;br /&gt;
***Auto-completion of variable names should show the question and question type to make it easier for users to pick the correct variable.&lt;br /&gt;
#Support sub-question-level Relevance&lt;br /&gt;
**Background:  EM already supports user-entered relevance equations at the group and question levels.  It also generates sub-question-level relevance for features like array_filter.  Users would like to be able ot add additional relevance criteria at the sub-question level.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Add a relevance column to the display of sub-questions, and ensure entered relevance is saved the to database (the data model is already OK)&lt;br /&gt;
***Refactor createFieldMap() (or its successor) to read sub-question-level relevance into the run-time data structures so that passed to EM&lt;br /&gt;
***Enhance EM&#039;s sub-question-level data structures to hold sub-question-level releavance&lt;br /&gt;
***Update EM&#039;s _ValidateQuestion() and JavaScript generation functions to AND any manually-entered sub-question-level relevance equations with that auto-generated for array_filter and array_filter_exclude&lt;br /&gt;
***Update ShowSurveyLogicFile() to show sub-question-level relevance equations ***Rigorously unit and regresssion test these changes.&lt;br /&gt;
#Add Sub-question-level Validation&lt;br /&gt;
**Background:  The question-level validation supports regular-expression-based validation of each sub-question.  Users would like to have sub-question-level validation to implement things like a question for collecting user contact information, where there are different validation criteria for address parts (e.g. city, state, postal code) and phone numbers.&lt;br /&gt;
**Strategy:  Similar to sub-question-level relevance&lt;br /&gt;
***Add data entry fields for regular expression validation at the sub-question level, and ensure saved to database (which already has a preg field at the sub-question level)&lt;br /&gt;
***Ensure EM gets access to the new preg values (via upgrade to createFieldMap)&lt;br /&gt;
***Upgrade EM _ValidateQuesation() and function for generation of validation equations to include these new critiera.  EM already supports validation at the sub-question level (and changes the CSS style to show fields that fail this validation)&lt;br /&gt;
***Upgrade ShowSurveyLogicFile() to show sub-question-level validation rules&lt;br /&gt;
***Rigorously unit and regresssion test these changes.&lt;br /&gt;
#Add Sub-question-level mandatory criteria&lt;br /&gt;
**Background:  Many users have asked, via the forums, for ways to make parts of a multi-part questions mandatory, but make other parts optional.  LimeSurvey already provides many options, such as minimum and maxium numbers of answers; but users have asked for more fine-grained control, and currently can only achieve that via custom JavaScript.&lt;br /&gt;
**Strategy:  Similar to sub-question-level relevance&lt;br /&gt;
***Add checkbox to indicate mandatory status at the sub-question level&lt;br /&gt;
#Add native support for input-masks at the question and sub-question level&lt;br /&gt;
**Background:  One of the commonly used work-arounds deals with input masks, such as the jQuery meimomask plugin.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Add mask attribute at question and sub-question level&lt;br /&gt;
***Have EM generate needed JavaScript code to create and manage those masks&lt;br /&gt;
#Add EM reporting functions (tables)&lt;br /&gt;
**Background: There is commonly request for enhancemnt of the print answers table at the end of the survey.  Some users want to generate custom reports mid-survey.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Implement showAllResponsesExcept(attributeList,attributeTitleList,questionList) function.  questionList = list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.&lt;br /&gt;
***Implement showTheseResponses(attributeList,attributeTitleList,questionList) function. questionList = list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.&lt;br /&gt;
#Add better EM support for operations on array type questions&lt;br /&gt;
**Background:  Many of the EM validation rules are effectively statements like count the number of empty sub-questions, or sum the values of the sub-questions.  EM generates these functions itself, so there is no burden on the user, even if there ar dozens of sub-quetions.  However, manual editing of these questions is cumbersom. Users could benefit from special variables to access all of the elements of a question so that they could write functions like (sum(this) == 10)) and have it be expanded to (sum(q1_1, q1_2, ..., q1_N) == 10).  Note, there is already a &amp;quot;this&amp;quot; variable, but it does not apply to sub-questions.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Extend EM so that &amp;quot;this&amp;quot; variable gets expanded into a comma separate list of sub-question references if there are sub-questions.  Have this expansion carry the suffix, so this.valueNAOK would become q_1.valueNAOK, q_2.valueNAOK, ..., q_N.valueNAOK.&lt;br /&gt;
***This macro expansion should occur in group.php (e.g. in the process of generating JavaScript), rather than having this variable be resolved at run-time within JavaScript.&lt;br /&gt;
***Provide similar array-expansion macros for all variables (not just &amp;quot;this&amp;quot;) - such as qcode_vars.*.  This would also functions like sum(qcode_vars.NAOK), count(qcode_vars.NAOK), implode(&#039; &#039;, qcode_vars.valueNAOK)&lt;br /&gt;
***For questions with comments, create macros like qcode_vars_nc and qcode_vars_oc for no-comments and  only-comments&lt;br /&gt;
***For arrays that might need row or  column-level processing, create aliases  like qcode_rowname_vars and qcode_colname_vars so can expand each.  This would let us replace the current system for generating row and column sums with equations like sum(qcode_rowname_vars.NAOK) and be sure that the sums will honor array_filter and array_filter_exclude.&lt;br /&gt;
#Add EM functions to validate data entry against value sets managed by Enterprise Vocabulary Systems&lt;br /&gt;
**Background:  Healthcare and biological sciences increasing use large controlled vocabularies, terminologies, or ontologies.  Data entry systems for such domains require validation against those vocabularies.  Large open-source projects, like [https://cabig.nci.nih.gov/community/tools/LexEVS_Server LexEVS] and [http://apelon.com/Products/DTS/tabid/97/Default.aspx Apelon DTS] provide open APIs to access that content.  Such tools let one validate diagnostic codes, and even do incremental search into those vocabularies as one types.  The main open projects are standardizing on the [http://hssp.wikispaces.com/cts2 CTS-2] (Clinical Terminology Services-2) specification.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Create EM-compatible PHP and JavaScript functions to access CTS-2 compliant EVS systems&lt;br /&gt;
***Should include question and sub-question-level validation rules to validate the final entry.  Currently, thre are em_validation_q and em_validation_sq advanced quation attributes for validating questions and sub-questions based upon calls to external functions.  It may be desirable to support custom sub-question-level validation to validate each sub-question against different value sets.  If so, can follow the model of adding sub-question-level validation and relevance.  Alternatively, may be desirable to add sub-question-level advanced question options (if LimeSurvey community feels that there may be enough such extensions that such customization should be stored in a general attribute table rather than making the questions table wider).&lt;br /&gt;
***Should also include ability to do incremetal searches into the value sets&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, PHP Debugging (e.g. xdebug), Yii, LimeSurvey&#039;s Expression Manager and code-base in general&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium to Hard&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thomas White (TMSWhite)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Optimize LimeSurvey for Long Surveys (and better performance and maintenance in general)==&lt;br /&gt;
&lt;br /&gt;
Although LimeSurvey is excellent for short and mid-length surveys, it is not optimized for surveys with hundreds or thousands of questions - such as those used by epidemiologists or in clinical trials.  This project would tackle each of those main limitations.  Those sub-tasks, and the development strategy include:&lt;br /&gt;
#Support for more than 1000 database columns&lt;br /&gt;
**Background: LS creates a horizontal table for survey data collection, and such tables often are limited to at most 1000 columns&lt;br /&gt;
**Strategies:&lt;br /&gt;
***Remove unneeded columns from horizontal table (e.g. type &#039;X&#039;)&lt;br /&gt;
***Conditionally remove unneeded equation columns (e.g. let users specify a prefix for variable names that should not be stored)&lt;br /&gt;
***Add option for Entity Attribute Value data model for data collection (which can support unlimited number of columns.  See details [http://bugs.limesurvey.org/view.php?id=5289 here].&lt;br /&gt;
#Memory and Code Optimization&lt;br /&gt;
**Background: LS loads the survey definition data model into several different data structures, such that it uses at least twice as much storage as it really needs.  Expression Manager now holds all of the instrument definition data, so the other data stores are no longer needed.&lt;br /&gt;
**Strategy&lt;br /&gt;
***Remove need for buildsurveysession() - gap analysis to add in any missing content to EM&lt;br /&gt;
***Remove need for createFieldMap() - similar gap analysis&lt;br /&gt;
***Normalize EM data structures to avoid internal duplication (and refactor code to use normalized structures) (and document new data structures so that future developers know which to use, and how to use them)&lt;br /&gt;
****gInfo - renaming of groupSeqInfo, plus add missing group-level attributes (relevance, description)&lt;br /&gt;
****qInfo - renaming of questionSeq2relevance, plus add any missing attributes from $fieldarray; remove aid, sqid; move grelevance to gInfo&lt;br /&gt;
****aInfo - for storing answer arrays?&lt;br /&gt;
****sqInfo - renaming of q2subqInfo, indexed on sgqa(?); remove content gleaned from gInfo and qInfo&lt;br /&gt;
****gStatus - renaming of indexGseq - make hold only dynamic values; so move gtext and gname to gInfo; also remove gRelInfo, keeping any unique variables it contains&lt;br /&gt;
****qStatus - renaming of indexQseq - make hold only dynamic values; so move qtext, qhelp, gtext, gname to qInfo&lt;br /&gt;
****sqStatus - renaming of subQrelInfo - make hold only dynamic values&lt;br /&gt;
****groupRelevanceInfo - consolidate into indexGseq?&lt;br /&gt;
****knownVars - instead of copying content, use reference to gInfo and qInfo (e.g. remove question, relevance, grelevance, qcode, ansList, ansArray, onlynum).&lt;br /&gt;
****varNameAttr - remove; generate on the fly from gInfo, qInfo, and knownVars&lt;br /&gt;
****alias2varName - remove; generate on the fly from knownVars&lt;br /&gt;
***Refactor EM so that stores normalized copies of secondary language text&lt;br /&gt;
***Optionally load only current group for each page transition rather than holding entire survey definition in memory&lt;br /&gt;
***Refactor EM for consistent variable naming&lt;br /&gt;
****e.g. questionId =&amp;gt; qid; groupNum =&amp;gt; gid; groupSeq =&amp;gt; gseq; questionSeq =&amp;gt; qseq&lt;br /&gt;
#Run-Time Performance Optimization&lt;br /&gt;
**Background:  qanda.php loads the content to create the questions and answers.  It used to do this by separate database queries per question.&lt;br /&gt;
**Strategy&lt;br /&gt;
***Refactor qanda.php to remove queries (like for &amp;quot;other&amp;quot;, or sub-question text) - have it get that information from EM&lt;br /&gt;
***Refactor LS so that language switching does not require a re-load of the core logic, but just the new language content  (and that it gets this from EM)&lt;br /&gt;
***Refactor replacements.php and EM&lt;br /&gt;
****Should only need to call replacements.php once per page, so set those valeus as locally static in EM per page.&lt;br /&gt;
****Refactor group.php to pass {QUESTION_*} via replacements array, rather than as globals passed to templatereplace&lt;br /&gt;
#Design-Time Performance Optimization&lt;br /&gt;
**Background:  LS used to only load the information from the data model that was needed for the given question or group.  EM had to load the entire data model to properly syntax highlight everything.  This can lead to some performance degradation in very long surveys&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Add methods to EM to just load changes to model as questions or groups are added, removed, or updated&lt;br /&gt;
***Pass those updates into EM internals so that syntax highlighting continues to be correct&lt;br /&gt;
***Ensure that admin pages only call the subset of EM functions needed to do accurate syntax highlighting.&lt;br /&gt;
#Optimizations for Rapid Development&lt;br /&gt;
**Background:  LS has a nice GUI for editing single questions at a time.  However, it is not optimized to make changes to multiple questions at a time.  Some competitor systems let authors design surveys using an Excel template (e.g. so that they can do bulk find and replace, or easily copy similar portions or answer lists).  Short of a full-blown AJAX-enabled admin system, this has the highest throughput potential&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Create an Excel data model that would work for importing surveys&lt;br /&gt;
***Create import and validation routines from that model&lt;br /&gt;
***A similar model, which could be extended for LS, is noted [http://bugs.limesurvey.org/view.php?id=5105 here].&lt;br /&gt;
#Performance Validation&lt;br /&gt;
**Load test surveys of varying lenghts&lt;br /&gt;
**Identify performance and memory bottlenecks&lt;br /&gt;
**Idenfity minimum memory requirements for certain survey lengths and concurrent user volumes&lt;br /&gt;
**Propose strategy to overcome those performance issues&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, PHP Debugging (e.g. xdebug), Yii, LimeSurvey&#039;s Expression Manager and code-base in general, Load testing tool (e.g. webload), PHP Profiler&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium to Hard&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thomas White (TMSWhite)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Idea template==&lt;br /&gt;
&lt;br /&gt;
Describe the idea here in general terms&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain what sort of coding skills would be needed for a student to implement this project&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain the level of difficulty involved&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Put your name (and tag) here if you are willing to mentor a student for this idea&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=More information=&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
[[GSoC getting started|Check out our &#039;Get started&#039; page]] for setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
==Frequently Asked Questions==&lt;br /&gt;
&lt;br /&gt;
Check out [[GSoC FAQ|our GSoC FAQ page.]]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Project_Ideas_for_GSoC_2012&amp;diff=2531</id>
		<title>Project Ideas for GSoC 2012</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Project_Ideas_for_GSoC_2012&amp;diff=2531"/>
		<updated>2012-02-21T21:55:22Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Welcome=&lt;br /&gt;
&lt;br /&gt;
Welcome Google Summer of Code Student aspirants (:razz:)&lt;br /&gt;
&lt;br /&gt;
This page lists project ideas developed by the LimeSurvey Community. These tend to be areas that will get the most support as projects since they have been developed by people who know the project and what it needs the most. &#039;&#039;&#039;However&#039;&#039;&#039;, if you have your own idea for a project discuss your awesome idea with us in our [http://www.limesurvey.org/en/forum forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing list] or at [http://www.limesurvey.org/en/support/live-chat #limesurvey on irc.freenode.net]. Then submit your proposal. Good Luck (:biggrin:)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=Project ideas=&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Refactor all question types to a modular OOP format==&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Implement a fully featured XMP-RPC API complete with unit test==&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Add a unit testing framework and write tests==&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Integrate the DBSE into Yii==&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Develop Improved &#039;bulk&#039; Question Handling UI (and other UI enhancements)==&lt;br /&gt;
&lt;br /&gt;
The idea is to provide ways of updating and modifying multiple questions, or multiple groups in one go. Often in a survey a user will need to make parallel changes to 5 or 6 questions all at once across a range of different groups. Being able to select various elements of questions, and then select a range of questions to edit would dramatically improve LimeSurvey&#039;s usability from the administrators perspective.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, Yii, Authentication protocols (openID, CAS, LDAP-bind, ...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jcleeland)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Implement a modular authentication framework==&lt;br /&gt;
&lt;br /&gt;
The idea is to design and implement a modular authentication &amp;quot;framework&amp;quot; for LimeSurvey as well as some authentication modules. The Authentication framework will define the API each authentication plugin must (or may) implement and propose basic methods that can be used by plugins (for instance how to store the plugins parameters in DB, how to display a form using the survey template). A plugin will be responsible to implement, for each particular authentication backend, specific methods (some mandatory, some optional) such as: user authentication, user provisioning, user rights, ...&lt;br /&gt;
&lt;br /&gt;
Currently authentication is only used for the survey-administration GUI and not the participants interface (tokens are used for this). With the new authentication framework it will be possible to define several authentication backends and use some of them for participants-authentication.&lt;br /&gt;
&lt;br /&gt;
The generic authentication framework must define the following services:&lt;br /&gt;
* User authentication: this interface must return the identity of the authenticated user if authentication is successful.&lt;br /&gt;
** Authentication may not always be based on a simple user/password form, so the proposed framework must be generic enough to enable authentication based on other schemes (using any numbers or interaction-pages between the server and the end-user or any other contextual parameter such as Referrer, session variable...&lt;br /&gt;
* User provisioning:&lt;br /&gt;
** when activated on the survey administration interface, an authentication module might be able to create a newly authenticated user into the LimeSurvey internal DB (which is required for setting the user rights on the platform). The newly created user can be assigned a default profile or a per-user profile (queried from an external database).&lt;br /&gt;
** when activated on the participants interface, the authentication module will provision the token table of the corresponding survey // alternatively the general-purpose cross-survey participants-database as described in the above GSoC idea.&lt;br /&gt;
&lt;br /&gt;
The already existing authentication schemes will be ported to the new framework (internal-DB and Web server authentication delegation) and at least a new one will be implemented (openID, CAS, Shibboleth).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, CodeIgniter, Authentication protocols (openID, CAS, LDAP-bind, ...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Unknown&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Want to know more&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please read the [http://docs.limesurvey.org/tiki-index.php?page=GSOC+2010++Authentication+framework#FAQ FAQ about this project]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Custom Report Generation==&lt;br /&gt;
&lt;br /&gt;
The task is to make a module which will generate custom reports. Module should be able to do these things(at least) :-&lt;br /&gt;
*Creating various types of reports i.e. using tables, pie charts, graphs and bar-charts to name few.&lt;br /&gt;
*The resulting charts and other illustrations should be easy to read and understand, and should include the ability to export into standard office suites.&lt;br /&gt;
*Reports can be general or survey specific.&lt;br /&gt;
**General in the sense that it should show basic findings of a general survey graphically like number of users completing the survey, average time taken to complete the survey, average number of correct responses etc.&lt;br /&gt;
**Survey specific results should also be addressed properly e.g. how many users choose first option as there answer of a particular question, how many users didn&#039;t answer a specific question etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
OOP experience in PHP and experience with a PHP framework like CakePHP or CodeIgniter, jQuery. Strong mathematical background will help!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jcleeland)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Adding new questions/subquestions and groups dynamically==&lt;br /&gt;
&lt;br /&gt;
Currently in LimeSurvey once a survey is activate we can not&lt;br /&gt;
*Add or delete groups&lt;br /&gt;
*Add or delete questions&lt;br /&gt;
*Add or delete subquestions or change their codes&lt;br /&gt;
&lt;br /&gt;
The idea is to cover these shortcomings. And in addition, all those participants who have already taken that survey must also be notified about the changes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Experience with a PHP framework like CakePHP or CodeIgniter and knowledge of inner working of LimeSurvey is must!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jcleeland)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Enhance Expression Manager==&lt;br /&gt;
&lt;br /&gt;
Starting with LimeSurvey 1.92, all of the front-end (survey-taking) processing is now managed using Expression Manager (EM).  EM implements a safe subset of PHP syntax so that authors can write complex equations.  It is integrated into LimeSuvey to control navigation (branching via relevance), validation, and tailoring/piping of content.  Although it is quite powerful, users are already asking for enhancements.&lt;br /&gt;
#Add a GUI for Expression Manager&lt;br /&gt;
**Background:  LimeSurvey has a nice GUI for building conditions, but it does not support complex equations such as those available within EM.  EM does have robust syntax highlighting after an equation is saved, which makes it easy to fix any syntax errors.  Hoever, users would like a GUI to ease authoring of equations.&lt;br /&gt;
**Strategy - use CodeMirror - see [http://bugs.limesurvey.org/view.php?id=5279 here]&lt;br /&gt;
***Create CodeMirror syntax file to do appropriate syntax highlighting (use C as base language), ensuring that CodeMirror knows the set of valid operators&lt;br /&gt;
***Use CodeMirror API to let it know the names of registered function and variable names&lt;br /&gt;
***Utilize auto-complete, ideally letting users see and choose among the availalbe function  syntaxes (e.g. when a function can take several paameters).&lt;br /&gt;
***Auto-completion of variable names should show the question and question type to make it easier for users to pick the correct variable.&lt;br /&gt;
#Support sub-question-level Relevance&lt;br /&gt;
**Background:  EM already supports user-entered relevance equations at the group and question levels.  It also generates sub-question-level relevance for features like array_filter.  Users would like to be able ot add additional relevance criteria at the sub-question level.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Add a relevance column to the display of sub-questions, and ensure entered relevance is saved the to database (the data model is already OK)&lt;br /&gt;
***Refactor createFieldMap() (or its successor) to read sub-question-level relevance into the run-time data structures so that passed to EM&lt;br /&gt;
***Enhance EM&#039;s sub-question-level data structures to hold sub-question-level releavance&lt;br /&gt;
***Update EM&#039;s _ValidateQuestion() and JavaScript generation functions to AND any manually-entered sub-question-level relevance equations with that auto-generated for array_filter and array_filter_exclude&lt;br /&gt;
***Update ShowSurveyLogicFile() to show sub-question-level relevance equations ***Rigorously unit and regresssion test these changes.&lt;br /&gt;
#Add Sub-question-level Validation&lt;br /&gt;
**Background:  The question-level validation supports regular-expression-based validation of each sub-question.  Users would like to have sub-question-level validation to implement things like a question for collecting user contact information, where there are different validation criteria for address parts (e.g. city, state, postal code) and phone numbers.&lt;br /&gt;
**Strategy:  Similar to sub-question-level relevance&lt;br /&gt;
***Add data entry fields for regular expression validation at the sub-question level, and ensure saved to database (which already has a preg field at the sub-question level)&lt;br /&gt;
***Ensure EM gets access to the new preg values (via upgrade to createFieldMap)&lt;br /&gt;
***Upgrade EM _ValidateQuesation() and function for generation of validation equations to include these new critiera.  EM already supports validation at the sub-question level (and changes the CSS style to show fields that fail this validation)&lt;br /&gt;
***Upgrade ShowSurveyLogicFile() to show sub-question-level validation rules&lt;br /&gt;
***Rigorously unit and regresssion test these changes.&lt;br /&gt;
#Add Sub-question-level mandatory criteria&lt;br /&gt;
**Background:  Many users have asked, via the forums, for ways to make parts of a multi-part questions mandatory, but make other parts optional.  LimeSurvey already provides many options, such as minimum and maxium numbers of answers; but users have asked for more fine-grained control, and currently can only achieve that via custom JavaScript.&lt;br /&gt;
**Strategy:  Similar to sub-question-level relevance&lt;br /&gt;
***Add checkbox to indicate mandatory status at the sub-question level&lt;br /&gt;
#Add native support for input-masks at the question and sub-question level&lt;br /&gt;
**Background:  One of the commonly used work-arounds deals with input masks, such as the jQuery meimomask plugin.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Add mask attribute at question and sub-question level&lt;br /&gt;
***Have EM generate needed JavaScript code to create and manage those masks&lt;br /&gt;
#Add EM reporting functions (tables)&lt;br /&gt;
**Background: There is commonly request for enhancemnt of the print answers table at the end of the survey.  Some users want to generate custom reports mid-survey.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Implement showAllResponsesExcept(attributeList,attributeTitleList,questionList) function.  questionList = list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.&lt;br /&gt;
***Implement showTheseResponses(attributeList,attributeTitleList,questionList) function. questionList = list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.&lt;br /&gt;
#Add better EM support for operations on array type questions&lt;br /&gt;
**Background:  Many of the EM validation rules are effectively statements like count the number of empty sub-questions, or sum the values of the sub-questions.  EM generates these functions itself, so there is no burden on the user, even if there ar dozens of sub-quetions.  However, manual editing of these questions is cumbersom. Users could benefit from special variables to access all of the elements of a question so that they could write functions like (sum(this) == 10)) and have it be expanded to (sum(q1_1, q1_2, ..., q1_N) == 10).  Note, there is already a &amp;quot;this&amp;quot; variable, but it does not apply to sub-questions.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Extend EM so that &amp;quot;this&amp;quot; variable gets expanded into a comma separate list of sub-question references if there are sub-questions.  Have this expansion carry the suffix, so this.valueNAOK would become q_1.valueNAOK, q_2.valueNAOK, ..., q_N.valueNAOK.&lt;br /&gt;
***This macro expansion should occur in group.php (e.g. in the process of generating JavaScript), rather than having this variable be resolved at run-time within JavaScript.&lt;br /&gt;
***Provide similar array-expansion macros for all variables (not just &amp;quot;this&amp;quot;) - such as qcode_vars.*.  This would also functions like sum(qcode_vars.NAOK), count(qcode_vars.NAOK), implode(&#039; &#039;, qcode_vars.valueNAOK)&lt;br /&gt;
***For questions with comments, create macros like qcode_vars_nc and qcode_vars_oc for no-comments and  only-comments&lt;br /&gt;
***For arrays that might need row or  column-level processing, create aliases  like qcode_rowname_vars and qcode_colname_vars so can expand each.  This would let us replace the current system for generating row and column sums with equations like sum(qcode_rowname_vars.NAOK) and be sure that the sums will honor array_filter and array_filter_exclude.&lt;br /&gt;
#Add EM functions to validate data entry against value sets managed by Enterprise Vocabulary Systems&lt;br /&gt;
**Background:  Healthcare and biological sciences increasing use large controlled vocabularies, terminologies, or ontologies.  Data entry systems for such domains require validation against those vocabularies.  Large open-source projects, like [https://cabig.nci.nih.gov/community/tools/LexEVS_Server LexEVS] and [http://apelon.com/Products/DTS/tabid/97/Default.aspx Apelon DTS] provide open APIs to access that content.  Such tools let one validate diagnostic codes, and even do incremental search into those vocabularies as one types.  The main open projects are standardizing on the [http://hssp.wikispaces.com/cts2 CTS-2] (Clinical Terminology Services-2) specification.&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Create EM-compatible PHP and JavaScript functions to access CTS-2 compliant EVS systems&lt;br /&gt;
***Should include question and sub-question-level validation rules to validate the final entry.  Currently, thre are em_validation_q and em_validation_sq advanced quation attributes for validating questions and sub-questions based upon calls to external functions.  It may be desirable to support custom sub-question-level validation to validate each sub-question against different value sets.  If so, can follow the model of adding sub-question-level validation and relevance.  Alternatively, may be desirable to add sub-question-level advanced question options (if LimeSurvey community feels that there may be enough such extensions that such customization should be stored in a general attribute table rather than making the questions table wider).&lt;br /&gt;
***Should also include ability to do incremetal searches into the value sets&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, PHP Debugging (e.g. xdebug), Yii, LimeSurvey&#039;s Expression Manager and code-base in general&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium to Hard&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thomas White (TMSWhite)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Optimize LimeSurvey for Long Surveys (and better performance in general)==&lt;br /&gt;
&lt;br /&gt;
Although LimeSurvey is excellent for short and mid-length surveys, it is not optimized for surveys with hundreds or thousands of questions - such as those used by epidemiologists or in clinical trials.  This project would tackle each of those main limitations.  Those sub-tasks, and the development strategy include:&lt;br /&gt;
#Support for more than 1000 database columns&lt;br /&gt;
**Background: LS creates a horizontal table for survey data collection, and such tables often are limited to at most 1000 columns&lt;br /&gt;
**Strategies:&lt;br /&gt;
***Remove unneeded columns from horizontal table (e.g. type &#039;X&#039;)&lt;br /&gt;
***Conditionally remove unneeded equation columns (e.g. let users specify a prefix for variable names that should not be stored)&lt;br /&gt;
***Add option for Entity Attribute Value data model for data collection (which can support unlimited number of columns.  See details [http://bugs.limesurvey.org/view.php?id=5289 here].&lt;br /&gt;
#Memory Optimization&lt;br /&gt;
**Background: LS loads the survey definition data model into several different data structures, such that it uses about 2 to 10 times as much storage as it really needs.  Expression Manager now holds all of the instrument definition data, so the other data stores are no longer needed.&lt;br /&gt;
**Strategy&lt;br /&gt;
***Remove need for buildsurveysession() - gap analysis to add in any missing content to EM&lt;br /&gt;
***Remove need for createFieldMap() - similar gap analysis&lt;br /&gt;
***Normalize EM data structures to avoid internal duplication (there are about 4 structures that hold over-lapping code)&lt;br /&gt;
***Refactor EM so that stores normalized copies of secondary language text&lt;br /&gt;
#Run-Time Performance Optimization&lt;br /&gt;
**Background:  qanda.php loads the content to create the questions and answers.  It used to do this by separate database queries per question.&lt;br /&gt;
**Strategy&lt;br /&gt;
***Refactor qanda.php to remove queries (like for &amp;quot;other&amp;quot;, or sub-question text) - have it get that information from EM&lt;br /&gt;
***Refactor LS so that language switching does not require a re-load of the core logic, but just the new language content  (and that it gets this from EM)&lt;br /&gt;
#Design-Time Performance Optimization&lt;br /&gt;
**Background:  LS used to only load the information from the data model that was needed for the given question or group.  EM had to load the entire data model to properly syntax highlight everything.  This can lead to some performance degradation in very long surveys&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Add methods to EM to just load changes to model as questions or groups are added, removed, or updated&lt;br /&gt;
***Pass those updates into EM internals so that syntax highlighting continues to be correct&lt;br /&gt;
***Ensure that admin pages only call the subset of EM functions needed to do accurate syntax highlighting.&lt;br /&gt;
#Optimizations for Rapid Development&lt;br /&gt;
**Background:  LS has a nice GUI for editing single questions at a time.  However, it is not optimized to make changes to multiple questions at a time.  Some competitor systems let authors design surveys using an Excel template (e.g. so that they can do bulk find and replace, or easily copy similar portions or answer lists).  Short of a full-blown AJAX-enabled admin system, this has the highest throughput potential&lt;br /&gt;
**Strategy:&lt;br /&gt;
***Create an Excel data model that would work for importing surveys&lt;br /&gt;
***Create import and validation routines from that model&lt;br /&gt;
***A similar model, which could be extended for LS, is noted [http://bugs.limesurvey.org/view.php?id=5105 here].&lt;br /&gt;
#Performance Validation&lt;br /&gt;
**Load test surveys of varying lenghts&lt;br /&gt;
**Identify performance and memory bottlenecks&lt;br /&gt;
**Idenfity minimum memory requirements for certain survey lengths and concurrent user volumes&lt;br /&gt;
**Propose strategy to overcome those performance issues&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, PHP Debugging (e.g. xdebug), Yii, LimeSurvey&#039;s Expression Manager and code-base in general, Load testing tool (e.g. webload), PHP Profiler&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium to Hard&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thomas White (TMSWhite)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Idea template==&lt;br /&gt;
&lt;br /&gt;
Describe the idea here in general terms&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain what sort of coding skills would be needed for a student to implement this project&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain the level of difficulty involved&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Put your name (and tag) here if you are willing to mentor a student for this idea&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=More information=&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
[[GSoC getting started|Check out our &#039;Get started&#039; page]] for setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
==Frequently Asked Questions==&lt;br /&gt;
&lt;br /&gt;
Check out [[GSoC FAQ|our GSoC FAQ page.]]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Coding_guidelines&amp;diff=3136</id>
		<title>Coding guidelines</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Coding_guidelines&amp;diff=3136"/>
		<updated>2012-01-24T01:21:20Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Contents:__TOC__&lt;br /&gt;
&lt;br /&gt;
=Naming convention=&lt;br /&gt;
*Use the Hungarian Rule for variables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[t]NameOfVariable&lt;br /&gt;
&lt;br /&gt;
 | &amp;lt;strike&amp;gt;-&amp;lt;/strike&amp;gt;&amp;lt;strike&amp;gt;+&amp;lt;/strike&amp;gt;----&lt;br /&gt;
&lt;br /&gt;
 |        +--&amp;gt; Descriptive name&lt;br /&gt;
&lt;br /&gt;
 +--&amp;gt; Datatype stored (for example start with &amp;quot;a&amp;quot; if it is an array)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
aQuestionAttributes: Array to store the questions attributes, Mixed values&lt;br /&gt;
&lt;br /&gt;
dSurveyEnds: Date when the survey ends&lt;br /&gt;
&lt;br /&gt;
sContditionsOutput: String used to create the JS for conditions&lt;br /&gt;
*In case a function is declared &#039;&#039;&#039;do not&#039;&#039;&#039; use the Hungarian rule for the function name, instead use &amp;quot;Lower CamelCase&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
function questionsRetrieve( $iQID, $iSurvey)&lt;br /&gt;
*What about files? Unless Yii requires it in some way always name your files in lowercase - this prevents problems on systems using case-aware filesystems&lt;br /&gt;
&lt;br /&gt;
=Documentation=&lt;br /&gt;
&lt;br /&gt;
Please refer to this introduction: [[How to document your source code]].&lt;br /&gt;
&lt;br /&gt;
=Structures=&lt;br /&gt;
*Indent using spaces instead of TAB, or be gentle to announce how many spaces are your TABs long. There is wide ranging debate about tabs vs. spaces, many people prefer using tabs, others prefer spaces, others are happy with a mix of tabs and spaces. Because LimeSurvey is developed collaboratively, we ask that you leave your preference and follow this standard.&lt;br /&gt;
*The opening curly brace must be below the structure opening:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if (condition)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Using one line for a simple condition is very &amp;quot;fashionable&amp;quot;, a taste of &amp;quot;hacker&amp;quot;, but it is not clear at all:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 WRONG: if (condition) {do true} else {do false}&lt;br /&gt;
&lt;br /&gt;
 WRONG: if (condition) {do true}&lt;br /&gt;
&lt;br /&gt;
        else {do false}&lt;br /&gt;
&lt;br /&gt;
 RIGHT: if (condition)&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
           do true&lt;br /&gt;
&lt;br /&gt;
        } else&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
           do false&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
 RIGHT: swith $sSelector&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
              case X:&lt;br /&gt;
&lt;br /&gt;
                   ...&lt;br /&gt;
&lt;br /&gt;
                   break;&lt;br /&gt;
&lt;br /&gt;
              case Y:&lt;br /&gt;
&lt;br /&gt;
                   ...&lt;br /&gt;
&lt;br /&gt;
              default:&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: It&amp;amp;acute;s true that sometimes the &amp;quot;WRONG&amp;quot; way can be useful, but if it makes the straight reading difficult, please use the &amp;quot;RIGHT&amp;quot; way instead. Be gentle with your fellow developers.&lt;br /&gt;
*SQL sentences must respect the same rule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $sSQL = &amp;quot;SELECT field1, field2, field3 &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;WHERE condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;AND condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;OR condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;ORDER BY field1, field2&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*The same for HTML in views tags:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;td colspan=&#039;2&#039;&lt;br /&gt;
&lt;br /&gt;
     height=&#039;4&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   Some Text&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=HTML=&lt;br /&gt;
*As you will notice, a very customized HTML element can take a lot of lines (very expensive if you paid each one (:wink:) ) to avoid that, use &#039;CSS classes&#039;. In general, use classes to aesthetic related stuff: color, borders, backgrounds, font faces, sizes, etc.&lt;br /&gt;
*Respect W3C standards, and try to use the HTML understandable for all browsers. If one of them has a special feature, think if this feature is so special to break down the HTML in other browsers.&lt;br /&gt;
*Do not use PHP short tags &amp;lt;? ?&amp;gt;. Always use full PHP tags &amp;lt;?php ?&amp;gt;&lt;br /&gt;
*Any rules of the mentioned before: about CSS, well closed HTML tags and JS respect XHTML standards. Give it a try!.&lt;br /&gt;
&lt;br /&gt;
=Localization=&lt;br /&gt;
&lt;br /&gt;
Currently we are using the gT(),eT(),ngT() and neT() functions of the limesurvey_lang object for translations.&lt;br /&gt;
&lt;br /&gt;
Since LimeSurvey is available in 60 languages it is very important that your original English string (which will be picked up automatically for translation by our translators) is done right from the start. Imagine if we have to correct only one string at a later time - then 60 strings become invalid across the project and need to be re-translated by the poor translator souls.&lt;br /&gt;
* gT() is the original translation function. It will return a translated version of the string in the currently selected language. ie: echo &#039;&#039;$clang-&amp;gt;gT(&amp;quot;Hello&amp;quot;);&#039;&#039;&lt;br /&gt;
* ngT() returns multiple translations of a sentence or phrase for which alternate plural forms may apply. ie: &#039;&#039;echo sprintf($clang-&amp;gt;ngT(&#039;Please select at least %s answer&#039;,&#039;Please select at least %s answers&#039;,iMinimumAnswers),$iMinimumAnswers)&#039;&#039;;&lt;br /&gt;
* eT() echos the translation directly. (ie: instead of &#039;&#039;echo $clang-&amp;gt;gT(&amp;quot;Hello&amp;quot;);&#039;&#039; you can use &#039;&#039;$clang-&amp;gt;eT(&amp;quot;Hello&amp;quot;);&#039;&#039;&lt;br /&gt;
* neT() echos the multiple translations of the sentence or phrase for which alternate plural forms may apply directly.&lt;br /&gt;
&lt;br /&gt;
Please follow these important rules:&lt;br /&gt;
*&#039;&#039;&#039;Do not embed margin spaces&#039;&#039;&#039; in your translation. Instead use proper CSS formatting&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Visible? &#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Visible?&#039;);&lt;br /&gt;
*&#039;&#039;&#039;Do not capitalize words&#039;&#039;&#039; except where grammatically correct (like at the beginning of a sentence or for a brand name). LimeSurvey is not a newspaper.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Create A New Label Set&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Create a new label set&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Google Maps API Key&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Google Maps API key&#039;);&lt;br /&gt;
*&#039;&#039;&#039;Do not concatenate&#039;&#039;&#039; several translations to form a sentence or concatenate to an additional information (like a number or string). Instead use the sprint() or sprintf() function with placeholders.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo $clang-&amp;gt;gT(&#039;The sum must not be bigger than&#039;).$iMaxSum;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;The sum must not be bigger than %s&#039;),$iMaxSum);&lt;br /&gt;
&lt;br /&gt;
This comes from the problem that in other languages the setting of a sentence can be much different and the information $iMaxSum from the example above might be needed in the middle of the sentence.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo $clang-&amp;gt;gT(&#039;The user&#039;).$sUsername.$clang-&amp;gt;gT(&#039;was deleted.&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;The user %s was deleted.&#039;),$sUsername);&lt;br /&gt;
*&#039;&#039;&#039;Use the n*T functions where applicable&#039;&#039;&#039;. These functions show a different translation depending the number of items. Currently LimeSurvey only supports the numbers/situations 1 and &amp;gt;1.&lt;br /&gt;
&lt;br /&gt;
+Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;Please select at least %s answer(s).&#039;),$iMinimumAnswers);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;ngT(&#039;Please select at least %s answer&#039;,&#039;Please select at least %s answers&#039;,iMinimumAnswers),$iMinimumAnswers);&lt;br /&gt;
&lt;br /&gt;
=Miscellaneous=&lt;br /&gt;
*Do not use &amp;quot;global&amp;quot; to access to a declared variable in another process. Pass variables or arrays by reference, use the session or the configuration object.&lt;br /&gt;
*If using an auxiliary variable makes clear the code or process, just do it. If you are coding a very complex expression, calling to functions with parameters that are other functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WRONG:&lt;br /&gt;
&lt;br /&gt;
iAResult= fa(fb(p1,p2),fc(fd(p3),p4),p5)&lt;br /&gt;
&lt;br /&gt;
It will be more readable:&lt;br /&gt;
&lt;br /&gt;
iAuxB = fb(p1,p2)&lt;br /&gt;
&lt;br /&gt;
iAuxD = fd(p3)&lt;br /&gt;
&lt;br /&gt;
iAuxC = fc(iAuxD,p4)&lt;br /&gt;
&lt;br /&gt;
iAResult = fa(iAuxB, iAuxC, p5)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anyway, if you are in doubt about someone missing the point or you are afraid that your expression is obscure, take the chance of writing it in a more simple way, even if that involves the use of one or more auxiliary variables.&lt;br /&gt;
*Be efficient and save resources (memory and runtime). Things might work for a small survey but also try out your new feature with a survey that has 400 question, 5 languages and 20,000 responses (Yes, there are surveys like this out there).&lt;br /&gt;
*There is always a way to write a line avoiding to reach the 80th column. Think of the people who have a 14&amp;quot; CRT (:wink:)&lt;br /&gt;
*Keep a fluid dialog with the others coders, they have their own thoughts about what you are doing.&lt;br /&gt;
*Ask if you are in doubt.&lt;br /&gt;
&lt;br /&gt;
=IMPORTANT=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This is a free development, everything you do can be useful for others. If the feature is very personal there is a way to turn it into a universal solution. This is the challenge!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;quot;The difficulty within a solution is to solve it in a simple way&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Lance Burton, magician)&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Coding_guidelines&amp;diff=3138</id>
		<title>Coding guidelines</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Coding_guidelines&amp;diff=3138"/>
		<updated>2012-01-21T03:16:33Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Contents:__TOC__&lt;br /&gt;
&lt;br /&gt;
=Naming convention=&lt;br /&gt;
*Use the Hungarian Rule for variables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[t]NameOfVariable&lt;br /&gt;
&lt;br /&gt;
 | &amp;lt;strike&amp;gt;-&amp;lt;/strike&amp;gt;&amp;lt;strike&amp;gt;+&amp;lt;/strike&amp;gt;----&lt;br /&gt;
&lt;br /&gt;
 |        +--&amp;gt; Descriptive name&lt;br /&gt;
&lt;br /&gt;
 +--&amp;gt; Datatype stored (for example start with &amp;quot;a&amp;quot; if it is an array)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
aQuestionAttributes: Array to store the questions attributes, Mixed values&lt;br /&gt;
&lt;br /&gt;
dSurveyEnds: Date when the survey ends&lt;br /&gt;
&lt;br /&gt;
sContditionsOutput: String used to create the JS for conditions&lt;br /&gt;
*In case a function is declared &#039;&#039;&#039;do not&#039;&#039;&#039; use the Hungarian rule for the function name, only for the variables:&lt;br /&gt;
&lt;br /&gt;
function questionsRetrieve( $iQID, $iSurvey)&lt;br /&gt;
*What about files? Unless Yii requires it in some way always name your files in lowercase - this prevents problems on systems using case-aware filesystems&lt;br /&gt;
&lt;br /&gt;
=Documentation=&lt;br /&gt;
&lt;br /&gt;
Please refer to this introduction: [[How to document your source code]].&lt;br /&gt;
&lt;br /&gt;
=Structures=&lt;br /&gt;
*Indent using spaces instead of TAB, or be gentle to announce how many spaces are your TABs long. There is wide ranging debate about tabs vs. spaces, many people prefer using tabs, others prefer spaces, others are happy with a mix of tabs and spaces. Because LimeSurvey is developed collaboratively, we ask that you leave your preference and follow this standard.&lt;br /&gt;
*The opening curly brace must be below the structure opening:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if (condition)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Using one line for a simple condition is very &amp;quot;fashionable&amp;quot;, a taste of &amp;quot;hacker&amp;quot;, but it is not clear at all:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 WRONG: if (condition) {do true} else {do false}&lt;br /&gt;
&lt;br /&gt;
 WRONG: if (condition) {do true}&lt;br /&gt;
&lt;br /&gt;
        else {do false}&lt;br /&gt;
&lt;br /&gt;
 RIGHT: if (condition)&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
           do true&lt;br /&gt;
&lt;br /&gt;
        } else&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
           do false&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
 RIGHT: swith $sSelector&lt;br /&gt;
&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
              case X:&lt;br /&gt;
&lt;br /&gt;
                   ...&lt;br /&gt;
&lt;br /&gt;
                   break;&lt;br /&gt;
&lt;br /&gt;
              case Y:&lt;br /&gt;
&lt;br /&gt;
                   ...&lt;br /&gt;
&lt;br /&gt;
              default:&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: It&amp;amp;acute;s true that sometimes the &amp;quot;WRONG&amp;quot; way can be useful, but if it makes the straight reading difficult, please use the &amp;quot;RIGHT&amp;quot; way instead. Be gentle with your fellow developers.&lt;br /&gt;
*SQL sentences must respect the same rule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 $sSQL = &amp;quot;SELECT field1, field2, field3 &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;WHERE condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;AND condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;OR condition &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        .&amp;quot;ORDER BY field1, field2&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*The same for HTML in views tags:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;td colspan=&#039;2&#039;&lt;br /&gt;
&lt;br /&gt;
     height=&#039;4&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   Some Text&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=HTML=&lt;br /&gt;
*As you will notice, a very customized HTML element can take a lot of lines (very expensive if you paid each one (:wink:) ) to avoid that, use &#039;CSS classes&#039;. In general, use classes to aesthetic related stuff: color, borders, backgrounds, font faces, sizes, etc.&lt;br /&gt;
*Respect W3C standards, and try to use the HTML understandable for all browsers. If one of them has a special feature, think if this feature is so special to break down the HTML in other browsers.&lt;br /&gt;
*Do not use PHP short tags &amp;lt;? ?&amp;gt;. Always use full PHP tags &amp;lt;?php ?&amp;gt;&lt;br /&gt;
*Any rules of the mentioned before: about CSS, well closed HTML tags and JS respect XHTML standards. Give it a try!.&lt;br /&gt;
&lt;br /&gt;
=Localization=&lt;br /&gt;
&lt;br /&gt;
Currently we are using the gT(),eT(),ngT() and neT() functions of the limesurvey_lang object for translations.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is available in 60 languages so it is most important that your original English string (which will be picked up automatically for translation by our translators) is done right from the start. Imagine if we have to correct only one string at a later time - then 60 strings become invalid across the project and need to be re-translated by the poor translator souls.&lt;br /&gt;
&lt;br /&gt;
Please follow these important rules:&lt;br /&gt;
*&#039;&#039;&#039;Do not embed margin spaces&#039;&#039;&#039; in your translation. Instead use proper CSS formatting&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Visible? &#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Visible?&#039;);&lt;br /&gt;
*&#039;&#039;&#039;Do not capitalize words&#039;&#039;&#039; except where grammatically correct (like at the beginning of a sentence or for a brand name). LimeSurvey is not a newspaper.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Create A New Label Set&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Create a new label set&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Google Maps API Key&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: $clang-&amp;gt;eT(&#039;Google Maps API key&#039;);&lt;br /&gt;
*&#039;&#039;&#039;Do not concatenate&#039;&#039;&#039; several translations to form a sentence or concatenate to an additional information (like a number or string). Instead use the sprint() or sprintf() function with placeholders.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo $clang-&amp;gt;gT(&#039;The sum must not be bigger than&#039;).$iMaxSum;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;The sum must not be bigger than %s&#039;),$iMaxSum);&lt;br /&gt;
&lt;br /&gt;
This comes from the problem that in other languages the setting of a sentence can be much different and the information $iMaxSum from the example above might be needed in the middle of the sentence.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo $clang-&amp;gt;gT(&#039;The user&#039;).$sUsername.$clang-&amp;gt;gT(&#039;was deleted.&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;The user %s was deleted.&#039;),$sUsername);&lt;br /&gt;
*&#039;&#039;&#039;Use the n*T functions where applicable&#039;&#039;&#039;. These functions show a different translation depending the number of items. Currently LimeSurvey only supports the numbers/situations 1 and &amp;gt;1.&lt;br /&gt;
&lt;br /&gt;
+Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#F00&#039;&amp;gt;Wrong&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;gT(&#039;Please select at least %s answer(s).&#039;),$iMinimumAnswers);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#060&#039;&amp;gt;Right&amp;lt;/span&amp;gt;: echo sprintf($clang-&amp;gt;ngT(&#039;Please select at least %s answer&#039;,&#039;Please select at least %s answers&#039;,iMinimumAnswers),$iMinimumAnswers);&lt;br /&gt;
&lt;br /&gt;
=Miscellaneous=&lt;br /&gt;
*Do not use &amp;quot;global&amp;quot; to access to a declared variable in another process. Pass variables or arrays by reference, use the session or the configuration object.&lt;br /&gt;
*If using an auxiliary variable makes clear the code or process, just do it. If you are coding a very complex expression, calling to functions with parameters that are other functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WRONG:&lt;br /&gt;
&lt;br /&gt;
iAResult= fa(fb(p1,p2),fc(fd(p3),p4),p5)&lt;br /&gt;
&lt;br /&gt;
It will be more readable:&lt;br /&gt;
&lt;br /&gt;
iAuxB = fb(p1,p2)&lt;br /&gt;
&lt;br /&gt;
iAuxD = fd(p3)&lt;br /&gt;
&lt;br /&gt;
iAuxC = fc(iAuxD,p4)&lt;br /&gt;
&lt;br /&gt;
iAResult = fa(iAuxB, iAuxC, p5)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anyway, if you are in doubt about someone missing the point or you are afraid that your expression is obscure, take the chance of writing it in a more simple way, even if that involves the use of one or more auxiliary variables.&lt;br /&gt;
*Be efficient and save resources (memory and runtime). Things might work for a small survey but also try out your new feature with a survey that has 400 question, 5 languages and 20,000 responses (Yes, there are surveys like this out there).&lt;br /&gt;
*There is always a way to write a line avoiding to reach the 80th column. Think of the people who have a 14&amp;quot; CRT (:wink:)&lt;br /&gt;
*Keep a fluid dialog with the others coders, they have their own thoughts about what you are doing.&lt;br /&gt;
*Ask if you are in doubt.&lt;br /&gt;
&lt;br /&gt;
=IMPORTANT=&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This is a free development, everything you do can be useful for others. If the feature is very personal there is a way to turn it into a universal solution. This is the challenge!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;quot;The difficulty within a solution is to solve it in a simple way&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Lance Burton, magician)&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Using_regular_expressions&amp;diff=3681</id>
		<title>Using regular expressions</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Using_regular_expressions&amp;diff=3681"/>
		<updated>2011-10-14T01:17:15Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
(Perl) Regular Expressions must start and finish with a forward slash (&amp;quot;/&amp;quot;). You can find a good library of regular expressions at http://www.regxlib.net/. These patterns will almost all work if surrounded with the forward slash.&lt;br /&gt;
&lt;br /&gt;
To test your regex you can [http://www.regxlib.net/RETester.aspx use this regex tester].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Please add successfully tested regular expressions!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples (note that these are all one line):&lt;br /&gt;
&lt;br /&gt;
=SPECIAL NOTE: Regular Expressions in Conditions=&lt;br /&gt;
&lt;br /&gt;
Note that when using regular expressions in the condition editor, do NOT include the beginning and ending slash.&lt;br /&gt;
&lt;br /&gt;
=Email Validation:=&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above regex will not validate email adresses with &amp;quot;+&amp;quot; - which is valid, and e.g. promoted by gmail. The below regex is slightly modified and allows &amp;quot;+&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^(\w[-._+\w]*\w@\w[-._\w]*\w\.\w{2,3})$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is still far from perfect - but I think its better then the original (also because start-of-string and end-of-string anchors are added). Mind. This will allow e.g. abc+++defg@somemail.office.com. Ideally the regex should be modified to only allow one &amp;quot;+&amp;quot; charachter.&lt;br /&gt;
&lt;br /&gt;
=Postcodes:=&lt;br /&gt;
&lt;br /&gt;
==Australian Postcodes:==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^[0-9]{4}/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Canadian Postcodes:==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^[a-zA-Z]\d{1}[a-zA-Z](\-| |)\d{1}[a-zA-Z]\d{1}$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==US Postal Codes:==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^[0-9]{5}([- /]?[0-9]{4})?$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Phone Numbers=&lt;br /&gt;
&lt;br /&gt;
==US Phone Number:==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^(?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4}$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^[\(\)\.\- ]{0,}[0-9]{3}[\(\)\.\- ]{0,}[0-9]{3}[\(\)\.\- ]{0,}[0-9]{4}[\(\)\.\- ]{0,}$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This second option will match all phone Canadian and US phone numbers that include non-digit symbols including&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; . ( ) - (space)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will allow you to match phone numbers which resemble below.&lt;br /&gt;
*(555)555 5555&lt;br /&gt;
*555.555.5555&lt;br /&gt;
*555 555 5555&lt;br /&gt;
*(555)-555-5555&lt;br /&gt;
*555-555-5555&lt;br /&gt;
*555555555&lt;br /&gt;
&lt;br /&gt;
==Australian Phone Number:==&lt;br /&gt;
&lt;br /&gt;
The following patterns match all various Australian mobile and landline phone numbers including with &amp;quot;+61&amp;quot; country prefix eg:&lt;br /&gt;
*(02) 9123 6535&lt;br /&gt;
*03 1234-5345&lt;br /&gt;
*0412 345 678&lt;br /&gt;
*+61 2 3456 789&lt;br /&gt;
&lt;br /&gt;
But not:&lt;br /&gt;
* 234 3450 234&lt;br /&gt;
*a234 534 3432&lt;br /&gt;
*134567&lt;br /&gt;
*123456789013&lt;br /&gt;
&lt;br /&gt;
Brackets, white space and hypens are ignored.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;NOTE: The &#039;PRECICE&#039; versions listed here match against the first four or five didgets in a number to ensure that they are valid Australian numbers.&lt;br /&gt;
&lt;br /&gt;
The &#039;NOT VERY PRECISE&#039; only match against the first and second didgit so may allow invaid numbers&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===All Australian phone numbers (mobile and landline - area code required)===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^\(?(?:\+?61|0)(?:(?:2\)?[ -]?(?:3[ -]?[38]|[46-9][ -]?[0-9]|5[ -]?[0-35-9])|3\)?(?:4[ -]?[0-57-9]|[57-9][ -]?[0-9]|6[ -]?[1-67])|7\)?[ -]?(?:[2-4][ -]?[0-9]|5[ -]?[2-7]|7[ -]?6)|8\)?[ -]?(?:5[ -]?[1-4]|6[ -]?[0-8]|[7-9][ -]?[0-9]))(?:[ -]?[0-9]){6}|4\)?[ -]?(?:(?:[01][ -]?[0-9]|2[ -]?[0-57-9]|3[ -]?[1-9]|4[ -]?[7-9]|5[ -]?[018])[ -]?[0-9]|3[ -]?0[ -]?[0-5])(?:[ -]?[0-9]){5})$/&lt;br /&gt;
&lt;br /&gt;
NOT VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\+?61|0)[2-478](?:[ -]?[0-9]){8}$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===All Australian phone numbers (landlines only - area code required)===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^\(?(?:\+?61|0)(?:2\)?[ -]?(?:3[ -]?[38]|[46-9][ -]?[0-9]|5[ -]?[0-35-9])|3\)?(?:4[ -]?[0-57-9]|[57-9][ -]?[0-9]|6[ -]?[1-67])|7\)?[ -]?(?:[2-4][ -]?[0-9]|5[ -]?[2-7]|7[ -]?6)|8\)?[ -]?(?:5[ -]?[1-4]|6[ -]?[0-8]|[7-9][ -]?[0-9]))(?:[ -]?[0-9]){6}$/&lt;br /&gt;
&lt;br /&gt;
NOT VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\+?61|\(?0)[2378]\)?(?:[ -]?[0-9]){8}$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===New South Wales landline phone numbers (area code optional)===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)2\)?[ -]?)?(?:3[ -]?[38]|[46-9][ -]?[0-9]|5[ -]?[0-35-9])(?:[ -]?[0-9]){6}$/&lt;br /&gt;
&lt;br /&gt;
NOT VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)2\)?(?:[ -]?[0-9]){7}[0-9]$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Victorian and Tasmanian landline phone numbers (area code optional)===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)3\)?[ -]?)?(?:4[ -]?[0-57-9]|[57-9][ -]?[0-9]|6[ -]?[1-67])(?:[ -]?[0-9]){6}$/&lt;br /&gt;
&lt;br /&gt;
NOT VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)3\)?(?:[ -]?[0-9]){7}[0-9]$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Queensland landline phone numbers (area code optional)===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)7\)?[ -]?)?(?:[2-4][ -]?[0-9]|5[ -]?[2-7]|7[ -]?6)(?:[ -]?[0-9]){6}$/&lt;br /&gt;
&lt;br /&gt;
NOT VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)7\)?(?:[ -]?[0-9]){7}[0-9]$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===South Australia, Northern Territory, Western Australia landline phone numbers (area code optional)===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)8\)?[ -]?)?(?:5[1-4]|6[0-8]|[7-9][0-9])$/&lt;br /&gt;
&lt;br /&gt;
NOT VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)8\)?(?:[ -]?[0-9]){7}[0-9]$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Australian Mobile phone numbers only===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\+?61|0)4 ?(?:(?:[01] ?[0-9]|2 ?[0-57-9]|3 ?[1-9]|4 ?[7-9]|5 ?[018]) ?[0-9]|3 ?0 ?[0-5])(?: ?[0-9]){5}$/&lt;br /&gt;
&lt;br /&gt;
NOT VERY PRECISE&lt;br /&gt;
&lt;br /&gt;
/^(?:\(?(?:\+?61|0)4\)?(?:[ -]?[0-9]){7}[0-9]$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=German marks (with optional plus or minus)=&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^[1-6]{1}[\+|\-]?$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Age Validation=&lt;br /&gt;
&lt;br /&gt;
===Example: Age 20-99===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/([2-9][0-9])/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example: Age 18-35===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/(1[8-9]|2[0-9]|3[0-5])/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example: Age 19-65===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;(1[8-9]|[2-5][0-9]|6[0-5])$&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Number validation=&lt;br /&gt;
&lt;br /&gt;
==Numbers from 1 to 99999==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9])$/&amp;lt;/nowiki&amp;gt;  &amp;lt;nowiki&amp;gt;/^[1-9][0-9]{0,4}$/ does the same as above but should run a little faster&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Numbers from 1 to 999, 1.000 to 999.999 to 999.999.999==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^[1-9][0-9]{0,2}(?:\.[0-9]{3}){0,2}$/&lt;br /&gt;
&lt;br /&gt;
accepts numbers from 1 to 999, 1.000 to 999.999 to 999.999.999 but&lt;br /&gt;
&lt;br /&gt;
rejects numbers like 999.1.1 , 94.22.22, 999.1.22, 999.11.1, 999.1.333&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Number validation with optionnal decimal (for price)==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^([1][0-9][0-9]|[1-9][0-9]|[0-9])[[\.)[0-9][0-9])?$/ accepts numbers from 0 to 199, with 2 decimal optionnal&amp;lt;/nowiki&amp;gt;  &amp;lt;nowiki&amp;gt;/^[1-9][0-9]{0,2}(?:,?[0-9]{3}){0,3}\.[0-9]{2}$/&lt;br /&gt;
&lt;br /&gt;
 forces two decimal points&lt;br /&gt;
&lt;br /&gt;
 accepts numbers from 1.00 to 999,999,999.00 with an optional comma delimiting thousands/millions&lt;br /&gt;
&lt;br /&gt;
 including all of the following: 1.00, 1,000.00 , 12,345.67 , 12345,02 , 123,456,468.00 , 1234566.00 , 123456789.00&lt;br /&gt;
&lt;br /&gt;
 but not 1,23.00 , 12,3.4 or 1234,43.04&amp;lt;/nowiki&amp;gt;  &amp;lt;nowiki&amp;gt;/^[1-9][0-9]{0,2}(?:,?[0-9]{3}){0,3}(?:\.[0-9]{2})?$/ same as above but the two decimal points are optional&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ==Month (1-12)==&lt;br /&gt;
&lt;br /&gt;
 If you want to ask for the month a person was born you can validate the input as follows:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;/^[0]*[1-9]$|^[0]*1[0-2]$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 =Minimum width (set to 3 in this example)=&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;/^.{3,}$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 =Currency=&lt;br /&gt;
&lt;br /&gt;
 ==US currency (dollar sign and cents optional)==&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;/^\$?\d+(\.(\d{2}]]?$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Swiss price==&lt;br /&gt;
&lt;br /&gt;
A number with two decimal numbers after the decimal point of which the last one is either a 5 or a 0:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^(\d+)(\.\d(05)?)?$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Validate score=&lt;br /&gt;
&lt;br /&gt;
==1-10==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^[1-9]{1}$|^10$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==1-100==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;/^[1-9]?[0-9]{1}$|^100$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Text validation=&lt;br /&gt;
&lt;br /&gt;
currently multiple short text doesn&#039;t support minimum or maximum answers. One way around this is to use a long free text type question with a regular expression.&lt;br /&gt;
&lt;br /&gt;
The following test for at least one word per line for at least 3 lines and no more than 10 lines. &amp;lt;nowiki&amp;gt;/(?:[&amp;lt;/div&amp;gt;,.;:?!&amp;amp; \n\r]+(?: [&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;,.;:?!&amp;amp; \n\r]+)*)(?:[,.;:?!&amp;amp; \n\r]?(?:\n|\r|\n\r|\r\n)(?:[&amp;lt;/div&amp;gt;,.;:?!&amp;amp; \n\r]+(?: [&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;,.;:?!&amp;amp; \n\r]+)*)){2,10}/is&amp;lt;/nowiki&amp;gt;If you wanted, say five words per line you could change the first and last star/asterisk to {4,} e.g. &amp;lt;nowiki&amp;gt;/(?:[&amp;lt;/div&amp;gt;,.;:?!&amp;amp; \n\r]+(?: [&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;,.;:?!&amp;amp; \n\r]+){4,})(?:[,.;:?!&amp;amp; \n\r]?(?:\n|\r|\n\r|\r\n)(?:[&amp;lt;/div&amp;gt;,.;:?!&amp;amp; \n\r]+(?: [&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;,.;:?!&amp;amp; \n\r]+){4,})){2,10}/is&amp;lt;/nowiki&amp;gt;If you wanted one or more words per line on between 1 and 5 lines, you can change the content of the last curley braces to {0,4} (note you use 0 because you&#039;re already matching the first line. &amp;lt;nowiki&amp;gt;/(?:[&amp;lt;/div&amp;gt;,.;:?!&amp;amp; \n\r]+(?: [&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;,.;:?!&amp;amp; \n\r]+)*)(?:[,.;:?!&amp;amp; \n\r]?(?:\n|\r|\n\r|\r\n)(?:[&amp;lt;/div&amp;gt;,.;:?!&amp;amp; \n\r]+(?: [&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;,.;:?!&amp;amp; \n\r]+)*)){0,4}/is&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Word count==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;The following restricts the number of words allowed to a minimum of 1 and a maximum of 200&lt;br /&gt;
&lt;br /&gt;
/^[-\w]+(?:\W+[-\w]+){0,199}\W*$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;To increase the minimum change the zero part of {0,199}&lt;br /&gt;
&lt;br /&gt;
To increase or decrease the maximum change the &amp;quot;199&amp;quot; part of {0,199}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Time validation=&lt;br /&gt;
&lt;br /&gt;
There are a number of ways of writing time formats. Some of the possible options are 12 hour or 24 hour, with seconds or without. Currently  (2009/04/06) LimeSurvey (v1.80plus) doesn&#039;t have a Time queston type so instead you can use &amp;quot;short free text&amp;quot; with one of the nine validation regular expressions below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;The following three validation strings test for 24 hour time (in order of appearences) without seconds, with optional seconds lastly with seconds required.&lt;br /&gt;
&lt;br /&gt;
/^(?:[01][0-9]|2[0-3]):[0-5][0-9]$/&lt;br /&gt;
&lt;br /&gt;
/^(?:[01][0-9]|2[0-3]):[0-5][0-9](?::[0-5][0-9])?$/&lt;br /&gt;
&lt;br /&gt;
/^(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/~/pp&amp;lt;span style=&amp;quot;color:pp~The following three match 12 hour time, as above with seconds, optional seconds and with seconds required&lt;br /&gt;
&lt;br /&gt;
/^(?&amp;quot;&amp;gt;00:[0-5][0-9] (?:am|AM)|(?:0[1-9]|1[01]):[0-5][0-9] (?:[ap]m|[AP]M)|12:[0-5][0-9] (?:pm|PM))$/&lt;br /&gt;
&lt;br /&gt;
/^(?:00:[0-5][0-9](?::[0-5][0-9])? (?:am|AM)|(?:0[1-9]|1[01]):[0-5][0-9](?::[0-5][0-9])? (?:[ap]m|[AP]M)|12:[0-5][0-9](?::[0-5][0-9])? (?:pm|PM))$/&lt;br /&gt;
&lt;br /&gt;
/^(?:00:[0-5][0-9]:[0-5][0-9] (?:am|AM)|(?:0[1-9]|1[01]):[0-5][0-9]:[0-5][0-9] (?:[ap]m|[AP]M)|12:[0-5][0-9]:[0-5][0-9] (?:pm|PM))$/~/pp&amp;lt;/span&amp;gt;pp~The following three match either 12 or 24 hour time as above with seconds, optional seconds and with seconds required&lt;br /&gt;
&lt;br /&gt;
/^(?:(?:00:[0-5][0-9] (?:am|AM)|(?:0[1-9]|1[01]):[0-5][0-9] (?:[ap]m|[AP]M)|12:[0-5][0-9] (?:pm|PM))|(?:[01][0-9]|2[0-3]):[0-5][0-9])$/&lt;br /&gt;
&lt;br /&gt;
/^(?:(?:00:[0-5][0-9](?&amp;lt;center&amp;gt;[0-5][0-9])? (?:am|AM)|(?:0[1-9]|1[01]):[0-5][0-9](?&amp;lt;/center&amp;gt;[0-5][0-9])? (?:[ap]m|[AP]M)|12:[0-5][0-9](?&amp;lt;center&amp;gt;[0-5][0-9])? (?:pm|PM))|(?:[01][0-9]|2[0-3]):[0-5][0-9](?&amp;lt;/center&amp;gt;[0-5][0-9])?)$/&lt;br /&gt;
&lt;br /&gt;
/^(?:(?:00:[0-5][0-9]:[0-5][0-9] (?:am|AM)|(?:0[1-9]|1[01]):[0-5][0-9]:[0-5][0-9] (?:[ap]m|[AP]M)|12:[0-5][0-9]:[0-5][0-9] (?:pm|PM))|(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=US States=&lt;br /&gt;
&lt;br /&gt;
To validate for one state use the following (example is Texas):&lt;br /&gt;
*TX uppercase only = &amp;lt;nowiki&amp;gt;/^(TX)$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
*tx lowercase only = &amp;lt;nowiki&amp;gt;/^(tx)$/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
*TX upper or lowercase = &amp;lt;nowiki&amp;gt;/^([T|t][X|x])$/&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2011&amp;diff=2487</id>
		<title>Project ideas for GSOC 2011</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2011&amp;diff=2487"/>
		<updated>2011-03-30T23:59:01Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Welcome=&lt;br /&gt;
&lt;br /&gt;
Welcome Google Summer of Code Student aspirants (:razz:)&lt;br /&gt;
&lt;br /&gt;
This page lists project ideas developed by the LimeSurvey Community. These tend to be areas that will get the most support as projects since they have been developed by people who know the project and what it needs the most. &#039;&#039;&#039;However&#039;&#039;&#039;, if you have your own idea for a project discuss your awesome idea with us in our [http://www.limesurvey.org/en/forum forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing list] or at [http://www.limesurvey.org/en/support/live-chat #limesurvey on irc.freenode.net]. Then submit your proposal. Good Luck (:biggrin:)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=Project ideas=&lt;br /&gt;
&lt;br /&gt;
==Central participants database (User panel)==&lt;br /&gt;
&lt;br /&gt;
Develop a central &#039;participants&#039; database for LimeSurvey that can be used as a central registry of participants between surveys. The database should allow&lt;br /&gt;
* adding/removing of users along with flexible data to store related information for users&lt;br /&gt;
* simple copying of user-information to individual survey token tables&lt;br /&gt;
* ability to link user entries with survey responses if the linked survey was not unanimous (UUIDs?)&lt;br /&gt;
* ability for survey participants to register in the panel&lt;br /&gt;
* ability to update the flexible user data from collected results&lt;br /&gt;
* a &#039;do not email&#039; blacklist to allow people to automatically unsubscribe&lt;br /&gt;
* data ownership features for multi-user systems - allow different LimeSurvey users to &#039;own&#039; different participants&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Database and PHP coding, CodeIgniter&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate to high - the coding would be relatively simple, but will entail complex database relationships&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Port the LimeSurvey front-end to CodeIgniter==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is still written using old procedural code. We want to take the next step into the future and use a MVC-framework name CodeIgniter and port the whole application to this new framework. However proting the whole application is too much for one students. That is why we will split the task into smaller ones. This particular task deals with porting the front-end of LimeSurvey to CodeIgniter - this means all the parts that can be seen by the average survey participant:&lt;br /&gt;
*Survey taking&lt;br /&gt;
*Public statistics&lt;br /&gt;
*Central landing page&lt;br /&gt;
&lt;br /&gt;
During the rewrite you will be prompted also to encapsulate certain functions to objects where easily doable and it makes sense - we do not want you to rewrite everything. Since you are only working on a certain part of LimeSurvey and other students will port the back-end (=administration) of LimeSurvey you will be required to coordinate your coding with the other students.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
OOP experience in PHP and experience with a PHP framework like CakePHP or CodeIgniter are definately a must. You should get busy with LimeSurvey as early as possible. Students can raise their chance to get accepted by showing off according knowledge about LimeSurvey inner workings.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you fulfill the requirements above the difficulty in this task is to gradually modernize an application with a modern coding approach while resisting the natural urge to rewrite everything at once. Our mantra to modernizing the application is that the framework is just laying the new fundaments while the fance walls can be built later. So we lay the fundament first and make it stable, then we build new walls (See also [[LimeSurvey roadmap|the LimeSurvey roadmap]] )&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
Thibault le Meur (tlemeur)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Port the LimeSurvey back-end (administration) to CodeIgniter==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is still written using old procedural code. We want to take the next step into the future and use a MVC-framework name CodeIgniter and port the whole application to this new framework. However porting the whole application is too much for one student. That is why we will split the task into smaller ones. This particular task deals with porting the backend of LimeSurvey to CodeIgniter - this means all the parts that can be seen by an administration user.&lt;br /&gt;
&lt;br /&gt;
During the rewrite you will be prompted also to encapsulate certain functions to objects where easily doable and it makes sense - we do not want you to rewrite everything. Since you are only working on a certain part of LimeSurvey and another student will port the front-end (=administration) of LimeSurvey you will be required to coordinate your coding with the other student.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
OOP experience in PHP and experience with a PHP framework like CakePHP or CodeIgniter are definately a must. You should get busy with LimeSurvey as early as possible. Students can raise their chance to get accepted by showing off according knowledge about LimeSurvey inner workings.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you are a very good PHP coder (and fit the demanded skills above) then the main difficulty in this task is the sheer size of it. The administration consists of a great number of different screens and functions which need to be ported. If you don&#039;t manage to port all of it then at least the unported parts still have to be working - still best would be if you manage to do the whole administration.&lt;br /&gt;
&lt;br /&gt;
Also the difficulty in this task is to gradually modernize an application with a modern coding approach while resisting the natural urge to rewrite everything at once. Our mantra to modernizing the application is that the framework is just laying the new foundation while the fancy walls can be built later. So we lay the foundation first and make it stable (your task in the administration), then we build new walls (See also [[LimeSurvey roadmap|the LimeSurvey roadmap]] )&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
Thibault le Meur (tlemeur)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Implement a modular authentication framework==&lt;br /&gt;
&lt;br /&gt;
The idea is to design and implement a modular authentication &amp;quot;framework&amp;quot; for LimeSurvey as well as some authentication modules. The Authentication framework will define the API each authentication plugin must (or may) implement and propose basic methods that can be used by plugins (for instance how to store the plugins parameters in DB, how to display a form using the survey template). A plugin will be responsible to implement, for each particular authentication backend, specific methods (some mandatory, some optionnal) such as: user authentication, user provisionning, user rights, ...&lt;br /&gt;
&lt;br /&gt;
Currently authentication is only used for the survey-administration GUI and not the participants interface (tokens are used for this). With the new authentication framework it will be possible to define several authentication backends and use some of them for participants-authentication.&lt;br /&gt;
&lt;br /&gt;
The generic authentication framework must define the following services:&lt;br /&gt;
* User authentication: this interface must return the identity of the authenticated user if authentication is successful.&lt;br /&gt;
** Authentication may not always be based on a simple user/password form, so the proposed framework must be generic enough to enable authentication based on other schemes (using any numbers or interaction-pages between the server and the end-user or any other contextual parameter such as Referrer, session variable...&lt;br /&gt;
* User provisionning:&lt;br /&gt;
** when activated on the survey administration interface, an authentication module might be able to create a newly authenticated user into the LimeSurvey internal DB (which is required for setting the user rights on the platform). The newly created user can be assigned a default profile or a per-user profile (queried from an external database).&lt;br /&gt;
** when activated on the participants interface, the authentication module will provision the token table of the correspoding survey // alternatively the general-purpose cross-survey participants-database as described in the above GSoC idea.&lt;br /&gt;
&lt;br /&gt;
The already existing authentication schemes will be ported to the new framework (internal-DB and Web server authentication delegation) and at least a new one will be implemented (openID, CAS, Shibboleth).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, CodeIgniter, Authentication protocols (openID, CAS, LDAP-bind, ...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
lemeur (Thibault Le Meur)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Want to know more&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please read the [http://docs.limesurvey.org/tiki-index.php?page=GSOC+2010++Authentication+framework#FAQ FAQ about this project]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Rewrite and extend the conditions in LimeSurvey==&lt;br /&gt;
&lt;br /&gt;
[[File:addNewCondition1.png]]&lt;br /&gt;
&lt;br /&gt;
Rewrite the conditions engine that will let survey administrators design, store and evaluate conditions. Conditions must be implemented in such a way that they can be used in several features such as question branching (survey logic), assessments, quotas, ...&lt;br /&gt;
&lt;br /&gt;
This projects will at least end up with:&lt;br /&gt;
* A working GUI to design complex conditions:&lt;br /&gt;
** several atomic conditions can be combined by AND or OR logical operators and will support for grouping conditions with parentheses&lt;br /&gt;
** an atomic condition representation can be&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;left operand&amp;gt; &amp;lt;operator&amp;gt; &amp;lt;right operand&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** an atomic condition editor will implement&lt;br /&gt;
*** several operators (equality, inequality, string-comparisons, numerical-comparisons, regexp),...&lt;br /&gt;
*** meta operators surch as &#039;Not displayed&#039;&lt;br /&gt;
** left and right operands can be answers from previous questions, or a static values. It should be extensible so that we are able in the future to use more complex operand such as the result of a specific function (for instance the sum of some previous integer questions)&lt;br /&gt;
* A working DB storage backend using a string in [http://en.wikipedia.org/wiki/Reverse_Polish_Notation RPN] (Reverse Polish Notation) to describe each condition&lt;br /&gt;
* The evaluation of conditions for the question branching feature.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CodeIgniter, JQuery and User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thibault Le Meur (lemeur)&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Want to know more&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Discussion about the [http://docs.limesurvey.org/tiki-index.php?page=GSOC+2010+Condition+engine LS2 conditions engine] is an interresting start. Note however that the task will be easier this year because of the existing conditions engine and the stable database layout of LS1.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Custom Report Generation==&lt;br /&gt;
&lt;br /&gt;
The task is to make a module which will generate custom reports. Module should be able to do these things(at least) :-&lt;br /&gt;
*Creating various types of reports i.e. using tables, pie charts, graphs and bar-charts to name few.&lt;br /&gt;
*The resulting charts and other illustrations should be easy to read and understand, and should include the ability to export into standard office suites.&lt;br /&gt;
*Reports can be general or survey specific.&lt;br /&gt;
**General in the sense that it should show basic findings of a general survey graphically like number of users completing the survey, average time taken to complete the survey, average number of correct responses etc.&lt;br /&gt;
**Survey specific results should also be addressed properly e.g. how many users choose first option as there answer of a particular question, how many users didn&#039;t answer a specific question etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
OOP experience in PHP and experience with a PHP framework like CakePHP or CodeIgniter, jQuery. Strong mathematical background will help!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Adding new questions/subquestions and groups dynamically==&lt;br /&gt;
&lt;br /&gt;
Currently in LimeSurvey once a survey is activate we can not&lt;br /&gt;
*Add or delete groups&lt;br /&gt;
*Add or delete questions&lt;br /&gt;
*Add or delete subquestions or change their codes&lt;br /&gt;
&lt;br /&gt;
The idea is to cover these shortcomings. And in addition, all those participants who have already taken that survey must also be notified about the changes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Experience with a PHP framework like CakePHP or CodeIgniter and knowledge of inner working of LimeSurvey is must!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Extend the use of assessments==&lt;br /&gt;
&lt;br /&gt;
[http://docs.limesurvey.org/Assessments&amp;amp;structure;=English+Instructions+for+LimeSurvey Assessments] are used a lot at Limesurvey but currently this feature only covers very basic needs. Users have asked for some additional assessment features, unfortunately most of them can&#039;t be implemented until we start saving assessment results at the database instead of calculating assessment scores at runtime.&lt;br /&gt;
&lt;br /&gt;
So the first step is to extend the database layout of Limesurvey and add a new table for storing assessment results. Once this is done advanced features can be implemented such as:&lt;br /&gt;
* Export assessment results when exporting survey data&lt;br /&gt;
* Include assessment results at confirmation emails&lt;br /&gt;
* Extend statistics to include information about assessment results such as max score, min score, mean score, standard deviation, ...&lt;br /&gt;
* Connect [http://docs.limesurvey.org/Quotas&amp;amp;structure;=English+Instructions+for+LimeSurvey quotas] and assessments so that assessment results can be used to screen users at the beginning of a survey.&lt;br /&gt;
* Enable assessment scores at [http://docs.limesurvey.org/Setting+conditions&amp;amp;structure;=English+Instructions+for+LimeSurvey conditions] so that a condition like &amp;quot;&#039;&#039;Show question X if &amp;lt;assessment_score1&amp;gt; &amp;gt; 10&#039;&#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, MySQL, CodeIgniter, JQuery and some basic User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Carsten Schmitz (c_schmitz)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;NEW&#039;&#039;&#039; Rebuild the database frontend using CodeIgniter==&lt;br /&gt;
&lt;br /&gt;
During last years GSoC, a database frontend was developed using CakePHP. Limesurvey has since decided to switch to the CodeIgniter framework. As such, last years work needs to be ported to CodeIgniter.&lt;br /&gt;
&lt;br /&gt;
All documentation from last year is available at [[Database Storage Engine Project|here]] aswell as the source of the developed CakePHP modules which can be found [https://limesurvey.svn.sourceforge.net/svnroot/limesurvey/source/limesurvey20/limesurvey-dev/app/plugins/ here] - the plugins market with dbse.&lt;br /&gt;
&lt;br /&gt;
The final project has to comply with the API developed last year, changes have to be discussed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, Object oriented programming &amp;amp; design patterns, CodeIgniter, CakePHP&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium, Main challenges will be database abstraction and automatic generation of sql code out of survey structures.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Maarten Tielemans (ttielu)&lt;br /&gt;
&lt;br /&gt;
Pieter-Jan Speelmans (MrP001)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Idea template==&lt;br /&gt;
&lt;br /&gt;
Describe the idea here in general terms&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain what sort of coding skills would be needed for a student to implement this project&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain the level of difficulty involved&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Put your name (and tag) here if you are willing to mentor a student for this idea&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=More information=&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
[[GSoC getting started|Check out our &#039;Get started&#039; page]] for setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
==Frequently Asked Questions==&lt;br /&gt;
&lt;br /&gt;
Check out [[GSoC FAQ|our GSoC FAQ page.]]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_roadmap&amp;diff=2097</id>
		<title>LimeSurvey roadmap</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_roadmap&amp;diff=2097"/>
		<updated>2011-02-09T10:06:54Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Contents:__TOC__&lt;br /&gt;
&lt;br /&gt;
=Background=&lt;br /&gt;
&lt;br /&gt;
Two years ago the development of completely new version of LimeSurvey, namely LimeSurvey 2 (short:LS2) was started. LS2 was developed in chunks during the last two years but until this day it remains far behind the current version of LimeSurvey 1.x. This has several reasons:&lt;br /&gt;
*CakePHP as PHP framework proved not dynamic enough. While CakePHP can be made to do all the things we required of it, the effort involved in achieving these things was far greater than we had expected or desired. This became more obvious as work progressed and things became more complicated to code and install. Optimisations also take a lot of effort. In general CakePHP was way slower than the current LimeSurvey 1.&lt;br /&gt;
*Except for specific, one-off directed efforts like Google Summer of Code the development stalled because we had no persistent LS2 contributors in the team&lt;br /&gt;
*The current LS1 development team is all focused on LimeSurvey 1 which is used by several thousand users and so the feedback of the community and any support is focused on LimeSurvey 1. CakePHP has a steep learning curve and currently none of the existing LS1 developers is able to put their mind to it. There is little likelihood that this will change in the future.&lt;br /&gt;
*Even if we put lots of development resources into LS2 right now it would still take another year until at least basic functionality in all common areas will be achieved - and even that will only represent a small fraction of the current LS1 feature set.&lt;br /&gt;
&lt;br /&gt;
=What now?=&lt;br /&gt;
&lt;br /&gt;
Considering the history of development activity for LimeSurvey 2 and the underlying problems of its development, the development team has decided that the future of LimeSurvey will take a new turn. This new way will circumvent most of the problems above by taking a slow and evolving approach. The following basic steps will be taken:&lt;br /&gt;
*Instead of trying to rewrite such a huge application from scratch we will slowly rewrite LimeSurvey 1. That way we will still have full community and developers support - LimeSurvey 1 will keep evolving and even during the rewrite phase we will be able to have new releases&lt;br /&gt;
*Instead of CakePHP we will use the CodeIgniter PHP framwork. CodeIgniter has been proved to be very stable, fast, flexible, actively developed and in many things it is very close to existing libraries already used in LimeSurvey 1 (like AdoDB). That minimizes the learning curve for existing LS1 developers and we can still run the old and new architecture side by side in the same application.&lt;br /&gt;
*Concepts that have been elaborated for LS2 aren&#039;t automatically obsolete - on the contrary they can be implemented while LimeSurvey is evolving.&lt;br /&gt;
*Last but not least: Baby steps - we will get to our goals eventually but if we go slow we won&#039;t stumble.&lt;br /&gt;
&lt;br /&gt;
This new develpment approach will allow us to reach our goal of a modular application which separates content from logic accoroding to MVC standards.&lt;br /&gt;
&lt;br /&gt;
=Timeline=&lt;br /&gt;
&lt;br /&gt;
We are currently working out a detailed timeline. Please bear with us - however the first step is pretty clear:&lt;br /&gt;
*Summer 2011: Google Summer of Code students will be working on rewriting big parts of the LimeSurvey 1 code to CodeIgniter, starting with the front-end (survey taking) and parts of the administration. Detailed steps can be found in the worked out GSOC tasks, once these are prepared.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_roadmap&amp;diff=2098</id>
		<title>LimeSurvey roadmap</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_roadmap&amp;diff=2098"/>
		<updated>2011-02-09T10:02:40Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Contents:__TOC__&lt;br /&gt;
&lt;br /&gt;
=Background=&lt;br /&gt;
&lt;br /&gt;
Two years ago the development of completely new version of LimeSurvey, namely LimeSurvey 2 (short:LS2) was started. LS2 was developed in chunks during the last two years but until this day it remains far behind the current version of LimeSurvey 1.x. This has several reasons:&lt;br /&gt;
*CakePHP as PHP framework proved to be not dynamic enough. While CakePHP can made to do all the things we required of it, the effort involved in achieving these things was far greater than we had expected or desired. This became more obvious as work progressed and things became more complicated to code and install. Optimisations also take a lot of effort. In general CakePHP was way slower than the current LimeSurvey 1.&lt;br /&gt;
*Except for specific, one-off directed efforts like Google Summer of Code the development stalled because we had no persistent LS2 contributors in the team&lt;br /&gt;
*The current LS1 development team is all focused on LimeSurvey 1 which is used by several thousand users and so the feedback of the community and any support is focused on LimeSurvey 1. CakePHP has a steep learning curve and currently none of the existing LS1 developers is able to put their mind to it. There is little likelihood that this will change in the future.&lt;br /&gt;
*Even if we put lots of development resources into LS2 right now it would still take another year until at least basic functionality in all common areas will be achieved - and even that will only represent a small fraction of the current LS1 feature set.&lt;br /&gt;
&lt;br /&gt;
=What now?=&lt;br /&gt;
&lt;br /&gt;
Considered the type of past development activities on LimeSurvey 2 and the underlying problems with the non-existent development resources it was agreed in the development team that the future of LimeSurvey will take a new turn. This new way will circumvent most of the problems above by taking a slow and evolving approach. The following basic steps will be taken:&lt;br /&gt;
*Instead of trying to rewrite such a huge application from scratch we will slowly rewrite LimeSurvey 1. That way we will still have full community and developers support - LimeSurvey 1 will keep evolving and even during the rewrite phase we will be able to have new releases&lt;br /&gt;
*Instead of CakePHP we will use the CodeIgniter PHP framwork. CodeIgniter has been proved to be very stable, fast, flexible, actively developed and in many things it is very close to existing libraries already used in LimeSurvey 1 (like AdoDB). That minimizes the learning curve for existing LS1 developers and we can still run the old and new architecture side by side in the same application.&lt;br /&gt;
*Concepts that have been elaborated for LS2 aren&#039;t automatically obsolete - on the contrary they can be implemented while LimeSurvey is evolving.&lt;br /&gt;
*Last but not least: Baby steps - we will get to our goals eventually but if we go slow we won&#039;t stumble.&lt;br /&gt;
&lt;br /&gt;
This new develpment approach will allow us to reach our goal of a modular application which separates content from logic accoroding to MVC standards.&lt;br /&gt;
&lt;br /&gt;
=Timeline=&lt;br /&gt;
&lt;br /&gt;
We are currently working out a detailed timeline. Please bear with us - however the first step is pretty clear:&lt;br /&gt;
*Summer 2011: Google Summer of Code students will be working on rewriting big parts of the LimeSurvey 1 code to CodeIgniter, starting with the front-end (survey taking) and parts of the administration. Detailed steps can be found in the worked out GSOC tasks, once these are prepared.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2000</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2000"/>
		<updated>2010-05-21T10:44:58Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey project has been accepted for the Google Summer of Code 2010!&lt;br /&gt;
&lt;br /&gt;
=Our Projects for 2010=&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=Database+Storage+Engine+Project LimeSurvey 2 Database Storage Engine]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=File+Upload+Question+Type LimeSurvey 1 File Upload Question Type]&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
The timelineline can be found [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#timeline here].&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is loved and used by many universities, students, medical institutes, non-profit organizations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provides LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been directly downloaded from Sourceforge over &#039;&#039;&#039;130,000 times&#039;&#039;&#039; in the last 12 months alone, and is also distributed as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, and included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognized as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;. LimeSurvey was successful in being selected as a mentoring organization for the Google Summer of Code in 2009.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source on-line survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionize on-line survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2010, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;File upload question type in LimeSurvey 1&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Marcel Minke&amp;lt;/center&amp;gt; &amp;lt;center&amp;gt;[http://docs.limesurvey.org/tiki-index.php?page=UserPage Mazi||Mazi]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Template editor?&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Mac Duy Hai&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;[[UserPage macduy||macduy]]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine, Mini-projects&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Thibault Le Meur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;lemeur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Student Applications===&lt;br /&gt;
* [GSoC_Student_Application_Template|GSoC Student Application Template]&lt;br /&gt;
* Advice and General Information:&lt;br /&gt;
&lt;br /&gt;
- [http://geekfeminism.org/2010/03/25/showing-your-awesomeness-for-google-summer-of-code/ Showing Your Awesomeness for GSoC]&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2001</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2001"/>
		<updated>2010-05-21T10:43:50Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey project has been accepted for the Google Summer of Code 2010!&lt;br /&gt;
&lt;br /&gt;
=Our Projects for 2010=&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=Database+Storage+Engine+Project LimeSurvey 2 Database Storage Engine]&lt;br /&gt;
* LimeSurvey 1 File Upload Question Type&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
The timelineline can be found [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#timeline here].&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is loved and used by many universities, students, medical institutes, non-profit organizations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provides LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been directly downloaded from Sourceforge over &#039;&#039;&#039;130,000 times&#039;&#039;&#039; in the last 12 months alone, and is also distributed as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, and included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognized as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;. LimeSurvey was successful in being selected as a mentoring organization for the Google Summer of Code in 2009.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source on-line survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionize on-line survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2010, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;File upload question type in LimeSurvey 1&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Marcel Minke&amp;lt;/center&amp;gt; &amp;lt;center&amp;gt;[http://docs.limesurvey.org/tiki-index.php?page=UserPage Mazi||Mazi]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Template editor?&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Mac Duy Hai&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;[[UserPage macduy||macduy]]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine, Mini-projects&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Thibault Le Meur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;lemeur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Student Applications===&lt;br /&gt;
* [GSoC_Student_Application_Template|GSoC Student Application Template]&lt;br /&gt;
* Advice and General Information:&lt;br /&gt;
&lt;br /&gt;
- [http://geekfeminism.org/2010/03/25/showing-your-awesomeness-for-google-summer-of-code/ Showing Your Awesomeness for GSoC]&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2002</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2002"/>
		<updated>2010-05-21T10:42:47Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey project has been accepted for the Google Summer of Code 2010!&lt;br /&gt;
&lt;br /&gt;
=Our Projects for 2010=&lt;br /&gt;
* LimeSurvey 2 Database Storage Engine&lt;br /&gt;
* LimeSurvey 1 File Upload Question Type&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
The timelineline can be found [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#timeline here].&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is loved and used by many universities, students, medical institutes, non-profit organizations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provides LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been directly downloaded from Sourceforge over &#039;&#039;&#039;130,000 times&#039;&#039;&#039; in the last 12 months alone, and is also distributed as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, and included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognized as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;. LimeSurvey was successful in being selected as a mentoring organization for the Google Summer of Code in 2009.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source on-line survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionize on-line survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2010, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;File upload question type in LimeSurvey 1&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Marcel Minke&amp;lt;/center&amp;gt; &amp;lt;center&amp;gt;[http://docs.limesurvey.org/tiki-index.php?page=UserPage Mazi||Mazi]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Template editor?&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Mac Duy Hai&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;[[UserPage macduy||macduy]]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine, Mini-projects&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Thibault Le Meur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;lemeur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Student Applications===&lt;br /&gt;
* [GSoC_Student_Application_Template|GSoC Student Application Template]&lt;br /&gt;
* Advice and General Information:&lt;br /&gt;
&lt;br /&gt;
- [http://geekfeminism.org/2010/03/25/showing-your-awesomeness-for-google-summer-of-code/ Showing Your Awesomeness for GSoC]&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2003</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2003"/>
		<updated>2010-03-27T00:08:23Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey project has been accepted for the Google Summer of Code 2010!&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
The timelineline can be found [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#timeline here].&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is loved and used by many universities, students, medical institutes, non-profit organizations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provides LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been directly downloaded from Sourceforge over &#039;&#039;&#039;130,000 times&#039;&#039;&#039; in the last 12 months alone, and is also distributed as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, and included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognized as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;. LimeSurvey was successful in being selected as a mentoring organization for the Google Summer of Code in 2009.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source on-line survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionize on-line survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2010, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;File upload question type in LimeSurvey 1&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Marcel Minke&amp;lt;/center&amp;gt; &amp;lt;center&amp;gt;[http://docs.limesurvey.org/tiki-index.php?page=UserPage Mazi||Mazi]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Template editor?&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Mac Duy Hai&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;[[UserPage macduy||macduy]]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine, Mini-projects&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Thibault Le Meur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;lemeur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Student Applications===&lt;br /&gt;
* [GSoC_Student_Application_Template|GSoC Student Application Template]&lt;br /&gt;
* Advice and General Information:&lt;br /&gt;
&lt;br /&gt;
- [http://geekfeminism.org/2010/03/25/showing-your-awesomeness-for-google-summer-of-code/ Showing Your Awesomeness for GSoC]&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=GSoC_Student_Application_Template&amp;diff=1439</id>
		<title>GSoC Student Application Template</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=GSoC_Student_Application_Template&amp;diff=1439"/>
		<updated>2010-03-26T04:54:16Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&#039;&#039;&#039;When you make your student application for LimeSurvey on the Google Website you will be asked to provide the following information.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We have reprinted it here so you can start organising yourself early - but you do not submit the application to us, it is submitted to google.&lt;br /&gt;
&lt;br /&gt;
Note that we will be thrilled if you can provide additional information about your project (ie: screenshots, designs etc.) on a seperate webpage (of your own, we won&#039;t host it for you).&lt;br /&gt;
&lt;br /&gt;
Be as detailed as you possibly can with your &amp;quot;project proposal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Template==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1: Please complete the following information:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(if you can&#039;t answer any, enter &#039;none&#039;)&lt;br /&gt;
&lt;br /&gt;
Your Name:&lt;br /&gt;
&lt;br /&gt;
Your Email:&lt;br /&gt;
&lt;br /&gt;
Your IRC Nick:&lt;br /&gt;
&lt;br /&gt;
Your IM and user id (): ie: Skype, jasebo (Skype is preferred)&lt;br /&gt;
&lt;br /&gt;
Your location and timezone:    ie: Melbourne Australia, GMT+10&lt;br /&gt;
&lt;br /&gt;
Your school/educational institution and course:    ie: Monash University, Computer Science&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2: Please outline your project proposal with as much detail as possible&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- We expect this to be lengthy and descriptive. Short summaries will not be sufficient for us to select your project.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3: How will LimeSurvey benefit from your proposal?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4: Please list specific milestones and deliverables for your proposal:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Milestones and deliverables are points or stages during the project that can be used to check that appropriate progress is being made. A milestone may be a point where certain functionality is available. Milestones or deliverables have to be measurable and explicit, so there has to be something you can show to indicate that a milestone or deliverable has been attained.&lt;br /&gt;
&lt;br /&gt;
- There must be mid-term milestones and milestones for the end of the project&lt;br /&gt;
&lt;br /&gt;
- If your proposal is successful, we will pursue milestones and deliverables in greater with you, but we need an indication initially of what milestones you believe can be reached.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;5: What Open Source Development Experience do you have?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please let us know of any experience you have with Open Source projects, whether that is with large coding projects, small projects, bug reports or tiny bug fixes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;6: What other coding, work or related experience do you have?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Let us know of any other experience or skills you have that are related to our project, your proposal and your capacity to achieve the goals you&#039;ve set out.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;7: Academic Experience:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please detail what you are studying at your higher education institution that is relevant to our project and your proposal. Let us know you&#039;re going with it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8: Why have you chosen LimeSurvey?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Let us know why you chose to apply for GSoC with LimeSurvey.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=GSoC_Student_Application_Template&amp;diff=1440</id>
		<title>GSoC Student Application Template</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=GSoC_Student_Application_Template&amp;diff=1440"/>
		<updated>2010-03-26T01:03:50Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&#039;&#039;&#039;When you make your student application for LimeSurvey on the Google Website you will be asked to provide the following information.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We have reprinted it here so you can start organising yourself early - but you do not submit the application to us, it is submitted to google.&lt;br /&gt;
&lt;br /&gt;
Note that we will be thrilled if you can provide additional information about your project (ie: screenshots, designs etc.) on a seperate webpage.&lt;br /&gt;
&lt;br /&gt;
Be as detailed as you possibly can with your &amp;quot;project proposal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1: Please complete the following information:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(if you can&#039;t answer any, enter &#039;none&#039;)&lt;br /&gt;
&lt;br /&gt;
Your Name:&lt;br /&gt;
&lt;br /&gt;
Your Email:&lt;br /&gt;
&lt;br /&gt;
Your IRC Nick:&lt;br /&gt;
&lt;br /&gt;
Your IM and user id (): ie: Skype, jasebo (Skype is preferred)&lt;br /&gt;
&lt;br /&gt;
Your location and timezone:    ie: Melbourne Australia, GMT+10&lt;br /&gt;
&lt;br /&gt;
Your school/educational institution and course:    ie: Monash University, Computer Science&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2: Please outline your project proposal with as much detail as possible&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- We expect this to be lengthy and descriptive. Short summaries will not be sufficient for us to select your project.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3: How will LimeSurvey benefit from your proposal?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4: Please list specific milestones and deliverables for your proposal:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Milestones and deliverables are points or stages during the project that can be used to check that appropriate progress is being made. A milestone may be a point where certain functionality is available. Milestones or deliverables have to be measurable and explicit, so there has to be something you can show to indicate that a milestone or deliverable has been attained.&lt;br /&gt;
&lt;br /&gt;
- There must be mid-term milestones and milestones for the end of the project&lt;br /&gt;
&lt;br /&gt;
- If your proposal is successful, we will pursue milestones and deliverables in greater with you, but we need an indication initially of what milestones you believe can be reached.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;5: What Open Source Development Experience do you have?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please let us know of any experience you have with Open Source projects, whether that is with large coding projects, small projects, bug reports or tiny bug fixes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;6: What other coding, work or related experience do you have?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Let us know of any other experience or skills you have that are related to our project, your proposal and your capacity to achieve the goals you&#039;ve set out.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;7: Academic Experience:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please detail what you are studying at your higher education institution that is relevant to our project and your proposal. Let us know you&#039;re going with it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8: Why have you chosen LimeSurvey?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Let us know why you chose to apply for GSoC with LimeSurvey.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=GSoC_Student_Application_Template&amp;diff=1441</id>
		<title>GSoC Student Application Template</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=GSoC_Student_Application_Template&amp;diff=1441"/>
		<updated>2010-03-26T01:00:57Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&#039;&#039;&#039;When you make your student application for LimeSurvey on the Google Website you will be asked to provide the following information.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We have reprinted it here so you can start organising yourself early - but you do not submit the application to us, it is submitted to google.&lt;br /&gt;
&lt;br /&gt;
Note that we will be thrilled if you can provide additional information about your project (ie: screenshots, designs etc. on a seperate webpage).&lt;br /&gt;
&lt;br /&gt;
Be as detailed as you possibly can with your &amp;quot;project proposal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1: Please complete the following information:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(if you can&#039;t answer any, enter &#039;none&#039;)&lt;br /&gt;
&lt;br /&gt;
Your Name:&lt;br /&gt;
&lt;br /&gt;
Your Email:&lt;br /&gt;
&lt;br /&gt;
Your IRC Nick:&lt;br /&gt;
&lt;br /&gt;
Your IM and user id (): ie: Skype, jasebo (Skype is preferred)&lt;br /&gt;
&lt;br /&gt;
Your location and timezone:    ie: Melbourne Australia, GMT+10&lt;br /&gt;
&lt;br /&gt;
Your school/educational institution and course:    ie: Monash University, Computer Science&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2: Please outline your project proposal with as much detail as possible&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- We expect this to be lengthy and descriptive. Short summaries will not be sufficient for us to select your project.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3: How will LimeSurvey benefit from your proposal?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4: Please list specific milestones and deliverables for your proposal:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Milestones and deliverables are points or stages during the project that can be used to check that appropriate progress is being made. A milestone may be a point where certain functionality is available. Milestones or deliverables have to be measurable and explicit, so there has to be something you can show to indicate that a milestone or deliverable has been attained.&lt;br /&gt;
&lt;br /&gt;
- There must be mid-term milestones and milestones for the end of the project&lt;br /&gt;
&lt;br /&gt;
- If your proposal is successful, we will pursue milestones and deliverables in greater with you, but we need an indication initially of what milestones you believe can be reached.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;5: What Open Source Development Experience do you have?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please let us know of any experience you have with Open Source projects, whether that is with large coding projects, small projects, bug reports or tiny bug fixes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;6: What other coding, work or related experience do you have?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Let us know of any other experience or skills you have that are related to our project, your proposal and your capacity to achieve the goals you&#039;ve set out.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;7: Academic Experience:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please detail what you are studying at your higher education institution that is relevant to our project and your proposal. Let us know you&#039;re going with it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8: Why have you chosen LimeSurvey?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Let us know why you chose to apply for GSoC with LimeSurvey.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=GSoC_Student_Application_Template&amp;diff=1442</id>
		<title>GSoC Student Application Template</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=GSoC_Student_Application_Template&amp;diff=1442"/>
		<updated>2010-03-26T00:57:30Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&#039;&#039;&#039;1: Please complete the following information:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(if you can&#039;t answer any, enter &#039;none&#039;)&lt;br /&gt;
&lt;br /&gt;
Your Name:&lt;br /&gt;
&lt;br /&gt;
Your Email:&lt;br /&gt;
&lt;br /&gt;
Your IRC Nick:&lt;br /&gt;
&lt;br /&gt;
Your IM and user id (): ie: Skype, jasebo (Skype is preferred)&lt;br /&gt;
&lt;br /&gt;
Your location and timezone:    ie: Melbourne Australia, GMT+10&lt;br /&gt;
&lt;br /&gt;
Your school/educational institution and course:    ie: Monash University, Computer Science&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2: Please outline your project proposal with as much detail as possible&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- We expect this to be lengthy and descriptive. Short summaries will not be sufficient for us to select your project.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3: How will LimeSurvey benefit from your proposal?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4: Please list specific milestones and deliverables for your proposal:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Milestones and deliverables are points or stages during the project that can be used to check that appropriate progress is being made. A milestone may be a point where certain functionality is available. Milestones or deliverables have to be measurable and explicit, so there has to be something you can show to indicate that a milestone or deliverable has been attained.&lt;br /&gt;
&lt;br /&gt;
- There must be mid-term milestones and milestones for the end of the project&lt;br /&gt;
&lt;br /&gt;
- If your proposal is successful, we will pursue milestones and deliverables in greater with you, but we need an indication initially of what milestones you believe can be reached.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;5: What Open Source Development Experience do you have?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please let us know of any experience you have with Open Source projects, whether that is with large coding projects, small projects, bug reports or tiny bug fixes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;6: What other coding, work or related experience do you have?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Let us know of any other experience or skills you have that are related to our project, your proposal and your capacity to achieve the goals you&#039;ve set out.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;7: Academic Experience:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please detail what you are studying at your higher education institution that is relevant to our project and your proposal. Let us know you&#039;re going with it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8: Why have you chosen LimeSurvey?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Let us know why you chose to apply for GSoC with LimeSurvey.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2004</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2004"/>
		<updated>2010-03-26T00:54:50Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey project has been accepted for the Google Summer of Code 2010!&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
The timelineline can be found [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#timeline here].&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is loved and used by many universities, students, medical institutes, non-profit organizations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provides LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been directly downloaded from Sourceforge over &#039;&#039;&#039;130,000 times&#039;&#039;&#039; in the last 12 months alone, and is also distributed as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, and included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognized as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;. LimeSurvey was successful in being selected as a mentoring organization for the Google Summer of Code in 2009.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source on-line survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionize on-line survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2010, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;File upload question type in LimeSurvey 1&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Marcel Minke&amp;lt;/center&amp;gt; &amp;lt;center&amp;gt;[http://docs.limesurvey.org/tiki-index.php?page=UserPage Mazi||Mazi]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Template editor?&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Mac Duy Hai&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;[[UserPage macduy||macduy]]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine, Mini-projects&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Thibault Le Meur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;lemeur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;br /&gt;
&lt;br /&gt;
===Student Application Template===&lt;br /&gt;
* [GSoC_Student_Application_Template|GSoC Student Application Template]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2010&amp;diff=2480</id>
		<title>Project ideas for GSOC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2010&amp;diff=2480"/>
		<updated>2010-03-20T15:15:58Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Welcome=&lt;br /&gt;
&lt;br /&gt;
Welcome Google Summer of Code Student aspirants (:razz:)!! Please check if you are an [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#student_eligibility eligible candidate] for the GSoC program.&lt;br /&gt;
&lt;br /&gt;
This page lists project ideas developed by the LimeSurvey Community. These tend to be areas that will get the most support as projects since they have been developed by people who know the project and what it needs the most. &#039;&#039;&#039;However&#039;&#039;&#039;, if you have your own idea for a project discuss your awesome idea with us in our [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/catid,11/id,24710/lang,en/ forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing list] or at #limesurvey on irc.freenode.net. Then submit &#039;&#039;&#039;your&#039;&#039;&#039; proposal. Good Luck (:biggrin:)&lt;br /&gt;
&lt;br /&gt;
=Project ideas=&lt;br /&gt;
&lt;br /&gt;
==Example Format...==&lt;br /&gt;
&lt;br /&gt;
Describe the idea here in general terms&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain what sort of coding skills would be needed for a student to implement this project&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain the level of difficulty involved&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Put your name (and tag) here if you are willing to mentor a student for this idea&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: File Upload question type==&lt;br /&gt;
&lt;br /&gt;
The idea is to have a question type in LimeSurvey1 where survey participants can upload one (or more) files. Often in surveys the participant is asked to create some content (pictures, movies, documents, etc.)  to upload as an answer to a question. The following goals are  primary in this task:&lt;br /&gt;
*Easy handling for the participant (uploading one or more files should be a piece of cake - also removing files if accidentally the wrong file was uploaded)&lt;br /&gt;
*Extensive configuration options for the question type like&lt;br /&gt;
**How many files are required, minimum and maxim number of files,&lt;br /&gt;
**maximum/minimum upload size,&lt;br /&gt;
**Allowed file types&lt;br /&gt;
*Safe!! storage in the file system, checks for file contents&lt;br /&gt;
*Implementation in statistics / data entry / printable survey / response browsing / response editing &amp;amp; RemoteControl&lt;br /&gt;
*Administrator can download one or more files (zip-packaging files for download) from one response and across responses&lt;br /&gt;
*Provide possible hooks for third party processing tools&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, jQuery, AJAX - existing knowledge on the general idea and related security would be of big advantage&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
c_schmitz (Carsten Schmitz)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: Authentication framework==&lt;br /&gt;
&lt;br /&gt;
The idea is to design and implement a generic authentication framework for LimeSurvey 1 as well as some authentication modules. The Authentication framework will make it possible to implement any kind of authentication backend apart from the already existing internal-DB and Web server delegation schemes. Currently authentication is only used for the survey-administration GUI and not the participants interface (tokens are used for this). With the new authentication framework it will be possible to define several authentication backends and use some of them for participants-authentication.&lt;br /&gt;
&lt;br /&gt;
The generic authentication framework must define the following services:&lt;br /&gt;
* User authentication: this interface must return the identity of the authenticated user if authentication is successful.&lt;br /&gt;
** Authentication may not always be based on a simple user/password form, so the proposed framework must be generic enough to enable authentication based on other schemes (using any numbers or GET/POST parameters or any other contextual parameter such as Referrer, session variable...&lt;br /&gt;
* User provisionning:&lt;br /&gt;
** when activated on the survey administration interface, an authentication module might be able to create a newly authenticated user into the LimeSurvey internal DB (which is required for setting the user rights on the platform). The newly created user can be assigned a default profile or a per-user profile (queried from an external database).&lt;br /&gt;
** when activated on the participants interface, the authentication module will provision the token table of the correspoding survey (only if the token for this user has not been already added).&lt;br /&gt;
&lt;br /&gt;
The already existing authentication schemes will be ported to the new framework (internal-DB and Web server authentication delegation) and at least a new one will be implemented (openID, CAS, Shibboleth).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, Authentication protocols (openID, CAS, LDAP-bind, ...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
lemeur (Thibault Le Meur)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Db Storage Engine==&lt;br /&gt;
&lt;br /&gt;
Develop an extensible plugin survey storage engine for LimeSurvey 2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other than survey design, everything that happens in LimeSurvey centres around the ability to save responses to questions to a database, and retrieve the responses again when required. Historically these functions have been incorporated within the various functions of LimeSurvey and this has locked LimeSurvey to a single methodology for data storage and retrieval and made future modifications and improvements difficult if not possible.&lt;br /&gt;
&lt;br /&gt;
For this project we are looking for students to write a &#039;middleware&#039; that exposes abstract high-level functions to LimeSurvey 2 (e.g.: storing these answers related to this question, running statistical analysis etc.) but is built in top of Cake&#039;s &#039;low-level&#039; operations (such as find, save etc). The aim is to abstract away from a specific DB implementation and provide an intuitive and rich API for LS2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Rationale&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the interface with the data storage system is so critical to practically every other function in LimeSurvey we want to develop a stand-alone module that is transportable and extensible for the future. And by keeping the logic of data and survey storage separate from the rest of LimeSurvey&amp;amp;rsquo;s functions we will the ease with which LimeSurvey can be developed in the long term.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Implementation&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is such an important project that we would consider multiple students undertaking the task. In conjunction with a strong understanding of data structures, php coding and api principles the students would also have to display a capacity to work in a team and with the broader community.&lt;br /&gt;
&lt;br /&gt;
The implementation would focus on becoming a plugin/addon module under CakePHP which uses the default CakePHP database systems to the absolute minimum. In a well implemented version of this proposal only simple SQL inserts, queries and updates would be required. All other logic would be managed by the engine.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Requirements &amp;amp; Considerations&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DB Engine must be able to do the following&lt;br /&gt;
* ease development of additional &#039;&#039;&#039;question types, which will be developed as plugins&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;efficient data retrieval&#039;&#039;&#039;, especially summaries (e.g. display 100 last responses)&lt;br /&gt;
* support &#039;&#039;&#039;generic&#039;&#039;&#039; data storage and retrieval - aside surveys, imagine running online admission tests, polls, sign-up forms, volunteer campaign etc. etc.&lt;br /&gt;
* easily support conditions, looped question, or generally, &#039;&#039;&#039;non-linear data&#039;&#039;&#039;. Think of a survey that asks how many children you have and then asks information about each of them.&lt;br /&gt;
* support questions that have multiple &#039;&#039;&#039;answers and multiple types of answers&#039;&#039;&#039;. Think of a question asking &amp;quot;What is your favourite ice cream?&amp;quot;, offering 3 fixed options and last one allowing user to enter a custom answer.&lt;br /&gt;
* support survey resuming (where applicable)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Field Naming and Database Extensibility Methodologies&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An ongoing debate in the LimeSurvey community has been the method in which the database stores survey results. In LimeSurvey 1 a flat database schema was used whereby once the survey designer had finished setting up the survey a database table was created with a field for every individual question/answer combination. The advantages of this database schema were speed of retrieval for reporting and exporting and searching. The disadvantages were that the survey system had to &amp;amp;lsquo;freeze&amp;amp;rsquo; the structure in place once the table was created (therefore the activate/de-activate rules in LimeSurvey 1). The single table method doesn&amp;amp;rsquo;t allow easy storage of metadata for individual question/answer combinations (such as timestamps). Nor does it lend itself to surveys with enormous quantities of question/answer combinations &amp;amp;ndash; sometimes running up against database limitations regarding the number of fields per table.&lt;br /&gt;
&lt;br /&gt;
An alternative is a &amp;amp;lsquo;normalised&amp;amp;rsquo; database topology where a single table is created to store all survey responses &amp;amp;ndash; one database row per question/answer combination. A related table would store metadata that is directly related to the survey sitting/session rather than the answer (e.g.: username, ip address, geographical location, user demographic). The advantage to this methodology is the increased flexibility (extensible) which would allow modification of surveys at any stage even after data has been collected (see requirements). The disadvantages are that searching and compilation of data is complicated and resource intensive.&lt;br /&gt;
&lt;br /&gt;
In a perfect world LimeSurvey would allow users to choose either methodology &amp;amp;ndash; either at an installation level or even on a per-survey level.&lt;br /&gt;
&lt;br /&gt;
Having a database storage engine effectively acting as an API would allow this functionality to be built, but the choice of database topology would be invisible to the related LimeSurvey functions that require data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Database Schema Design, Sound knowledge of Algorithms and Data Structures&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
jasebo (Jason Cleeland)&lt;br /&gt;
&lt;br /&gt;
macduy (Mac Duy Hai)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Template Editor==&lt;br /&gt;
&lt;br /&gt;
Limesurvey 2 needs a nice and powerful template editor so everyone can create a template which matches their requirements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
One needs to know about the details of the [http://dwoo.org/ dwoo template engine] which is used at LS2. There is some cakePHP coding needed to create an interface and write changes to the template files as well as some HTML/CSS to create a nice interface.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You don&#039;t have to create difficult algorithms for this task. It&#039;s useful if you have worked with templates for another web-application or take a detailled look at [http://docs.limesurvey.org/tiki-index.php?page=Themes%3A+Templates+and+Styles&amp;amp;structure;=English+Instructions+for+LimeSurvey how templates work in Limesurvey]. Some design/usability background would be nice but is not a must.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mazi&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Mini-projects==&lt;br /&gt;
&lt;br /&gt;
Mini-projects is a collection of small-to-medium sized projects, which you mix-and-match according to your tastes. Heck, you can even roll your own idea and once reviewed and approved, you can code away. Some recommended/important mini-projects and their brief descriptions:&lt;br /&gt;
*&#039;&#039;&#039;Smarter installer:&#039;&#039;&#039; LS2.0 comes with its own installer, though it may not be the friendliest to use. Your task is to make it juicier to use:&lt;br /&gt;
** Resume installation - if the user aborts the installation mid-way, make it easy for him to resume it&lt;br /&gt;
** Better error handling - meaningful error reports, suggestions how to fix them: e.g. &amp;quot;Database does not exist&amp;quot; is better than &amp;quot;Database error&amp;quot;&lt;br /&gt;
** Customization - invite the user to customize his installation of LimeSurvey - from security settings such as salt, to interface such as the header title.&lt;br /&gt;
*&#039;&#039;&#039;User management:&#039;&#039;&#039; When the number of users grow, it becomes increasingly harder to manage them. Implement functionality and provide interface for features that would make this task easier. Inspire yourself by the big players, such as the infamous you-know-which-one social website.&lt;br /&gt;
**&#039;&#039;&#039;Groups within groups:&#039;&#039;&#039; LS2 users can belong to a group, but groups cannot belong to other groups.&lt;br /&gt;
**&#039;&#039;&#039;Contact lists:&#039;&#039;&#039; There is already something called AssignmentGroups. Study this concept carefully and generalize to a Contact List&lt;br /&gt;
**&#039;&#039;&#039;GUI:&#039;&#039;&#039; Design a GUI which allows you easily manage users, groups and contact lists.&lt;br /&gt;
**&#039;&#039;&#039;Searching:&#039;&#039;&#039; Provide an efficient but simple-to-use search interface and functionality&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, JavaScript &amp;amp; jQuery&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mac Duy Hai (macduy)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Template/Theme Editor==&lt;br /&gt;
&lt;br /&gt;
The idea is to develop a theme / template framework similar to one in jquery [http://jqueryui.com/themeroller/ | Jquery Theme Roller] and thus making the UI design of the surveys easier.The current template editor is based on dwoo template engine which actually loads the files exposing the css etc for us to edit, which of course require some skill set to proceed. Using this template editor we can make everything UI based and thus requiring no developer skills to edit the templates.&lt;br /&gt;
&lt;br /&gt;
The overview of the modules can be seen here:&lt;br /&gt;
&lt;br /&gt;
[[File:theme_roller.png]]&lt;br /&gt;
&lt;br /&gt;
It&amp;amp;rsquo;ll be implemented using Jquery to use the more advanced UI experiences.(:biggrin:)&lt;br /&gt;
&lt;br /&gt;
The following mock-up will give us a better view:&lt;br /&gt;
&lt;br /&gt;
Moderate[[File:theme_editor_small.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, CSS, AJAX, JavaScript &amp;amp; jQuery.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Lime Survey Social - Facebook Application==&lt;br /&gt;
&lt;br /&gt;
The idea aims at developing a Facebook app which gives a social touch to LS 2.0. The application will be integrated in several Facebook integration points like News Feed, Applications boxes, Wall etc so that the user participation will be more. Adding a social touch can drive us more user participation and increase the popularity. The ability to control the Facebook app can be provided in the LS2.0 Admin Dashboard and also in the FB user application window with varied options.&lt;br /&gt;
&lt;br /&gt;
The facebook has the following modules (we can add more. This is primary draft.)&lt;br /&gt;
*All Survey related core features. (Create, Edit, Delete, Administer etc)&lt;br /&gt;
*Gain reward points.&lt;br /&gt;
*Use reward points to create more surveys.&lt;br /&gt;
*Spread the surveys ...... and more&lt;br /&gt;
&lt;br /&gt;
The idea can be extended to other social networks&lt;br /&gt;
&lt;br /&gt;
[[File:fb_overview.png]]&lt;br /&gt;
&lt;br /&gt;
The mock-ups :&lt;br /&gt;
&lt;br /&gt;
[[File:facebook app.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:canvas.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Facebook API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Integration of Poll Questions==&lt;br /&gt;
&lt;br /&gt;
Polls are one of the most popular and quick response getting tools once can use. Implementing polls in LS 2.0 will be an added advantage. Since every one of us know what polls are about, this idea focuses on the implementation part.&lt;br /&gt;
&lt;br /&gt;
The idea is to integrate the ability to create a POLL Module in Admin dashboard, where he can administer (Create | Edit | Delete | View Responses etc) the Polls.We can even get feedback &amp;amp;ldquo;about the survey&amp;amp;rdquo; at the end on how the user feels by creating a custom poll (we can even redirect the user to this poll).&lt;br /&gt;
*Chat Bots and Polls: An another idea is to create chat bots so that whenever we create a poll, all the friends (who added the bot) of that bot will be pinged by the question followed by options. Getting an answer is very easy (Bot friends just need to type a single letter stating the answer) and its a push model which ensures the delivery to everyone (even offline).We can even extend this to deliver certain type of surveys question by question through the bot.&lt;br /&gt;
&lt;br /&gt;
A simple mock-up for this:&lt;br /&gt;
&lt;br /&gt;
[[File:chat.png]]&lt;br /&gt;
*Alternate Solution: An alternate solution provided by Mazi is clubbing this idea with the Facebook app idea. Instead of porting parts of the admin backend to facebook or other social networks we&#039;ll have options in Admin panel to &amp;quot;publish as: common survey |mobile device survey | facebook poll | homepage poll |  ... etc &amp;quot; Everything will be put together at the usualm admin backend but you can choose which way(s) you want publish your survey.&lt;br /&gt;
&lt;br /&gt;
We can further extend this idea by giving additional options to publish as widgets for websites and blogs etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, XMPP Protocol (Knowledge of developing bots), Knowledge of Polls.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Survey Community Project==&lt;br /&gt;
&lt;br /&gt;
Build a system for LS2 that connects to a central repository of survey resources, such as demographic questions, answer styles and templates. Integrating with a login system, allow LimeSurvey users to easily publish their work to a community resource or use other published works from the same location.&lt;br /&gt;
&lt;br /&gt;
For many finding already written question texts, or standardised demographic questions would really simplify their use of a survey tool. LimeSurvey could leverage on the community spirit of an open source product and encourage users to share their own work. By integrating a &amp;quot;Publish to the LimeSurvey Library&amp;quot; button in the administration system with questions, or templates, or anything else that can be shared, LimeSurvey could develop a library of tools that simplifies Survey Creation even further.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Web and User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jasebo)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Condition Engine==&lt;br /&gt;
&lt;br /&gt;
[[File:addNewCondition1.png]]&lt;br /&gt;
&lt;br /&gt;
Build a system for LS2 that will let survey administrators design, store and evaluate conditions. Conditions can be used in several features such as question branching (survey logic), assessments, quotas, ...&lt;br /&gt;
&lt;br /&gt;
This projects will at least end up with:&lt;br /&gt;
* A working GUI to design complex conditions:&lt;br /&gt;
** several atomic conditions can be combined by AND or OR logical operators and will support for grouping conditions with parentheses&lt;br /&gt;
** an atomic condition representation can be&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;left operand&amp;gt; &amp;lt;operator&amp;gt; &amp;lt;right operand&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** an atomic condition editor will implement&lt;br /&gt;
*** several operators (equality, inequality, string-comparisons, numerical-comparisons, regexp),...&lt;br /&gt;
*** meta operators surch as &#039;Not displayed&#039;&lt;br /&gt;
** left and right operands can be answers from previous questions, or a static values. It should be extensible so that we are able in the future to use more complex operand such as the result of a specific function (for instance the sum of some previous integer questions)&lt;br /&gt;
* A working DB storage backend using a string in [http://en.wikipedia.org/wiki/Reverse_Polish_Notation RPN] (Reverse Polish Notation) to describe each condition&lt;br /&gt;
* A first version of the evaluation of conditions for the question branching feature. This part will require interaction with other parts of the projects (Survey Engine, and DB engine).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, JQuery and User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thibault Le Meur (lemeur)&lt;br /&gt;
&lt;br /&gt;
=We want your ideas!=&lt;br /&gt;
&lt;br /&gt;
What floats your boat? Do you have another idea that gets you excited? Discuss your ideas in our [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/catid,11/id,24710/lang,en/ forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing lists] or at #limesurvey on irc.freenode.net.&lt;br /&gt;
&lt;br /&gt;
=More Information=&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Google&#039;s Summer of Code 2010==&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010 Limesurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
An introduction to LimeSurvey and our application for this years Google Summer of Code&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started How to get started with LimeSurvey&#039;s GSoC]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
==Frequently Asked Questions==&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google&#039;s Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2010&amp;diff=2481</id>
		<title>Project ideas for GSOC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2010&amp;diff=2481"/>
		<updated>2010-03-20T15:04:35Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Welcome=&lt;br /&gt;
&lt;br /&gt;
Welcome Google Summer of Code Student aspirants (:razz:)!! Please check if you are an [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#student_eligibility eligible candidate] for the GSoC program.&lt;br /&gt;
&lt;br /&gt;
This page lists project ideas developed by the LimeSurvey Community. These tend to be areas that will get the most support as projects since they have been developed by people who know the project and what it needs the most. &#039;&#039;&#039;However&#039;&#039;&#039;, if you have your own idea for a project discuss your awesome idea with us in our [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/catid,11/id,24710/lang,en/ forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing list] or at #limesurvey on irc.freenode.net. Then submit &#039;&#039;&#039;your&#039;&#039;&#039; proposal. Good Luck (:biggrin:)&lt;br /&gt;
&lt;br /&gt;
=Project ideas=&lt;br /&gt;
&lt;br /&gt;
==Example Format...==&lt;br /&gt;
&lt;br /&gt;
Describe the idea here in general terms&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain what sort of coding skills would be needed for a student to implement this project&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain the level of difficulty involved&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Put your name (and tag) here if you are willing to mentor a student for this idea&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: File Upload question type==&lt;br /&gt;
&lt;br /&gt;
The idea is to have a question type in LimeSurvey1 where survey participants can upload one (or more) files. Often in surveys the participant is asked to create some content (pictures, movies, documents, etc.)  to upload as an answer to a question. The following goals are  primary in this task:&lt;br /&gt;
*Easy handling for the participant (uploading one or more files should be a piece of cake - also removing files if accidentally the wrong file was uploaded)&lt;br /&gt;
*Extensive configuration options for the question type like&lt;br /&gt;
**How many files are required, minimum and maxim number of files,&lt;br /&gt;
**maximum/minimum upload size,&lt;br /&gt;
**Allowed file types&lt;br /&gt;
*Safe!! storage in the file system, checks for file contents&lt;br /&gt;
*Implementation in statistics / data entry / printable survey / response browsing / response editing &amp;amp; RemoteControl&lt;br /&gt;
*Administrator can download one or more files (zip-packaging files for download) from one response and across responses&lt;br /&gt;
*Provide possible hooks for third party processing tools&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, jQuery, AJAX - existing knowledge on the general idea and related security would be of big advantage&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
c_schmitz (Carsten Schmitz)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: Authentication framework==&lt;br /&gt;
&lt;br /&gt;
The idea is to design and implement a generic authentication framework for LimeSurvey 1 as well as some authentication modules. The Authentication framework will make it possible to implement any kind of authentication backend apart from the already existing internal-DB and Web server delegation schemes. Currently authentication is only used for the survey-administration GUI and not the participants interface (tokens are used for this). With the new authentication framework it will be possible to define several authentication backends and use some of them for participants-authentication.&lt;br /&gt;
&lt;br /&gt;
The generic authentication framework must define the following services:&lt;br /&gt;
* User authentication: this interface must return the identity of the authenticated user if authentication is successful.&lt;br /&gt;
** Authentication may not always be based on a simple user/password form, so the proposed framework must be generic enough to enable authentication based on other schemes (using any numbers or GET/POST parameters or any other contextual parameter such as Referrer, session variable...&lt;br /&gt;
* User provisionning:&lt;br /&gt;
** when activated on the survey administration interface, an authentication module might be able to create a newly authenticated user into the LimeSurvey internal DB (which is required for setting the user rights on the platform). The newly created user can be assigned a default profile or a per-user profile (queried from an external database).&lt;br /&gt;
** when activated on the participants interface, the authentication module will provision the token table of the correspoding survey (only if the token for this user has not been already added).&lt;br /&gt;
&lt;br /&gt;
The already existing authentication schemes will be ported to the new framework (internal-DB and Web server authentication delegation) and at least a new one will be implemented (openID, CAS, Shibboleth).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, Authentication protocols (openID, CAS, LDAP-bind, ...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
lemeur (Thibault Le Meur)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Db Storage Engine==&lt;br /&gt;
&lt;br /&gt;
Develop an extensible plugin survey storage engine for LimeSurvey 2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other than survey design, everything that happens in LimeSurvey centres around the ability to save responses to questions to a database, and retrieve the responses again when required. Historically these functions have been incorporated within the various functions of LimeSurvey and this has locked LimeSurvey to a single methodology for data storage and retrieval and made future modifications and improvements difficult if not possible.&lt;br /&gt;
&lt;br /&gt;
For this project we are looking for students to write a &#039;middleware&#039; that exposes abstract high-level functions to LimeSurvey 2 (e.g.: storing these answers related to this question, running statistical analysis etc.) but is built in top of Cake&#039;s &#039;low-level&#039; operations (such as find, save etc). The aim is to abstract away from a specific DB implementation and provide an intuitive and rich API for LS2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Rationale&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the interface with the data storage system is so critical to practically every other function in LimeSurvey we want to develop a stand-alone module that is transportable and extensible for the future. And by keeping the logic of data and survey storage separate from the rest of LimeSurvey&amp;amp;rsquo;s functions we will the ease with which LimeSurvey can be developed in the long term.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Implementation&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is such an important project that we would consider multiple students undertaking the task. In conjunction with a strong understanding of data structures, php coding and api principles the students would also have to display a capacity to work in a team and with the broader community.&lt;br /&gt;
&lt;br /&gt;
The implementation would focus on becoming a plugin/addon module under CakePHP which uses the default CakePHP database systems to the absolute minimum. In a well implemented version of this proposal only simple SQL inserts, queries and updates would be required. All other logic would be managed by the engine.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Requirements &amp;amp; Considerations&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DB Engine must be able to do the following&lt;br /&gt;
* ease development of additional &#039;&#039;&#039;question types, which will be developed as plugins&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;efficient data retrieval&#039;&#039;&#039;, especially summaries (e.g. display 100 last responses)&lt;br /&gt;
* support &#039;&#039;&#039;generic&#039;&#039;&#039; data storage and retrieval - aside surveys, imagine running online admission tests, polls, sign-up forms, volunteer campaign etc. etc.&lt;br /&gt;
* easily support conditions, looped question, or generally, &#039;&#039;&#039;non-linear data&#039;&#039;&#039;. Think of a survey that asks how many children you have and then asks information about each of them.&lt;br /&gt;
* support questions that have multiple &#039;&#039;&#039;answers and multiple types of answers&#039;&#039;&#039;. Think of a question asking &amp;quot;What is your favourite ice cream?&amp;quot;, offering 3 fixed options and last one allowing user to enter a custom answer.&lt;br /&gt;
* support survey resuming (where applicable)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Field Naming and Database Extensibility Methodologies&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An ongoing debate in the LimeSurvey community has been the method in which the database stores survey results. In LimeSurvey 1 a flat database schema was used whereby once the survey designer had finished setting up the survey a database table was created with a field for every individual question/answer combination. The advantages of this database schema were speed of retrieval for reporting and exporting and searching. The disadvantages were that the survey system had to &amp;amp;lsquo;freeze&amp;amp;rsquo; the structure in place once the table was created (therefore the activate/de-activate rules in LimeSurvey 1). The single table method doesn&amp;amp;rsquo;t allow easy storage of metadata for individual question/answer combinations (such as timestamps). Nor does it lend itself to surveys with enormous quantities of question/answer combinations &amp;amp;ndash; sometimes running up against database limitations regarding the number of fields per table.&lt;br /&gt;
&lt;br /&gt;
An alternative is a &amp;amp;lsquo;normalised&amp;amp;rsquo; database topology where a single table is created to store all survey responses &amp;amp;ndash; one database row per question/answer combination. A related table would store metadata that is directly related to the survey sitting/session rather than the answer (e.g.: username, ip address, geographical location, user demographic). The advantage to this methodology is the increased flexibility (extensible) which would allow modification of surveys at any stage even after data has been collected (see requirements). The disadvantages are that searching and compilation of data is complicated and resource intensive.&lt;br /&gt;
&lt;br /&gt;
In a perfect world LimeSurvey would allow users to choose either methodology &amp;amp;ndash; either at an installation level or even on a per-survey level.&lt;br /&gt;
&lt;br /&gt;
Having a database storage engine effectively acting as an API would allow this functionality to be built, but the choice of database topology would be invisible to the related LimeSurvey functions that require data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Database Schema Design, Sound knowledge of Algorithms and Data Structures&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
jasebo (Jason Cleeland)&lt;br /&gt;
&lt;br /&gt;
macduy (Mac Duy Hai)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Template Editor==&lt;br /&gt;
&lt;br /&gt;
Limesurvey 2 needs a nice and powerful template editor so everyone can create a template which matches their requirements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
One needs to know about the details of the [http://dwoo.org/ dwoo template engine] which is used at LS2. There is some cakePHP coding needed to create an interface and write changes to the template files as well as some HTML/CSS to create a nice interface.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You don&#039;t have to create difficult algorithms for this task. It&#039;s useful if you have worked with templates for another web-application or take a detailled look at [http://docs.limesurvey.org/tiki-index.php?page=Themes%3A+Templates+and+Styles&amp;amp;structure;=English+Instructions+for+LimeSurvey how templates work in Limesurvey]. Some design/usability background would be nice but is not a must.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mazi&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Mini-projects==&lt;br /&gt;
&lt;br /&gt;
Mini-projects is a collection of small-to-medium sized projects, which you mix-and-match according to your tastes. Heck, you can even roll your own idea and once reviewed and approved, you can code away. Some recommended/important mini-projects and their brief descriptions:&lt;br /&gt;
*&#039;&#039;&#039;Smarter installer:&#039;&#039;&#039; LS2.0 comes with its own installer, though it may not be the friendliest to use. Your task is to make it juicier to use:&lt;br /&gt;
** Resume installation - if the user aborts the installation mid-way, make it easy for him to resume it&lt;br /&gt;
** Better error handling - meaningful error reports, suggestions how to fix them: e.g. &amp;quot;Database does not exist&amp;quot; is better than &amp;quot;Database error&amp;quot;&lt;br /&gt;
** Customization - invite the user to customize his installation of LimeSurvey - from security settings such as salt, to interface such as the header title.&lt;br /&gt;
*&#039;&#039;&#039;User management:&#039;&#039;&#039; When the number of users grow, it becomes increasingly harder to manage them. Implement functionality and provide interface for features that would make this task easier. Inspire yourself by the big players, such as the infamous you-know-which-one social website.&lt;br /&gt;
**&#039;&#039;&#039;Groups within groups:&#039;&#039;&#039; LS2 users can belong to a group, but groups cannot belong to other groups.&lt;br /&gt;
**&#039;&#039;&#039;Contact lists:&#039;&#039;&#039; There is already something called AssignmentGroups. Study this concept carefully and generalize to a Contact List&lt;br /&gt;
**&#039;&#039;&#039;GUI:&#039;&#039;&#039; Design a GUI which allows you easily manage users, groups and contact lists.&lt;br /&gt;
**&#039;&#039;&#039;Searching:&#039;&#039;&#039; Provide an efficient but simple-to-use search interface and functionality&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, JavaScript &amp;amp; jQuery&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mac Duy Hai (macduy)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Template/Theme Editor==&lt;br /&gt;
&lt;br /&gt;
The idea is to develop a theme / template framework similar to one in jquery [http://jqueryui.com/themeroller/ | Jquery Theme Roller] and thus making the UI design of the surveys easier.The current template editor is based on dwoo template engine which actually loads the files exposing the css etc for us to edit, which of course require some skill set to proceed. Using this template editor we can make everything UI based and thus requiring no developer skills to edit the templates.&lt;br /&gt;
&lt;br /&gt;
The overview of the modules can be seen here:&lt;br /&gt;
&lt;br /&gt;
[[File:theme_roller.png]]&lt;br /&gt;
&lt;br /&gt;
It&amp;amp;rsquo;ll be implemented using Jquery to use the more advanced UI experiences.(:biggrin:)&lt;br /&gt;
&lt;br /&gt;
The following mock-up will give us a better view:&lt;br /&gt;
&lt;br /&gt;
Moderate[[File:theme_editor_small.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, CSS, AJAX, JavaScript &amp;amp; jQuery.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Lime Survey Social - Facebook Application==&lt;br /&gt;
&lt;br /&gt;
The idea aims at developing a Facebook app which gives a social touch to LS 2.0. The application will be integrated in several Facebook integration points like News Feed, Applications boxes, Wall etc so that the user participation will be more. Adding a social touch can drive us more user participation and increase the popularity. The ability to control the Facebook app can be provided in the LS2.0 Admin Dashboard and also in the FB user application window with varied options.&lt;br /&gt;
&lt;br /&gt;
The facebook has the following modules (we can add more. This is primary draft.)&lt;br /&gt;
*All Survey related core features. (Create, Edit, Delete, Administer etc)&lt;br /&gt;
*Gain reward points.&lt;br /&gt;
*Use reward points to create more surveys.&lt;br /&gt;
*Spread the surveys ...... and more&lt;br /&gt;
&lt;br /&gt;
The idea can be extended to other social networks&lt;br /&gt;
&lt;br /&gt;
[[File:fb_overview.png]]&lt;br /&gt;
&lt;br /&gt;
The mock-ups :&lt;br /&gt;
&lt;br /&gt;
[[File:facebook app.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:canvas.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Facebook API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Integration of Poll Questions==&lt;br /&gt;
&lt;br /&gt;
Polls are one of the most popular and quick response getting tools once can use. Implementing polls in LS 2.0 will be an added advantage. Since every one of us know what polls are about, this idea focuses on the implementation part.&lt;br /&gt;
&lt;br /&gt;
The idea is to integrate the ability to create a POLL Module in Admin dashboard, where he can administer (Create | Edit | Delete | View Responses etc) the Polls.We can even get feedback &amp;amp;ldquo;about the survey&amp;amp;rdquo; at the end on how the user feels by creating a custom poll (we can even redirect the user to this poll).&lt;br /&gt;
*Chat Bots and Polls: An another idea is to create chat bots so that whenever we create a poll, all the friends (who added the bot) of that bot will be pinged by the question followed by options. Getting an answer is very easy (Bot friends just need to type a single letter stating the answer) and its a push model which ensures the delivery to everyone (even offline).We can even extend this to deliver certain type of surveys question by question through the bot.&lt;br /&gt;
&lt;br /&gt;
A simple mock-up for this:&lt;br /&gt;
&lt;br /&gt;
[[File:chat.png]]&lt;br /&gt;
*Alternate Solution: An alternate solution provided by Mazi is clubbing this idea with the Facebook app idea. Instead of porting parts of the admin backend to facebook or other social networks we&#039;ll have options in Admin panel to &amp;quot;publish as: common survey |mobile device survey | facebook poll | homepage poll |  ... etc &amp;quot; Everything will be put together at the usualm admin backend but you can choose which way(s) you want publish your survey.&lt;br /&gt;
&lt;br /&gt;
We can further extend this idea by giving additional options to publish as widgets for websites and blogs etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, XMPP Protocol (Knowledge of developing bots), Knowledge of Polls.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Survey Community Project==&lt;br /&gt;
&lt;br /&gt;
Build a system for LS2 that connects to a central repository of survey resources, such as demographic questions, answer styles and templates. Integrating with a login system, allow LimeSurvey users to easily publish their work to a community resource or use other published works from the same location.&lt;br /&gt;
&lt;br /&gt;
For many finding already written question texts, or standardised demographic questions would really simplify their use of a survey tool. LimeSurvey could leverage on the community spirit of an open source product and encourage users to share their own work. By integrating a &amp;quot;Publish to the LimeSurvey Library&amp;quot; button in the administration system with questions, or templates, or anything else that can be shared, LimeSurvey could develop a library of tools that simplifies Survey Creation even further.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Web and User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jasebo)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Condition Engine==&lt;br /&gt;
&lt;br /&gt;
[[File:addNewCondition1.png]]&lt;br /&gt;
&lt;br /&gt;
Build a system for LS2 that will let survey administrators design, store and evaluate conditions. Conditions can be used in several features such as question branching (survey logic), assessments, quotas, ...&lt;br /&gt;
&lt;br /&gt;
This projects will at least end up with:&lt;br /&gt;
* A working GUI to design complex conditions:&lt;br /&gt;
** several atomic conditions can be combined by AND or OR logical operators and will support for grouping conditions with parentheses&lt;br /&gt;
** an atomic condition representation can be&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;left operand&amp;gt; &amp;lt;operator&amp;gt; &amp;lt;right operand&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** an atomic condition editor will implement&lt;br /&gt;
*** several operators (equality, inequality, string-comparisons, numerical-comparisons, regexp),...&lt;br /&gt;
*** meta operators surch as &#039;Not displayed&#039;&lt;br /&gt;
** left and right operands can be answers from previous questions, or a static values. It should be extensible so that we are able in the future to use more complex operand such as the result of a specific function (for instance the sum of some previous integer questions)&lt;br /&gt;
* A working DB storage backend using a string in [http://en.wikipedia.org/wiki/Reverse_Polish_Notation RPN] (Reverse Polish Notation) to describe each condition&lt;br /&gt;
* A first version of the evaluation of conditions for the question branching feature. This part will require interaction with other parts of the projects (Survey Engine, and DB engine).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, JQuery and User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thibault Le Meur (lemeur)&lt;br /&gt;
&lt;br /&gt;
=We want your ideas!=&lt;br /&gt;
&lt;br /&gt;
What floats your boat? Do you have another idea that gets you excited? Discuss your ideas in our [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/catid,11/id,24710/lang,en/ forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing lists] or at #limesurvey on irc.freenode.net.&lt;br /&gt;
&lt;br /&gt;
=More Information=&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Google&#039;s Summer of Code 2010==&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010 Limesurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
An introduction to LimeSurvey and our application for this years Google Summer of Code&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started How to get started with LimeSurvey&#039;s GSoC 2009]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
==Frequently Asked Questions==&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google&#039;s Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2923</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2923"/>
		<updated>2010-03-20T03:54:00Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey RemoteControl is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
=Installation=&lt;br /&gt;
&lt;br /&gt;
== How to install LSRC==&lt;br /&gt;
&lt;br /&gt;
If you are using version 1.80 or higher, you do not need to install LSRC, it is included in the package and will be ready to set up - you will not need to install it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; It is included in Limesurvey since 1.80RC2, before 1.80RC4 it was called &amp;quot;japh&amp;quot; or &amp;quot;japhService&amp;quot;&lt;br /&gt;
* create a Dir &amp;quot;remotecontrol&amp;quot; in your LimeSurvey admin dir.&lt;br /&gt;
* copy the included files to the new directory.&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
&lt;br /&gt;
In a default LimeSurvey installation LSRC is disabled. In order to use LSRC you must first enable the service, and then adjust the settings to suit your needs.&lt;br /&gt;
* To &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes it&#039;s own log. This log is particularly helpful when implementing new features. If some functions of LSRC don&#039;t work look for where it stops functioning in this log. Once you have finished setting up or developing new features you should turn the log off by setting this value to false.&lt;br /&gt;
** $lsrcDebugLog, The name of the file where the log should be written.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment this line out (put two forward slashes at the beginning of the line &amp;quot;//&amp;quot;) once you have finished setting up and have put your LSRC service into production.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. &#039;&#039;&#039;Note:&#039;&#039;&#039;Turning this on simply changes the internal addressing to either &amp;quot;https:&amp;quot; or &amp;quot;http:&amp;quot; in order to work over a SSL connection, nothing more.&lt;br /&gt;
** set the directories, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE on PHP 5.3:&#039;&#039;&#039; setting the path2wsdl to http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl worked with all prior 5.3 version of PHP. With PHP 5.3 the client will not recognize the wsdl lsrc.server.php?wsdl gives back. You have to call lsrc.server.php?wsdl once to generate the lsrc.wsdl file and then point your client to http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl instead.&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; ,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyDescription&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;welcomeText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;endText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyAdmins@email.adress&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Survey Adminsname&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;http://an.end.url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Description of End Url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.testclient.php needs to fit the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to set this vars in lsrc.testclient.php ( lines 40 and 41)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Known Bugs (and workarounds)=&lt;br /&gt;
* With PHP 5.3.0, the testclient have problems to read the generated wsdl from lsrc.server.php?wsdl. You have to generate it an use the static file to test it.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2924</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2924"/>
		<updated>2010-03-20T03:48:49Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey RemoteControl is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
=Installation=&lt;br /&gt;
&lt;br /&gt;
== How to install LSRC==&lt;br /&gt;
&lt;br /&gt;
If you are using version 1.80 or higher, you do not need to install LSRC, it is included in the package and will be ready to set up - you will not need to install it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; It is included in Limesurvey since 1.80RC2, before 1.80RC4 it was called &amp;quot;japh&amp;quot; or &amp;quot;japhService&amp;quot;&lt;br /&gt;
* create a Dir &amp;quot;remotecontrol&amp;quot; in your LimeSurvey admin dir.&lt;br /&gt;
* copy the included files to the new directory.&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
&lt;br /&gt;
In a default LimeSurvey installation LSRC is disabled. In order to use LSRC you must first enable the service, and then adjust the settings to suit your needs.&lt;br /&gt;
* To &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes an own log. This log is helpful when implementing new features, if some function does not work, look where it hangs in this log. Should be set to false if in productive Use.&lt;br /&gt;
** $lsrcDebugLog, File where the log should be written to.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment if in productive Mode.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. It does not more or less than generating the target address in the wsdl with http: or https:.&lt;br /&gt;
** set the dirs, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE on PHP 5.3:&#039;&#039;&#039; setting the path2wsdl to http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl worked with all prior 5.3 version of PHP. With PHP 5.3 the client will not recognize the wsdl lsrc.server.php?wsdl gives back. You have to call lsrc.server.php?wsdl once to generate the lsrc.wsdl file and then point your client to http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl instead.&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; ,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyDescription&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;welcomeText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;endText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyAdmins@email.adress&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Survey Adminsname&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;http://an.end.url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Description of End Url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.testclient.php needs to fit the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to set this vars in lsrc.testclient.php ( lines 40 and 41)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Known Bugs (and workarounds)=&lt;br /&gt;
* With PHP 5.3.0, the testclient have problems to read the generated wsdl from lsrc.server.php?wsdl. You have to generate it an use the static file to test it.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2925</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2925"/>
		<updated>2010-03-20T03:45:35Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey RemoteControl is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
=Installation=&lt;br /&gt;
&lt;br /&gt;
== How to install LSRC==&lt;br /&gt;
&lt;br /&gt;
If you are using version 1.80 or higher, you do not need to install LSRC, it is included in the package and will be ready to set up - you will not need to install it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; It is included in Limesurvey since 1.80RC2, before 1.80RC4 it was called &amp;quot;japh&amp;quot; or &amp;quot;japhService&amp;quot;&lt;br /&gt;
* create a Dir &amp;quot;remotecontrol&amp;quot; in your LimeSurvey admin dir.&lt;br /&gt;
* copy the included files to the new directory.&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
* first of all you have to &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes an own log. This log is helpful when implementing new features, if some function does not work, look where it hangs in this log. Should be set to false if in productive Use.&lt;br /&gt;
** $lsrcDebugLog, File where the log should be written to.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment if in productive Mode.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. It does not more or less than generating the target address in the wsdl with http: or https:.&lt;br /&gt;
** set the dirs, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE on PHP 5.3:&#039;&#039;&#039; setting the path2wsdl to http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl worked with all prior 5.3 version of PHP. With PHP 5.3 the client will not recognize the wsdl lsrc.server.php?wsdl gives back. You have to call lsrc.server.php?wsdl once to generate the lsrc.wsdl file and then point your client to http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl instead.&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; ,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyDescription&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;welcomeText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;endText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyAdmins@email.adress&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Survey Adminsname&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;http://an.end.url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Description of End Url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.testclient.php needs to fit the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to set this vars in lsrc.testclient.php ( lines 40 and 41)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Known Bugs (and workarounds)=&lt;br /&gt;
* With PHP 5.3.0, the testclient have problems to read the generated wsdl from lsrc.server.php?wsdl. You have to generate it an use the static file to test it.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2926</id>
		<title>RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=RemoteControl&amp;diff=2926"/>
		<updated>2010-03-20T03:44:55Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey RemoteControl is a PHP:SOAP based Web service application.&lt;br /&gt;
&lt;br /&gt;
The LSRC makes it possible for developers to control specific functionality of Limesurvey from any other Application, without beeing restricted to PHP as a Programming language.&lt;br /&gt;
&lt;br /&gt;
You can start a predefined survey (change titles and things), add predefined groups or questions to this coresurvey. Activate the survey, restrict it to start and endtime, make it closed, add Participant data or just tokens when you need them (your customer just bought a book and now you want to invite him to a closed survey automatically), return the unused tokens to the main application, delete a survey, get a fieldmap for a survey, invite or remind the participants of your survey, etc...&lt;br /&gt;
&lt;br /&gt;
Be aware that this piece of code was originally written to bind LimeSurvey to a University management software in order to evaluate lectures. So there could be comments in the code or documentation, which have to do with my Company&#039;s Software or which are just a little bit confusing when you have nothing to do with University&#039;s or the German language.&lt;br /&gt;
&lt;br /&gt;
Post any comments, wishes or bugs to the [http://bugs.limesurvey.org bugtracker].&lt;br /&gt;
&lt;br /&gt;
==Files included in LSRC==&lt;br /&gt;
* lsrc.config.php (configuration variables)&lt;br /&gt;
* lsrc.server.php (the logical SOAP:Server brain. Programm logic is mainly in here )&lt;br /&gt;
* lsrc.helper.php (class LsrcHelper, this Class does the work. Mainly copied and customized from Limesurvey files. Especially for import tasks)&lt;br /&gt;
* lsrc_orig.wsdl (wsdl definition for SOAP messages. From this file the lsrc.wsdl is generated with correct paths)&lt;br /&gt;
* lsrc.testclient.php (to test the environment and functionality of the webservice on the fly)&lt;br /&gt;
&lt;br /&gt;
== Directory included==&lt;br /&gt;
* \surveys (for the core survey .csv&#039;s.) Used by sCreateSurvey.&lt;br /&gt;
* \groups (for exported group .csv&#039;s . Used by sImportGroup. There should be always an empty group for importing, so you can add questions to a new group)&lt;br /&gt;
* \questions (for exported questions .csv&#039;s. sImportFreetext and sImportMatrix depend on &amp;quot;Freitext.csv&amp;quot; and &amp;quot;Matrix5.csv&amp;quot; which should be exported questions(Freetext and Array 5 point Matrix).&lt;br /&gt;
&lt;br /&gt;
== Requirements==&lt;br /&gt;
* PHP &amp;gt;= 5.2.1 with PHP:SOAP Extension enabled&lt;br /&gt;
* libXML installed&lt;br /&gt;
* MySQL, PostgreSQL or (not recommended) MSSQL&lt;br /&gt;
* (optional) OpenSSL&lt;br /&gt;
* (optional) a Certificate for better Security&lt;br /&gt;
&lt;br /&gt;
=Installation=&lt;br /&gt;
&lt;br /&gt;
== How to install LSRC==&lt;br /&gt;
&lt;br /&gt;
If you are using version 1.80 or higher, you do not need to install LSRC, it is included in the package.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; It is included in Limesurvey since 1.80RC2, before 1.80RC4 it was called &amp;quot;japh&amp;quot; or &amp;quot;japhService&amp;quot;&lt;br /&gt;
* create a Dir &amp;quot;remotecontrol&amp;quot; in your LimeSurvey admin dir.&lt;br /&gt;
* copy the included files to the new directory.&lt;br /&gt;
&lt;br /&gt;
== How to configure LSRC==&lt;br /&gt;
* first of all you have to &#039;&#039;&#039;enable the LSRC in LimeSurveys config.php&#039;&#039;&#039; or in lsrc.config.php&lt;br /&gt;
** set the variable &#039;&#039;&#039;$enableLsrc = true&#039;&#039;&#039;;&lt;br /&gt;
* In the &#039;&#039;&#039;lsrc.config.php&#039;&#039;&#039; file, you can &#039;&#039;&#039;set all needed Variables&#039;&#039;&#039; for the LSRC in Section Variables.&lt;br /&gt;
** set the Error Handling. While configuring and testing it is very good to get all errors. If you are using lsrc in Production, you should comment error_reporting, so that it sticks to the servers defaults.&lt;br /&gt;
** $lsrcDebug, if set to true, the lsrc writes an own log. This log is helpful when implementing new features, if some function does not work, look where it hangs in this log. Should be set to false if in productive Use.&lt;br /&gt;
** $lsrcDebugLog, File where the log should be written to.&lt;br /&gt;
** ini_set(&amp;quot;log_errors&amp;quot;, &amp;quot;1&amp;quot;), Apaches log file (error.log) will get filed with php-errors. Very useful for debugging. Comment if in productive Mode.&lt;br /&gt;
** ini_set(&amp;quot;soap.wsdl_cache_enabled&amp;quot;, &amp;quot;0&amp;quot;), while testing, caching is not useful. If in productive Mode, turn this on or just comment the line to stick to server defaults.&lt;br /&gt;
** (optional) set $lsrcOverSSL to true, if you want SOAP to exchange the messages over SSL resp. https. It does not more or less than generating the target address in the wsdl with http: or https:.&lt;br /&gt;
** set the dirs, where the .csv files to import can be found. You will have to export some survey, you want to import and activate with LSRC, first.&lt;br /&gt;
** (optional) change $sLsrcSeparator = &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate tokens for the sInsertToken function with any other separator than default, which is a comma.&lt;br /&gt;
** (optional) change $sDatasetSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datasets for the sInsertParticipants function with any other separator than default, which are two colons.&lt;br /&gt;
** (optional) change $sDatafieldSeperator= &amp;quot;your separator&amp;quot;; in lsrc.config.php if you wish to separate Datafields for the sInsertParticipants function with any other separator than default, which is a semicolon.&lt;br /&gt;
* the script needs rights to write files to the folder &amp;quot;admin/remotecontrol/&amp;quot;  (lsrc.log, if logging is used and lsrc.wsdl). if(you cannot or don&#039;t want to set the directory rights to 777){create those two files(lsrc.log and lsrc.wsdl)in the lsrc dir with the permission to write them(777))&lt;br /&gt;
* If you want to save Survey, group or question csv&#039;s directly from Limesurvey into the lsrc Folders, you need to set them to 777, too. (Option can be enabled by adding $export4lsrc = true; to Limesurveys config.php)&lt;br /&gt;
* You may have to generate a wsdl file if you need a static one. Run lsrc.server.php?wsdl and the script will make a lsrc.wsdl with the correct server url included in the lsrc directory.&lt;br /&gt;
* If auto wsdl generation do not work properly (maybe virtual hosts make Problems, please report back, if so or not so, can&#039;t test at the moment) You have to set the url of the lsrc.server.php script in the last block of the wsdl&lt;br /&gt;
&lt;br /&gt;
==How to enable OpenSSL / https Support==&lt;br /&gt;
* LSRC supports SSL over http resp. https.&lt;br /&gt;
* Your Webserver needs to support and enable OpenSSL (See your Webserver Manual)&lt;br /&gt;
* &#039;&#039;&#039;ATTENTION:&#039;&#039;&#039; Just set the Variable $lsrcOverSSL = true; in lsrc.config.php. After that, initialize your client like shown below, a wsdl file with correct URL will be generated automaticly for you:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;https://localhost/limesurvey/admin/lsrc.server.php?wsdl&#039;,&lt;br /&gt;
&lt;br /&gt;
                 array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &#039;ONLY FOLLOW THIS STEPS IF WSDL GENERATION DOES NOT WORK FOR YOU&#039; &amp;lt;br&amp;gt;There are two locations in the code, where you force the webservice to use https&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 1. On the client side, when you call the SOAP-Server over wsdl. For &#039;https&#039; do it like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; for &#039;http&#039; like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new SoapClient(&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl&#039;, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; Note that the client will only get the wsdl-definition over https, to get the SOAP Messages over https, set the uri in the wsdl file, like below...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; 2. Here is the most important Step to SSL. At the End of the lsrc.wsdl file, last block, same procedure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;https://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt; or for normal http mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;port name=&#039;LsrcPort&#039; binding=&#039;tns:LsrcBinding&#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;soap:address location=&#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php&#039; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;/port&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! all request, response and fault messages will be transported over https...&lt;br /&gt;
&lt;br /&gt;
=How to use LSRC=&lt;br /&gt;
&lt;br /&gt;
==use the client==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE on PHP 5.3:&#039;&#039;&#039; setting the path2wsdl to http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl worked with all prior 5.3 version of PHP. With PHP 5.3 the client will not recognize the wsdl lsrc.server.php?wsdl gives back. You have to call lsrc.server.php?wsdl once to generate the lsrc.wsdl file and then point your client to http://localhost/limesurvey/admin/remotecontrol/lsrc.wsdl instead.&lt;br /&gt;
&lt;br /&gt;
There is a PHPclient (from version 1.86) in the remotecontrol folder. You can use this ClientClass to control Limesurvey from within your PHP Applications with ease.&lt;br /&gt;
&lt;br /&gt;
Take a look at lsrc.testclient-new.php to get an impression of how it can be implemented.&lt;br /&gt;
&lt;br /&gt;
Basically you just have to include the class, prepare the Client and start the function calls.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* include the client class&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
include_once(&amp;quot;lsrc.client.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* initiate the testclient object&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient = new lsrcClient();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* prepare the lsrcClient class (initiate the soapClient, set sid if needed)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;prepare(333);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set user and password (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;user = &#039;admin&#039;;&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;pass = &#039;password&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* set the path2wsdl (only needed, when not set in the client class directly)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$testclient-&amp;gt;path2wsdl = &#039;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* call the function to create a survey&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$sReturn = $testclient-&amp;gt;createSurvey(&amp;quot;surveyName&amp;quot; ,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyDescription&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;welcomeText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;endText&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;surveyAdmins@email.adress&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Survey Adminsname&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;http://an.end.url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;Description of End Url&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
                                    &amp;quot;template138&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
echo $sReturn;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Skript initiates the client. The parameter at prepare, sets the surveyId. In this case it means we are going to create the survey with the Id 333. If you do not give an id, the survey will get a random id.&lt;br /&gt;
&lt;br /&gt;
Next we set the user and password to use. You do not have to do this, as long as the inital values of the client are correct. But you may have to, if you build your app in a way, that different users use the client to create Surveys or edit them.&lt;br /&gt;
&lt;br /&gt;
In the end, the survey is created with the createSurvey Method and the return is echoed.&lt;br /&gt;
&lt;br /&gt;
==using the functions==&lt;br /&gt;
&lt;br /&gt;
You will need a SOAP- or at least RPC-Client to communicate with the LSRC Webservice. How to create such a Client depends on the programming language you use.&lt;br /&gt;
&lt;br /&gt;
The LSRC itself is written in PHP5 using the PHP:SOAP extension with SOAP 1.1.&lt;br /&gt;
&lt;br /&gt;
In PHP you would initiate the Client-object and call a function from the Webservice with code like e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$wsdl=&amp;quot;http://localhost/limesurvey/admin/remotecontrol/lsrc.server.php?wsdl&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$client = new SoapClient($wsdl, array(&#039;soap_version&#039; =&amp;gt; SOAP_1_1,&lt;br /&gt;
&lt;br /&gt;
                 &#039;trace&#039; =&amp;gt; 1));&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sReturn = $client-&amp;gt;sInsertToken($user, $pass, $iVid, $sToken);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
catch (SoapFault $fault)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    $sOutput .= &amp;quot; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;SOAP Error: &amp;quot;.$fault-&amp;gt;faultcode.&amp;quot; : &amp;quot;.$fault-&amp;gt;faultstring;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The LSRC offers some functions:&lt;br /&gt;
&lt;br /&gt;
(&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) means: Mandatory Parameter&lt;br /&gt;
&lt;br /&gt;
==sCreateSurvey==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;Parameters changed after 1.81+! (sVend added)&amp;lt;/span&amp;gt;&lt;br /&gt;
* String sCreateSurvey($sUser, $sPass, $iVid, $sVtit , $sVbes, $sVwel, $sVend, $sMail, $sName, $sUrl, $sUbes, $sVtyp )&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates a new survey. It imports an exported survey from any LS v1.xx. and changes some fields (in the current Version it changes SurveyTitle,  SurveyDescription and SurveyWelcomeText, adminemail, adminname, url and url_description to the string which was given by the client.)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int $iVid, SurveyID desired ID for the Survey, make sure it doesn&#039;t already exist in LimeSurvey&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVtit, SurveyTitle, should be the (Nr +)Name of the Event to be evaluated&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string $sVbes, Survey Description, This should be String put together with veransttyp + doztitle + dozname&lt;br /&gt;
*** string $sVwel, Survey Welcometext, A text shown before the survey starts. If not given it says: &amp;quot;Herzlich Willkommen zur Evaluation von &amp;quot;$sVtit&amp;quot;&lt;br /&gt;
*** string $sVend, Survey Endtext, Text shown at the endpage.&lt;br /&gt;
*** string $sMail, Admin Email, Email Adress of the responsible person for this survey&lt;br /&gt;
*** string $sName, Name of the responsible person for this survey&lt;br /&gt;
*** string $sUrl, Url of the Link, shown on the last page of survey.&lt;br /&gt;
*** string $sUbes, Description String of the URL above. ( &amp;lt;a href=&#039;$sUrl&#039;&amp;gt;$sUbes&amp;lt;/a&amp;gt; )&lt;br /&gt;
*** string $sVtyp, The type of Event that should be evaluated. Use in combination with sAvailableModules with $mode=&#039;core&#039; to get all available &amp;quot;types&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the created survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;SurveyID already exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Import went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Goto line 714 in lsrc.helper.php to see what can be done and customized while importing.&lt;br /&gt;
*** If you want Limesurvey to give your Survey a random Number if the given ID exist (because you do not need a specific identification for your surveys), just go into the function sCreateSurvey in lsrc.server.php and delete or comment out the if($lsrcHelper-&amp;gt;surveyExists($iVid)) clause. In Result, Limesurvey will give your survey a random ID when the given ID exists.&lt;br /&gt;
&lt;br /&gt;
==sActivateSurvey==&lt;br /&gt;
* String &#039;&#039;&#039;sActivateSurvey&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, date start, date end)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Activates an existing survey and set start and enddate optional&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID for the Survey to activate.&lt;br /&gt;
*** date start, date for the Survey to start. 2008-10-22 means it starts exactly at 2008-10-22 00:00:00 Servertime&lt;br /&gt;
*** date end, date for the Survey to end. 2008-10-22 means it ends exactly at 2008-10-22 23:59:59 Servertime. Nobody can access nor complete the Survey only a second later.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the SurveyID from the activated survey&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey you want to activate does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Activation went wrong somehow&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** You can set startDate and/or endDate after activation if needed. Just run the function again with desired parameters.&lt;br /&gt;
&lt;br /&gt;
==sImportGroup==&lt;br /&gt;
* String &#039;&#039;&#039;sImportGroup&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String groupName, String groupDescription)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported group file (.csv) to the Survey given by SurveyID&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string Module, the filename of the Group you want to add to the Survey. Use sAvailableModules to get the available groups.&lt;br /&gt;
*** string groupName, the Title the Group gets. If not set, it will use the title given in the .csv.&lt;br /&gt;
*** string groupDescription, Description of the group. If not set, it will use the description given in the .csv.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;Import OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Survey Module $sMod does not exist&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under \groups or any other dir given in lsrc.config.php&lt;br /&gt;
*** &amp;lt;strike&amp;gt;It imports only the files beginning with &amp;quot;mod_&amp;quot; ending with &amp;quot;.csv&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
*** The Param Module must only contain the &amp;quot;name of the Module&amp;quot;: Only the String before &amp;quot;.csv&amp;quot;&lt;br /&gt;
*** The baselanguage of the group to import, have to match the baselanguage of the coresurvey.&lt;br /&gt;
&lt;br /&gt;
==sImportQuestion==&lt;br /&gt;
* String &#039;&#039;&#039;sImportQuestion&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last group of the Survey given by SurveyID. This is meant for predefined questions stored in the /question directory&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) String Module, the name of the csv file you want to add to the Survey, without extension(.csv).&lt;br /&gt;
*** String mandatory, default=&#039;N&#039; set to &#039;Y&#039; if you want that question mandatory&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
&lt;br /&gt;
==sImportFreetext==&lt;br /&gt;
* String &#039;&#039;&#039;sImportFreetext&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String questionTitle, String questionText, String questionhelp, String module=&#039;freitext&#039;, string mandatory)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (.csv) to the last Group of the survey given by SurveyID and changes the Title, question and helptext. This is meant for importing empty question.csv&#039;s (Text Questions)&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** String questionTitle, Name or Categorie of the Question&lt;br /&gt;
*** String questionText, The Question itself&lt;br /&gt;
*** String questionhelp, A little Help text for better understanding of the Question&lt;br /&gt;
*** String module, the name of the Module you want to add to the Survey. It should be &amp;quot;Freitext&amp;quot; by default.&lt;br /&gt;
*** String mandatory, make the question mandatory by giving &#039;Y&#039; as this param.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to change Surveys from other people&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported questions as .csv which lay under \questions or any dir given in lsrc.config.php&lt;br /&gt;
*** It is meant for importing one shortext, Longtext or Hugetext Question and changing the Question and Helptext.&lt;br /&gt;
*** The baselanguage of the question to import, have to match the baselanguage of the core survey.&lt;br /&gt;
*** Be sure to have at least one proper .csv (Freitext.csv) in the proper directory (questions), to use this function.&lt;br /&gt;
*** Use sAvailableModules with mode=&#039;que&#039; to get all question .csv&#039;s available.&lt;br /&gt;
&lt;br /&gt;
==sImportMatrix==&lt;br /&gt;
* String &#039;&#039;&#039;sImportMatrix&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, String Module, String questionText, String questionhelp, String questionItems)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Imports an exported question file (Matrix5.csv) to the Survey given by SurveyID and changes the question, helptext and gives Items to the 5 Scale Matrix. This is meant for importing one 5 Scale Matrix Question.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the SurveyID&lt;br /&gt;
*** string Module, the name of the Module you want to add to the Survey. It should be &amp;quot;Matrix&amp;quot; by default.&lt;br /&gt;
*** String questionText, the question or text to the Matrix&lt;br /&gt;
*** String questionhelp, the help text&lt;br /&gt;
*** String questionItems, the Items that should be rated, separated by commas&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns the String &amp;quot;OK&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Group does not support Surveys Baselanguage ($langcode)&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** It imports only exported groups as .csv which lay under docs\demosurveys\studiply_mod&lt;br /&gt;
*** It is meant for importing a group with only one 5 Scale Matrix Question and changing the Question and Helptext and add Items.&lt;br /&gt;
*** Be sure to use an user with the surveys baselanguage as default, because this language is used to fill the language fields for answers and questions while importing.&lt;br /&gt;
&lt;br /&gt;
==sAvailableModules==&lt;br /&gt;
* String &#039;&#039;&#039;sAvailableModules&#039;&#039;&#039;(string USER, string PASSWORD, string mode)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Returning all the csv Names of the csv&#039;s in the Directorys configured in lsrc.config.php&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** String mode, (optional) &amp;quot;mod&amp;quot; for the available groups, &amp;quot;core&amp;quot; for the coreSurveys, &amp;quot;que&amp;quot; for addable questions. Default, when not given is &amp;quot;mod&amp;quot;.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went fine, it returns a String with all surveys, groups or questions (depends on mode) in the Dir given in lsrc.config.php, separated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==sSendEmail==&lt;br /&gt;
* String sSendEmail($sUser, $sPass, $surveyID, $type, $maxLsrcEmails=&#039;&#039;, $subject=&#039;&#039;, $emailText=&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends Emails to Participants of a particular survey&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Useraccount with appropriate rights&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int surveyID, Id of the survey from which participants will be mailed&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string type, the kind of email you like to send (invite, remind or custom)&lt;br /&gt;
*** int $maxLsrcEmails, if you want to override $maxemails setting in config.php for sending mails with lsrc: here you go.&lt;br /&gt;
*** string subject, only needed if type==custom, the subject for the mail to be send.&lt;br /&gt;
*** string emailText, only needed if type==custom, the text for the mail to be send.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** &amp;quot;X Mails send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in custom mode.&lt;br /&gt;
*** &amp;quot;X Mails send. X Mails left to send&amp;quot; or &amp;quot;No Mails to send&amp;quot; in invite mode.&lt;br /&gt;
*** &amp;quot;X Reminders send. X Reminders left to send&amp;quot; or &amp;quot;No Reminders to send&amp;quot; in remind mode.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Type: &amp;quot;, &amp;quot;Wrong send Type given. Possible types are: custom, invite or remind&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** invite: When $maxemails is set the function sends only $maxemails in one go. If you call it again, it will go on to send the invitations, until everyone is invited.&lt;br /&gt;
*** remind: When $maxemails is set, it will only send $maxemails in one go. It checks if reminders have been send to other participants and if there are participants who received less reminders than others, the script will first send reminders to those who have not been reminded so often, until the remindercount is equal.&lt;br /&gt;
*** custom: $maxemails have no effect in custom mode. I have no solution for counting those who have been mailed before.&lt;br /&gt;
&lt;br /&gt;
==sInsertToken==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertToken&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Token)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. It is possible to add tokens to the existing table.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string Token, a string with comma separated tokens. There is a possibility to set any other separator in config.php. Max. tested length of a string was 500,000 tokens, that makes a String of 5,500,000 Chars,  this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 100,000 tokens over the webservice. Repeat for more tokens.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Token given, [X] Token inserted&amp;quot;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Token could not be inserted&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** Make sure on the client side that no token appears twice in the table. There is no check on this and won&#039;t be in the future. What happens if there are two same tokens? 2 participants will get the same token, one will fill out the form for both, and the other will get a message: &amp;quot;your token have already participated&amp;quot;&lt;br /&gt;
*** If there is no token table, it will create one and add the tokens.&lt;br /&gt;
*** If the Tokentable already exists, it just adds the given tokens to the existing table.&lt;br /&gt;
&lt;br /&gt;
==sInsertParticipants==&lt;br /&gt;
* String &#039;&#039;&#039;sInsertParticipants&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string ParticipantData)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Creates and populates a table {dbprefix}token_{SurveyID} and thus &amp;quot;closes&amp;quot; the survey. You can deliver some data to the token table. If you do not support a token, or an empty String as token, a unique token will be generated for the participant.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, ID of the survey to close with a token table&lt;br /&gt;
*** string ParticipantData, The Data have to be in the right Syntax, it&#039;s like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN::FIRSTNAME;LASTNAME;EMAIL;ATTRIB1;ATTRIB2;TOKEN&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The Data Syntax change with 1.86&#039;&#039;&#039;. in order to take language, validfrom, validuntil and a variable count of attributes.&lt;br /&gt;
&lt;br /&gt;
With 1.86 and later versions, it will have to be like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIRSTNAME;LASTNAME;EMAIL;LANGUAGE;TOKEN;VALIDFROM;VALIDUNTIL;attribute1,attribute2,attribute3::FIRSTNAME ... etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
note that the 8th field is the attributes field. There is no 9th field. You can seperate many attributes with a colon (,). The lsrc will create the needed fields in the db if they are not present. All Fields after LANGUAGE are optional and do not have to be send.&lt;br /&gt;
&lt;br /&gt;
seperate the Datasets with double colons (::) and the fields with semicolon (;). The &#039;&#039;&#039;attrib1, attrib2 and token fields are optional&#039;&#039;&#039;, you can just leave them out if not used. Note that the attrib field will get empty and not NULL, by now there where no complications, inform us, if you see some difficulties in not setting them NULL. Max. successfully tested length of a string was 3,000,000 Chars, this is just the limit of the apache webserver on my notebook (CoreDuo 1,6MHz, 1GB Ram) with default Resource Limits (60,60,16). I recommend to send max. 10,000 Datasets over the webservice at once(~1,000,000 chars). Repeat for more Datasets.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** if everything went ok, it returns the String: &amp;quot;[X] Datasets given, [X] rows inserted. &amp;quot;;&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
** &#039;&#039;&#039;Note&#039;&#039;&#039;:&lt;br /&gt;
*** default tokenlength is 5 chars, if you want to change the length, goto lsrc.server.php, line 441&lt;br /&gt;
*** If the token table does not exists, it will be created, and if it does, the data will be added.&lt;br /&gt;
&lt;br /&gt;
==sTokenReturn==&lt;br /&gt;
* string return &#039;&#039;&#039;sTokenReturn&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back all Tokens, which did not complete the Survey, in a String seperated by commas.&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want get the unused tokens&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of all unused tokens seperated by comma.&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Token table for this Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;No unused Tokens found&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==sGetFieldmap==&lt;br /&gt;
* string return &#039;&#039;&#039;sGetFieldmap&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: Gives back the fieldmap for the survey&lt;br /&gt;
&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;fieldname&amp;quot;,&amp;quot;type&amp;quot;,&amp;quot;sid&amp;quot;,&amp;quot;gid&amp;quot;,&amp;quot;qid&amp;quot;,&amp;quot;aid&amp;quot;,&amp;quot;title&amp;quot;,&amp;quot;question&amp;quot;,&amp;quot;group_name&amp;quot;,&amp;quot;lid&amp;quot;,&amp;quot;lid1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39801&amp;quot;,&amp;quot;F&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;How do you feel?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;111X779X39802&amp;quot;,&amp;quot;M&amp;quot;,&amp;quot;111&amp;quot;,&amp;quot;779&amp;quot;,&amp;quot;3980&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;1a&amp;quot;,&amp;quot;Why do you feel like this?&amp;quot;,&amp;quot;Paticipant feelings&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;:&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) int SurveyID, the ID for the Survey from which you want to get the Fieldmap.&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string USER, this have to be an existing Admin-, Superadmin- or Useraccount with the rights to create and activate Surveys&lt;br /&gt;
*** (&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;m&amp;lt;/span&amp;gt;) string PASSWORD, this has to match the password for the account.&lt;br /&gt;
** &#039;&#039;&#039;Returns&#039;&#039;&#039;:&lt;br /&gt;
*** Returns a String, a string of the fieldmap, seperated by comma and blanks&lt;br /&gt;
** &#039;&#039;&#039;Possible Faults&#039;&#039;&#039;:&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to get fieldmaps from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;No SurveyId given&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
==fSendStatistic==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&#039;&#039;(since 1.86)&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;fSendStatistic&#039;&#039;&#039;(string USER, string PASSWORD, int SurveyID, string Email, string doctype, string graph)&lt;br /&gt;
** &#039;&#039;&#039;Purpose&#039;&#039;&#039;: sends an Statistic File as Attachment&lt;br /&gt;
** &#039;&#039;&#039;Parameters&#039;&#039;&#039;&lt;br /&gt;
*** user: Limesurvey user&lt;br /&gt;
*** password: Limesurvey Password&lt;br /&gt;
*** surveyId: ID of the survey from which statistics should be generated&lt;br /&gt;
*** email: the adress to which the statistic file is send&lt;br /&gt;
*** doctype: pdf, xls or html. With pdf or xls, the recipient gets an attached file with a short notice. With html, he gets an html e-mail without attachments&lt;br /&gt;
*** graph: turn graph generation on or off. Works only with pdf generation. Use &#039;1&#039; as a string if you want to enable it&lt;br /&gt;
** &#039;&#039;&#039;returns&#039;&#039;&#039;&lt;br /&gt;
*** string: &#039;XLS send&#039;&lt;br /&gt;
*** string: &#039;PDF send&#039;&lt;br /&gt;
*** string: &#039;HTML send&#039;&lt;br /&gt;
** &#039;&#039;&#039;possible Faults&#039;&#039;&#039;&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Server: &amp;quot;, &amp;quot;Mandatory Parameters missing&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;User or password wrong&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Authentication: &amp;quot;, &amp;quot;You have no right to send statistics from other peoples Surveys&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Database: &amp;quot;, &amp;quot;Survey does not exists&amp;quot;);&lt;br /&gt;
***  throw new SoapFault(&amp;quot;Mail System&amp;quot;, &amp;quot;Mail could not be send! Check your E-Mail Settings.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
&lt;br /&gt;
For testing purposes, we made a testclient in php. Therefore you need a webserver to run it. If you test on one machine you need nothing to do, you can go to http://localhost/limesurvey/admin/lsrc/lsrc.testclient.php in your browser to test the webservices functionality.&lt;br /&gt;
&lt;br /&gt;
Of Course this is very boring, because the apache talks with himself (and thats not the matter of a webservice).&lt;br /&gt;
&lt;br /&gt;
The Testclient have two purposes:&lt;br /&gt;
&lt;br /&gt;
1. It checks the Server(the one the testclient is running on!) for the PHP:SOAP Extension and installed libXML version and gives feedback if the enviroment does support SOAP via PHP:SOAP. This is very useful to check your Server and your Client towards PHP:SOAP compatibility. In addition to this, it will check if the wsdl file you want to connect to exists, it does not validate the wsdl file.&lt;br /&gt;
&lt;br /&gt;
2. You can test the functions of the webservice.&lt;br /&gt;
&lt;br /&gt;
If you test the webservice in realistic enviroment (two machines) you have to customize three things&lt;br /&gt;
* the lsrc.testclient.php needs to be on the machine where the webservice is NOT running, but it needs a webserver... download xampp from apachefriends if you dont have one &amp;lt;strike&amp;gt;(caution for Linux Users: you have to compile PHP5 with SOAP and enable the extension, futhermore you have to install libXML2. Last thing can by done very easy via Synaptics or apt-get)&amp;lt;/strike&amp;gt; xampp for Linux works well with SOAP and libXML from version 1.7.&lt;br /&gt;
* this Line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$limeUrl=&#039;https://localhost/limesource/limesurvey&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the beginning of lsrc.testclient.php needs to fit the target Limesurvey Installation Dir. localhost for servername is always wrong in this testcase, 127.0.0.1, too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTES&#039;&#039;&#039;:&lt;br /&gt;
* The Testclient is configured to use &amp;quot;admin&amp;quot; &amp;quot;password&amp;quot; as authentication. If you want to test with another user or password you have to set this vars in lsrc.testclient.php ( lines 40 and 41)&lt;br /&gt;
* If you just get a blank page on the testclient, make sure the path to the wsdl is correct, and the var $enableLsrc is set to true in config.php or lsrc.config.php&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
* Security is enhanced: no action without permission (as good as Limesurveys Security itself --&amp;gt; very good)&lt;br /&gt;
* No headers or &amp;quot;Quick and Dirtys&amp;quot; anymore, no Scripts, just functions and a class.&lt;br /&gt;
* All configuration Variables are stored in lsrc.config.php by now&lt;br /&gt;
* There is a debug functionality, showing where the script runs through the code in an own log file. Use Apaches error.log in addition to find errors if you got any.&lt;br /&gt;
* LSRC is part of LimeSurvey, therefore it stands under GNU/GPL License v2 or later.&lt;br /&gt;
* SOAP Services and therefore LSRC only support UTF-8 charsets.&lt;br /&gt;
* LSRC works with AdoDB (MySql,Postgresql, MSSQL) .&lt;br /&gt;
* LSRC is tested, but under steady development, use on your own risk, test the functions before using them productively!&lt;br /&gt;
&lt;br /&gt;
=Changes=&lt;br /&gt;
&lt;br /&gt;
1.86&lt;br /&gt;
* new function fSendStatistics: to send statistics as attachment to an e-mail-address&lt;br /&gt;
* Datasyntax for sInsertParticipants changed in order to take validfrom, validuntil, language and a variable Set of attributes.&lt;br /&gt;
&lt;br /&gt;
1.85&lt;br /&gt;
* Several improvements to stability.&lt;br /&gt;
&lt;br /&gt;
1.82&lt;br /&gt;
* Added sVend Parameter to sCreateSurvey, to set the endtext&lt;br /&gt;
* sInsertParticipants takes a token in the dataset, however, if non is supported, it will be generated.&lt;br /&gt;
* a new variable $enableLsrc is introduced to enable the Lsrc only when it is used.&lt;br /&gt;
* a serious exploit has been fixed.&lt;br /&gt;
&lt;br /&gt;
1.81&lt;br /&gt;
* Added sGetFieldmap function.&lt;br /&gt;
* The template.csv&#039;s changed.&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc.&lt;br /&gt;
&lt;br /&gt;
1.80 =&amp;gt; 1.81&lt;br /&gt;
* Changed sImportGroup: imports &#039;&#039;&#039;all&#039;&#039;&#039; groups under $modDir, adds them to the survey. Not only the ones with mod_ as prefix. In addition, you can give Name and Description of the Group.&lt;br /&gt;
* New sImportQuestion: imports questions in $queDir and adds them to the last group&lt;br /&gt;
* New sImportFreetext: imports a Freetext question and changes the title and question to the Strings given. Previously, this function was called sImportQuestion.&lt;br /&gt;
* Changed sAvailableModules: type can be core, mod or que. &amp;quot;que&amp;quot; is new and gives back the names of all the questions available.&lt;br /&gt;
* New sSendEmail: send invitations, reminders and custom mails to participants of a survey over Limesurvey.&lt;br /&gt;
&lt;br /&gt;
=ToDo / ToCome=&lt;br /&gt;
* &amp;lt;strike&amp;gt;sInsertParticipants should take a lang attribute for each participant&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
please add your feature requests to the [http://bugs.limesurvey.org bugtracker] if it is not listed here...&lt;br /&gt;
&lt;br /&gt;
=Known Bugs (and workarounds)=&lt;br /&gt;
* With PHP 5.3.0, the testclient have problems to read the generated wsdl from lsrc.server.php?wsdl. You have to generate it an use the static file to test it.&lt;br /&gt;
* Surveys get not imported in 1.85, due to a bug. The bug is fixed and will be released with the next release. Talk to rakete if you need it earlier...&lt;br /&gt;
* exported csv&#039;s prior 1.81 will not import over lsrc anymore. Import them via Browser and export them back to lsrc to get them work again. (attributes moved from survey to survey_languagesettings)&lt;br /&gt;
* sInsertPaticipants and sInsertToken function: You should note, that in case of an Seperator at the beginning or the end of the Datastring, the return Message will recognize one more given Dataset or Token as inserted into the db...&lt;br /&gt;
* There is a bug with Webservices in general: Sometimes (~ 1 of 10.000 Cases) you will get an error message like &amp;quot;function &#039;anyFunction&#039; does not exist on the server&amp;quot; or similar, altough everything is fine. Just wait a few Moments, clear you cache, phone your mom (she will be happy to hear from you ;)) and try again.&lt;br /&gt;
* Webservice will not work if the &amp;quot;install&amp;quot; dir is not renamed or deleted in limesurvey and $debug is not set to 2 -&amp;gt; &amp;quot;looks like we got no xml document&amp;quot; without errorlogs&lt;br /&gt;
&lt;br /&gt;
please add your bug report to the [http://bugs.limesurvey.org bugtracker] if you found an Issue that is not listed here.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
&lt;br /&gt;
There have been a security hole in the versions prior 1.82 (1.80RC2 to 1.81+). This leak could be used to compromise your webspace if it is weakly configured.&lt;br /&gt;
&lt;br /&gt;
To minimise the risk of a security leak endanger your system, we disabled the lsrc by default with version 1.82 and you have to enable it explicity in your config.php.&lt;br /&gt;
&lt;br /&gt;
Some things you can do to improve your security when using the lsrc:&lt;br /&gt;
* instead of setting the remotecontrol folder to 777, just create an empty file lsrc.wsdl with the rights 777&lt;br /&gt;
* disable the lsrc.log in lsrc.config.php&lt;br /&gt;
* Do not set the survey, groups, questions folders to 777 for saving lsrc templates directly within Limesurvey, instead, save the .csv on your local PC and upload them via ftp to the folders.&lt;br /&gt;
* delete lsrc.testclient.php, when in productive use. Lsrc.testclient.php could be used from unauthorized people to perform portscanning on other machines. The attacked webserver would be seeing your webserver as attacker, altough you did not perform any attack by yourself. This is not so serious, as this bahaviour of the testclient is not much valuable for any serious hacker.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2010&amp;diff=2482</id>
		<title>Project ideas for GSOC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Project_ideas_for_GSOC_2010&amp;diff=2482"/>
		<updated>2010-03-19T10:49:21Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Welcome=&lt;br /&gt;
&lt;br /&gt;
Welcome Google Summer of Code Student aspirants (:razz:)!! Please check if you are an [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#student_eligibility eligible candidate] for the GSoC program.&lt;br /&gt;
&lt;br /&gt;
This page lists project ideas developed by the LimeSurvey Community. These tend to be areas that will get the most support as projects since they have been developed by people who know the project and what it needs the most. &#039;&#039;&#039;However&#039;&#039;&#039;, if you have your own idea for a project discuss your awesome idea with us in our [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/catid,11/id,24710/lang,en/ forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing list] or at #limesurvey on irc.freenode.net. Then submit &#039;&#039;&#039;your&#039;&#039;&#039; proposal. Good Luck (:biggrin:)&lt;br /&gt;
&lt;br /&gt;
=Project ideas=&lt;br /&gt;
&lt;br /&gt;
==Example Format...==&lt;br /&gt;
&lt;br /&gt;
Describe the idea here in general terms&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain what sort of coding skills would be needed for a student to implement this project&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Explain the level of difficulty involved&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Put your name (and tag) here if you are willing to mentor a student for this idea&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: File Upload question type==&lt;br /&gt;
&lt;br /&gt;
The idea is to have a question type in LimeSurvey1 where survey participants can upload one (or more) files. Often in surveys the participant is asked to create some content (pictures, movies, documents, etc.)  to upload as an answer to a question. The following goals are  primary in this task:&lt;br /&gt;
*Easy handling for the participant (uploading one or more files should be a piece of cake - also removing files if accidentally the wrong file was uploaded)&lt;br /&gt;
*Extensive configuration options for the question type like&lt;br /&gt;
**How many files are required, minimum and maxim number of files,&lt;br /&gt;
**maximum/minimum upload size,&lt;br /&gt;
**Allowed file types&lt;br /&gt;
*Safe!! storage in the file system, checks for file contents&lt;br /&gt;
*Implementation in statistics / data entry / printable survey / response browsing / response editing &amp;amp; RemoteControl&lt;br /&gt;
*Administrator can download one or more files (zip-packaging files for download) from one response and across responses&lt;br /&gt;
*Provide possible hooks for third party processing tools&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, jQuery, AJAX - existing knowledge on the general idea and related security would be of big advantage&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
c_schmitz (Carsten Schmitz)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 1: Authentication framework==&lt;br /&gt;
&lt;br /&gt;
The idea is to design and implement a generic authentication framework for LimeSurvey 1 as well as some authentication modules. The Authentication framework will make it possible to implement any kind of authentication backend apart from the already existing internal-DB and Web server delegation schemes. Currently authentication is only used for the survey-administration GUI and not the participants interface (tokens are used for this). With the new authentication framework it will be possible to define several authentication backends and use some of them for participants-authentication.&lt;br /&gt;
&lt;br /&gt;
The generic authentication framework must define the following services:&lt;br /&gt;
* User authentication: this interface must return the identity of the authenticated user if authentication is successful.&lt;br /&gt;
** Authentication may not always be based on a simple user/password form, so the proposed framework must be generic enough to enable authentication based on other schemes (using any numbers or GET/POST parameters or any other contextual parameter such as Referrer, session variable...&lt;br /&gt;
* User provisionning:&lt;br /&gt;
** when activated on the survey administration interface, an authentication module might be able to create a newly authenticated user into the LimeSurvey internal DB (which is required for setting the user rights on the platform). The newly created user can be assigned a default profile or a per-user profile (queried from an external database).&lt;br /&gt;
** when activated on the participants interface, the authentication module will provision the token table of the correspoding survey (only if the token for this user has not been already added).&lt;br /&gt;
&lt;br /&gt;
The already existing authentication schemes will be ported to the new framework (internal-DB and Web server authentication delegation) and at least a new one will be implemented (openID, CAS, Shibboleth).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, SQL, Authentication protocols (openID, CAS, LDAP-bind, ...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Medium&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
lemeur (Thibault Le Meur)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Db Storage Engine==&lt;br /&gt;
&lt;br /&gt;
Develop an extensible plugin survey storage engine for LimeSurvey 2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Description&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other than survey design, everything that happens in LimeSurvey centres around the ability to save responses to questions to a database, and retrieve the responses again when required. Historically these functions have been incorporated within the various functions of LimeSurvey and this has locked LimeSurvey to a single methodology for data storage and retrieval and made future modifications and improvements difficult if not possible.&lt;br /&gt;
&lt;br /&gt;
For this project we are looking for students to write a &#039;middleware&#039; that exposes abstract high-level functions to LimeSurvey 2 (e.g.: storing these answers related to this question, running statistical analysis etc.) but is built in top of Cake&#039;s &#039;low-level&#039; operations (such as find, save etc). The aim is to abstract away from a specific DB implementation and provide an intuitive and rich API for LS2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Rationale&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the interface with the data storage system is so critical to practically every other function in LimeSurvey we want to develop a stand-alone module that is transportable and extensible for the future. And by keeping the logic of data and survey storage separate from the rest of LimeSurvey&amp;amp;rsquo;s functions we will the ease with which LimeSurvey can be developed in the long term.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Implementation&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is such an important project that we would consider multiple students undertaking the task. In conjunction with a strong understanding of data structures, php coding and api principles the students would also have to display a capacity to work in a team and with the broader community.&lt;br /&gt;
&lt;br /&gt;
The implementation would focus on becoming a plugin/addon module under CakePHP which uses the default CakePHP database systems to the absolute minimum. In a well implemented version of this proposal only simple SQL inserts, queries and updates would be required. All other logic would be managed by the engine.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Requirements &amp;amp; Considerations&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DB Engine must be able to do the following&lt;br /&gt;
* ease development of additional &#039;&#039;&#039;question types, which will be developed as plugins&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;efficient data retrieval&#039;&#039;&#039;, especially summaries (e.g. display 100 last responses)&lt;br /&gt;
* support &#039;&#039;&#039;generic&#039;&#039;&#039; data storage and retrieval - aside surveys, imagine running online admission tests, polls, sign-up forms, volunteer campaign etc. etc.&lt;br /&gt;
* easily support conditions, looped question, or generally, &#039;&#039;&#039;non-linear data&#039;&#039;&#039;. Think of a survey that asks how many children you have and then asks information about each of them.&lt;br /&gt;
* support questions that have multiple &#039;&#039;&#039;answers and multiple types of answers&#039;&#039;&#039;. Think of a question asking &amp;quot;What is your favourite ice cream?&amp;quot;, offering 3 fixed options and last one allowing user to enter a custom answer.&lt;br /&gt;
* support survey resuming (where applicable)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Field Naming and Database Extensibility Methodologies&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An ongoing debate in the LimeSurvey community has been the method in which the database stores survey results. In LimeSurvey 1 a flat database schema was used whereby once the survey designer had finished setting up the survey a database table was created with a field for every individual question/answer combination. The advantages of this database schema were speed of retrieval for reporting and exporting and searching. The disadvantages were that the survey system had to &amp;amp;lsquo;freeze&amp;amp;rsquo; the structure in place once the table was created (therefore the activate/de-activate rules in LimeSurvey 1). The single table method doesn&amp;amp;rsquo;t allow easy storage of metadata for individual question/answer combinations (such as timestamps). Nor does it lend itself to surveys with enormous quantities of question/answer combinations &amp;amp;ndash; sometimes running up against database limitations regarding the number of fields per table.&lt;br /&gt;
&lt;br /&gt;
An alternative is a &amp;amp;lsquo;normalised&amp;amp;rsquo; database topology where a single table is created to store all survey responses &amp;amp;ndash; one database row per question/answer combination. A related table would store metadata that is directly related to the survey sitting/session rather than the answer (e.g.: username, ip address, geographical location, user demographic). The advantage to this methodology is the increased flexibility (extensible) which would allow modification of surveys at any stage even after data has been collected (see requirements). The disadvantages are that searching and compilation of data is complicated and resource intensive.&lt;br /&gt;
&lt;br /&gt;
In a perfect world LimeSurvey would allow users to choose either methodology &amp;amp;ndash; either at an installation level or even on a per-survey level.&lt;br /&gt;
&lt;br /&gt;
Having a database storage engine effectively acting as an API would allow this functionality to be built, but the choice of database topology would be invisible to the related LimeSurvey functions that require data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Database Schema Design, Sound knowledge of Algorithms and Data Structures&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
jasebo (Jason Cleeland)&lt;br /&gt;
&lt;br /&gt;
macduy (Mac Duy Hai)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Template Editor==&lt;br /&gt;
&lt;br /&gt;
Limesurvey 2 needs a nice and powerful template editor so everyone can create a template which matches their requirements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
One needs to know about the details of the [http://dwoo.org/ dwoo template engine] which is used at LS2. There is some cakePHP coding needed to create an interface and write changes to the template files as well as some HTML/CSS to create a nice interface.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You don&#039;t have to create difficult algorithms for this task. It&#039;s useful if you have worked with templates for another web-application or take a detailled look at [http://docs.limesurvey.org/tiki-index.php?page=Themes%3A+Templates+and+Styles&amp;amp;structure;=English+Instructions+for+LimeSurvey how templates work in Limesurvey]. Some design/usability background would be nice but is not a must.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mazi&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Mini-projects==&lt;br /&gt;
&lt;br /&gt;
Mini-projects is a collection of small-to-medium sized projects, which you mix-and-match according to your tastes. Heck, you can even roll your own idea and once reviewed and approved, you can code away. Some recommended/important mini-projects and their brief descriptions:&lt;br /&gt;
*&#039;&#039;&#039;Smarter installer:&#039;&#039;&#039; LS2.0 comes with its own installer, though it may not be the friendliest to use. Your task is to make it juicier to use:&lt;br /&gt;
** Resume installation - if the user aborts the installation mid-way, make it easy for him to resume it&lt;br /&gt;
** Better error handling - meaningful error reports, suggestions how to fix them: e.g. &amp;quot;Database does not exist&amp;quot; is better than &amp;quot;Database error&amp;quot;&lt;br /&gt;
** Customization - invite the user to customize his installation of LimeSurvey - from security settings such as salt, to interface such as the header title.&lt;br /&gt;
*&#039;&#039;&#039;User management:&#039;&#039;&#039; When the number of users grow, it becomes increasingly harder to manage them. Implement functionality and provide interface for features that would make this task easier. Inspire yourself by the big players, such as the infamous you-know-which-one social website.&lt;br /&gt;
**&#039;&#039;&#039;Groups within groups:&#039;&#039;&#039; LS2 users can belong to a group, but groups cannot belong to other groups.&lt;br /&gt;
**&#039;&#039;&#039;Contact lists:&#039;&#039;&#039; There is already something called AssignmentGroups. Study this concept carefully and generalize to a Contact List&lt;br /&gt;
**&#039;&#039;&#039;GUI:&#039;&#039;&#039; Design a GUI which allows you easily manage users, groups and contact lists.&lt;br /&gt;
**&#039;&#039;&#039;Searching:&#039;&#039;&#039; Provide an efficient but simple-to-use search interface and functionality&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, JavaScript &amp;amp; jQuery&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mac Duy Hai (macduy)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Template/Theme Editor==&lt;br /&gt;
&lt;br /&gt;
The idea is to develop a theme / template framework similar to one in jquery [http://jqueryui.com/themeroller/ | Jquery Theme Roller] and thus making the UI design of the surveys easier.The current template editor is based on dwoo template engine which actually loads the files exposing the css etc for us to edit, which of course require some skill set to proceed. Using this template editor we can make everything UI based and thus requiring no developer skills to edit the templates.&lt;br /&gt;
&lt;br /&gt;
The overview of the modules can be seen here:&lt;br /&gt;
&lt;br /&gt;
[[File:theme_roller.png]]&lt;br /&gt;
&lt;br /&gt;
It&amp;amp;rsquo;ll be implemented using Jquery to use the more advanced UI experiences.(:biggrin:)&lt;br /&gt;
&lt;br /&gt;
The following mock-up will give us a better view:&lt;br /&gt;
&lt;br /&gt;
Moderate[[File:theme_editor_small.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, CSS, AJAX, JavaScript &amp;amp; jQuery.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Lime Survey Social - Facebook Application==&lt;br /&gt;
&lt;br /&gt;
The idea aims at developing a Facebook app which gives a social touch to LS 2.0. The application will be integrated in several Facebook integration points like News Feed, Applications boxes, Wall etc so that the user participation will be more. Adding a social touch can drive us more user participation and increase the popularity. The ability to control the Facebook app can be provided in the LS2.0 Admin Dashboard and also in the FB user application window with varied options.&lt;br /&gt;
&lt;br /&gt;
The facebook has the following modules (we can add more. This is primary draft.)&lt;br /&gt;
*All Survey related core features. (Create, Edit, Delete, Administer etc)&lt;br /&gt;
*Gain reward points.&lt;br /&gt;
*Use reward points to create more surveys.&lt;br /&gt;
*Spread the surveys ...... and more&lt;br /&gt;
&lt;br /&gt;
The idea can be extended to other social networks&lt;br /&gt;
&lt;br /&gt;
[[File:fb_overview.png]]&lt;br /&gt;
&lt;br /&gt;
The mock-ups :&lt;br /&gt;
&lt;br /&gt;
[[File:facebook app.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:canvas.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Facebook API.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Integration of Poll Questions==&lt;br /&gt;
&lt;br /&gt;
Polls are one of the most popular and quick response getting tools once can use. Implementing polls in LS 2.0 will be an added advantage. Since every one of us know what polls are about, this idea focuses on the implementation part.&lt;br /&gt;
&lt;br /&gt;
The idea is to integrate the ability to create a POLL Module in Admin dashboard, where he can administer (Create | Edit | Delete | View Responses etc) the Polls.We can even get feedback &amp;amp;ldquo;about the survey&amp;amp;rdquo; at the end on how the user feels by creating a custom poll (we can even redirect the user to this poll).&lt;br /&gt;
*Chat Bots and Polls: An another idea is to create chat bots so that whenever we create a poll, all the friends (who added the bot) of that bot will be pinged by the question followed by options. Getting an answer is very easy (Bot friends just need to type a single letter stating the answer) and its a push model which ensures the delivery to everyone (even offline).We can even extend this to deliver certain type of surveys question by question through the bot.&lt;br /&gt;
&lt;br /&gt;
A simple mock-up for this:&lt;br /&gt;
&lt;br /&gt;
[[File:chat.png]]&lt;br /&gt;
*Alternate Solution: An alternate solution provided by Mazi is clubbing this idea with the Facebook app idea. Instead of porting parts of the admin backend to facebook or other social networks we&#039;ll have options in Admin panel to &amp;quot;publish as: common survey |mobile device survey | facebook poll | homepage poll |  ... etc &amp;quot; Everything will be put together at the usualm admin backend but you can choose which way(s) you want publish your survey.&lt;br /&gt;
&lt;br /&gt;
We can further extend this idea by giving additional options to publish as widgets for websites and blogs etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, XMPP Protocol (Knowledge of developing bots), Knowledge of Polls.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Survey Community Project==&lt;br /&gt;
&lt;br /&gt;
Build a system for LS2 that connects to a central repository of survey resources, such as demographic questions, answer styles and templates. Integrating with a login system, allow LimeSurvey users to easily publish their work to a community resource or use other published works from the same location.&lt;br /&gt;
&lt;br /&gt;
For many finding already written question texts, or standardised demographic questions would really simplify their use of a survey tool. LimeSurvey could leverage on the community spirit of an open source product and encourage users to share their own work. By integrating a &amp;quot;Publish to the LimeSurvey Library&amp;quot; button in the administration system with questions, or templates, or anything else that can be shared, LimeSurvey could develop a library of tools that simplifies Survey Creation even further.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, Web and User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moderate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jason Cleeland (jasebo)&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey 2: Condition Engine==&lt;br /&gt;
&lt;br /&gt;
[[File:addNewCondition1.png]]&lt;br /&gt;
&lt;br /&gt;
Build a system for LS2 that will let survey administrators design, store and evaluate conditions. Conditions can be used in several features such as question branching (survey logic), assessments, quotas, ...&lt;br /&gt;
&lt;br /&gt;
This projects will at least end up with:&lt;br /&gt;
* A working GUI to design complex conditions:&lt;br /&gt;
** several atomic conditions can be combined by AND or OR logical operators and will support for grouping conditions with parentheses&lt;br /&gt;
** an atomic condition representation can be&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&amp;lt;left operand&amp;gt; &amp;lt;operator&amp;gt; &amp;lt;right operand&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** an atomic condition editor will implement&lt;br /&gt;
*** several operators (equality, inequality, string-comparisons, numerical-comparisons, regexp),...&lt;br /&gt;
*** meta operators surch as &#039;Not displayed&#039;&lt;br /&gt;
** left and right operands can be answers from previous questions, or a static values. It should be extensible so that we are able in the future to use more complex operand such as the result of a specific function (for instance the sum of some previous integer questions)&lt;br /&gt;
* A working DB storage backend using a string in [http://en.wikipedia.org/wiki/Reverse_Polish_Notation RPN] (Reverse Polish Notation) to describe each condition&lt;br /&gt;
* A first version of the evaluation of conditions for the question branching feature. This part will require interaction with other parts of the projects (Survey Engine, and DB engine).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Skills&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PHP, CakePHP, JQuery and User Interface Design Skills&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Difficulty&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
High&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Probable Mentors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Thibault Le Meur (lemeur)&lt;br /&gt;
&lt;br /&gt;
=We want your ideas!=&lt;br /&gt;
&lt;br /&gt;
What floats your boat? Do you have another idea that gets you excited? Discuss your ideas in our [http://www.limesurvey.org/component/option,com_fireboard/Itemid,105/func,view/catid,11/id,24710/lang,en/ forums], [https://lists.sourceforge.net/lists/listinfo/limesurvey-developers mailing lists] or at #limesurvey on irc.freenode.net.&lt;br /&gt;
&lt;br /&gt;
=More Information=&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Google&#039;s Summer of Code 2009==&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2009 Limesurvey GSoC 2009]&lt;br /&gt;
&lt;br /&gt;
An introduction to LimeSurvey and our application for this years Google Summer of Code&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started How to get started with LimeSurvey&#039;s GSoC 2009]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
==Frequently Asked Questions==&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google&#039;s Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2007</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2007"/>
		<updated>2010-03-16T00:54:56Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is applying to be involved in the Google Summer of Code for 2010&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
The timelineline can be found [http://socghop.appspot.com/document/show/gsoc_program/google/gsoc2010/faqs#timeline here].&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Limesurvey is loved and used by many Universities, Students, Medical Institutes, non-profit organisations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provide LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been directly downloaded from Sourceforge over &#039;&#039;&#039;130,000 times&#039;&#039;&#039; in the last 12 months alone, and is also distributed as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, and included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognised as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;. LimeSurvey was succesful in being selected as a mentoring organisation for the Google Summer of Code in 2009.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source online survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionise online survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2010, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;File upload question type in LimeSurvey 1&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Marcel Minke&amp;lt;/center&amp;gt; &amp;lt;center&amp;gt;[http://docs.limesurvey.org/tiki-index.php?page=UserPage Mazi||Mazi]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Template editor?&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Mac Duy Hai&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;[[UserPage macduy||macduy]]&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Database Storage Engine, Mini-projects&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Thibault Le Meur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;lemeur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Engine&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2015</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2015"/>
		<updated>2010-02-18T00:19:00Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is applying to be involved in the Google Summer of Code for 2010&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://code.google.com/opensource/gsoc/2009/faqs.html FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Limesurvey is loved and used by many Universities, Students, Medical Institutes, non-profit organisations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provide LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been directly downloaded from Sourceforge over &#039;&#039;&#039;130,000 times&#039;&#039;&#039; in the last 12 months alone, and is also distributed as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, and included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognised as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;. LimeSurvey was succesful in being selected as a mentoring organisation for the Google Summer of Code in 2009.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source online survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionise online survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2009, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Currently Thinking About It&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Thinking About New Ideas&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2016</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2016"/>
		<updated>2010-02-18T00:18:37Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is applying to be involved in the Google Summer of Code for 2010&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://code.google.com/opensource/gsoc/2009/faqs.html FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Limesurvey is loved and used by many Universities, Students, Medical Institutes, non-profit organisations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provide LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been directly downloaded from Sourceforge over &#039;&#039;&#039;130,000 times&#039;&#039;&#039; in the last 12 months alone, and is also distributed as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, and included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognised as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;. LimeSurvey was succesful in being selected as a mentoring organisation for the Google Summer of Code in 2009.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source online survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionise online survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2009, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Currently Thinking About It&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Thinking About New Ideas&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2017</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2017"/>
		<updated>2010-02-17T23:43:54Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is applying to be involved in the Google Summer of Code for 2010&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2010 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2010&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2010]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://code.google.com/opensource/gsoc/2009/faqs.html FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Limesurvey is loved and used by many Universities, Students, Medical Institutes, non-profit organisations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provide LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been downloaded from Sourceforge over &#039;&#039;&#039;100,000 times&#039;&#039;&#039; in the last year, and is included as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, as well as being included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognised as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source online survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionise online survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2009, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Currently Thinking About It&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Thinking About New Ideas&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2018</id>
		<title>LimeSurvey GSoC 2010</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2010&amp;diff=2018"/>
		<updated>2010-02-17T23:43:16Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2010=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is applying to be involved in the Google Summer of Code for 2010&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2010 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was accepted as a mentoring organisation for the first time in 2009, and is hopeful and excited about he opportunity to participate again in 2010. We plan to give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
Find out more about our program in 2009 at [http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2009&amp;amp;structure;=LimeSurvey+Development LimeSurvey GSoC 2009]&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get a stipend from Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://code.google.com/opensource/gsoc/2009/faqs.html FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Limesurvey is loved and used by many Universities, Students, Medical Institutes, non-profit organisations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provide LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been downloaded from Sourceforge over &#039;&#039;&#039;100,000 times&#039;&#039;&#039; in the last year, and is included as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, as well as being included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognised as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source online survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionise online survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC student like yourself to get involved early in a project that has a strong history and an even stronger future. Our community is welcoming and fun. One of our students from 2009 has now become the project lead for LimeSurvey 2. It&#039;s a classic case of the student becoming a master!&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 ideas page] and see if any idea interests you. If you have an idea of your own, then develop it. If any idea excites you, and you want to implement that feature during the summer of 2009, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it. Come and join us on the IRC channel on freenode (#limesurvey) and talk about what you want to do.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2010 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Currently Thinking About It&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Thinking About New Ideas&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2010 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2009&amp;diff=1998</id>
		<title>LimeSurvey GSoC 2009</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2009&amp;diff=1998"/>
		<updated>2009-10-24T17:04:03Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2009=&lt;br /&gt;
&lt;br /&gt;
This year LimeSurvey is hosting three Google Summer of Code students.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;[[Google Summer of Code 2009 - Wrapup]]&#039;&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;[[UserPage macduy|Mac Duy Hai]]&#039;&#039;&#039; (macduy)- &#039;&#039;&#039;[[GSOC09 dashboard project]]&#039;&#039;&#039;==&lt;br /&gt;
* Mentors: [[UserPage c_schmitz|Carsten Schmitz]] (c_schmitz), [[UserPage cwittenb|Carsten Wittenberg]] (cwittenb)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Title:&#039;&#039;&#039;LimeSurvey2 Dashboards for Administrators&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Abstract:&#039;&#039;&#039; Aim of the project is to create a widget-based customisable dashboard for LimeSurvey2 administrators, allowing them to get an overview of any information inside LimeSurvey2. The widgets, from which the dashboard is constructed from, will be customizable, interactive, reusable and have a consistent design (see mockup: http://www.flickr.com/photos/macduy/3401513176/)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;[[UserPage dqminh|Dao Quang Minh]]&#039;&#039;&#039; (dqminh)- &#039;&#039;&#039;[[GSOC09 statistics project]]&#039;&#039;&#039;==&lt;br /&gt;
* Mentors: [[UserPage jcleeland|Jason Cleeland]] (jasebo), [[UserPage Mazi|Marcel Minke]] (Mazi)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Title:&#039;&#039;&#039; Survey Statistics Module&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Abstract:&#039;&#039;&#039; Limesurvey is a tool for data collection and not a tool for data analysis. A general overview is very helpful for users who don&#039;t want to use expensive tools for data evaluation.&lt;br /&gt;
* Extend the question type plugins so they can deliver methods for computing a result summary&lt;br /&gt;
* Create a report generator so users can put together their own reports with their own graphs or let a wizard do it&lt;br /&gt;
* Establish filter properties so user can filter results to a certain scope&lt;br /&gt;
&lt;br /&gt;
=LimeSurvey Summer of Code (Google Summer of Code Associated Projects)=&lt;br /&gt;
&lt;br /&gt;
The following students are completing their proposals although not formally part of the Google Summer of Code project. In all other respects, they are working to the same guidelines and rules. LimeSurvey welcomes and thanks them.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;[[UserPage honglianglv|Hongliang Lv]]&#039;&#039;&#039; (honglianglv) - &#039;&#039;&#039;LSOC09[[Web Service Project]]&#039;&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Title&#039;&#039;&#039;: Create a web service Interface&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Abstract:&#039;&#039;&#039; We like to have web service interfaces in LimeSurvey 2. This gets very handy if you want to connect other Programms with LimeSurvey. Especially if they are not written in PHP. If the Interface could support REST messages in addition to SOAP. The interface would be wider accepted by other developers and potential users. And the Results API can be also thought as a web service!&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2009 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is excited about our participation in the program and have been accepted as mentoring organization for the &#039;&#039;&#039;Google Summer of Code 2009&#039;&#039;&#039;. We&#039;ll give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
[[File:2009socwithlogo.gif]]&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get paid by Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://code.google.com/opensource/gsoc/2009/faqs.html FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Limesurvey is loved and used by many Universities, Students, Medical Institutes, non-profit organisations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provide LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been downloaded from Sourceforge over &#039;&#039;&#039;100,000 times&#039;&#039;&#039; in the last year, and is included as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, as well as being included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognised as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source online survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionise online survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC Jedi like yourself to get involved early in a project that has a strong history and an even stronger future.&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 ideas page] and see if any idea interests you. If any idea excites you, and you want to implement that feature during the summer of 2009, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2009 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Thibault Le Meur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;lemeur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Handling, Authorization API&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Handling, Statistics, Results API, Question Type&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Statistics, Dashboard, Question type, Multilingual Surveys &amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Wittenberg&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;cwittenb&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Interface Design&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Marcel Minke&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Mazi&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;LimeSurvey Offline with Google Gears&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Josef Prandstetter&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;ElMatador69&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;LimeSurvey Offline with Google Gears&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Tim Wahrendorff&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;rakete&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Webservice Interface&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;br /&gt;
&lt;br /&gt;
===Death by Survey===&lt;br /&gt;
* [Death by Survey]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Google_Summer_of_Code_2009_-_Wrapup&amp;diff=1400</id>
		<title>Google Summer of Code 2009 - Wrapup</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Google_Summer_of_Code_2009_-_Wrapup&amp;diff=1400"/>
		<updated>2009-09-11T01:57:46Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&#039;&#039;&#039;Google&amp;amp;rsquo;s Summer of Code 2009 at LimeSurvey&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
LimeSurvey was chosen in 2009 to participate in the Google Summer of Code program. It was our first experience at the program and so we approached it with a huge deal of excitement, trepidation and hopeful anticipation. The timing was particularly good as it allowed us to put some additional impetus into the development of our second generation version of LimeSurvey, which is being built from the ground up and represents a large jump from the initial version.&lt;br /&gt;
&lt;br /&gt;
We received around 50 applications from students with development proposals for LimeSurvey 2. Ultimately Google offered to fund 3 placements, which we duly filled with our 3 best student applications. While one of our students did not complete the placement, we rate the years involvement in GSoC as an outstanding success and we&amp;amp;rsquo;re very pleased with the outcomes both in terms of code development and the introduction of new developers to the project team.&lt;br /&gt;
&lt;br /&gt;
Our two successfully completed projects were:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mac Duy Hai&amp;amp;rsquo;s Dashboard Project&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This project aimed to create a widget-based customisable dashboard for LimeSurvey2 administrators, allowing them to get an overview of any information inside LimeSurvey2. The widgets, from which the dashboard is constructed from, would be customizable, interactive, reusable and have a consistent design.&lt;br /&gt;
&lt;br /&gt;
Here is a screenshot of Hai&amp;amp;rsquo;s finished work&lt;br /&gt;
&lt;br /&gt;
[[File:macduyhai.png]]&lt;br /&gt;
&lt;br /&gt;
One of the main criticisms of LimeSurvey version 1 has been the administrative interface. Hai&#039;s great work on the administrative dashboard will serve LimeSurvey 2 development well for years to come.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;(Daniel) Dao Quanh Minh&amp;amp;rsquo;s Statistics Project&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This project aimed to make the statistics module as functional as (or richer in terms of functionalities and usabiltities than) LimeSurvey 1.x. The new statistic module would also support question type developers and enable them to customize what attributes should be used for statistical report.&lt;br /&gt;
&lt;br /&gt;
Daniel&amp;amp;rsquo;s project ran into some hurdles from the beginning, as Daniel discovered various limitations in the existing question modules. Showing great initiative, he was able to recognise the importance of the question module/structure to the rest of the project and worked on this area for the first term. Daniel was able to bring his project back on track in the second semester, and although the full scope of the original proposal wasn&amp;amp;rsquo;t met, he was able to meet the revised targets with aplomb. Daniel has provided LimeSurvey 2 with the fundamental statistics structure that was originally envisaged and this will be of great advantage to our future development.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lessons Learned&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As a first timer in GSoC, we faced a very steep learning curve this year &amp;amp;ndash; and it&amp;amp;rsquo;s probable that we weren&amp;amp;rsquo;t able to perform as well as possible as a result. There is not a lot in the way of guidelines for new organisations, and so we managed the best we could.&lt;br /&gt;
&lt;br /&gt;
What worked very well for us was requiring our students to report regularly to our weekly developer meetings. Emails to the developer group were not as frequent as I would have liked, and this is something I will emphasise in future years. The smaller number of the development team who have been actively involved in coding our new version also meant that there probably wasn&#039;t as much of a sounding board for the students as they would have liked. This problem will resolve itself over the next year or so as development and developers move into version 2.&lt;br /&gt;
&lt;br /&gt;
Our students were very active in our IRC channel and our online forums, and I think this really helped them get a good grounding in the wider LimeSurvey community.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is hugely grateful to both Google for sponsoring this wonderful event, and to our students.&lt;br /&gt;
&lt;br /&gt;
Our students have remained active with the project since completion, and Hai is taking an ongoing development role in LimeSurvey 2.&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2009&amp;diff=1999</id>
		<title>LimeSurvey GSoC 2009</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=LimeSurvey_GSoC_2009&amp;diff=1999"/>
		<updated>2009-09-08T23:38:48Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code 2009=&lt;br /&gt;
&lt;br /&gt;
This year LimeSurvey is hosting three Google Summer of Code students.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;[[Google Summer of Code 2009 - Wrapup]]&#039;&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;[[UserPage macduy|Mac Duy Hai]]&#039;&#039;&#039; (macduy)- &#039;&#039;&#039;[[GSOC09 dashboard project]]&#039;&#039;&#039;==&lt;br /&gt;
* Mentors: [[UserPage c_schmitz|Carsten Schmitz]] (c_schmitz), [[UserPage cwittenb|Carsten Wittenberg]] (cwittenb)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Title:&#039;&#039;&#039;LimeSurvey2 Dashboards for Administrators&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Abstract:&#039;&#039;&#039; Aim of the project is to create a widget-based customisable dashboard for LimeSurvey2 administrators, allowing them to get an overview of any information inside LimeSurvey2. The widgets, from which the dashboard is constructed from, will be customizable, interactive, reusable and have a consistent design (see mockup: http://www.flickr.com/photos/macduy/3401513176/)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;[[UserPage dqminh|Dao Quang Minh]]&#039;&#039;&#039; (dqminh)- &#039;&#039;&#039;[[GSOC09 statistics project]]&#039;&#039;&#039;==&lt;br /&gt;
* Mentors: [[UserPage jcleeland|Jason Cleeland]] (jasebo), [[UserPage Mazi|Marcel Minke]] (Mazi)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Title:&#039;&#039;&#039; Survey Statistics Module&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Abstract:&#039;&#039;&#039; Limesurvey is a tool for data collection and not a tool for data analysis. A general overview is very helpful for users who don&#039;t want to use expensive tools for data evaluation.&lt;br /&gt;
* Extend the question type plugins so they can deliver methods for computing a result summary&lt;br /&gt;
* Create a report generator so users can put together their own reports with their own graphs or let a wizard do it&lt;br /&gt;
* Establish filter properties so user can filter results to a certain scope&lt;br /&gt;
&lt;br /&gt;
=LimeSurvey Summer of Code (Google Summer of Code Associated Projects)=&lt;br /&gt;
&lt;br /&gt;
The following students are completing their proposals although not formally part of the Google Summer of Code project. In all other respects, they are working to the same guidelines and rules. LimeSurvey welcomes and thanks them.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;[[UserPage honglianglv|Hongliang Lv]]&#039;&#039;&#039; (honglianglv) - &#039;&#039;&#039;LSOC09[[Web Service Project]]&#039;&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Title&#039;&#039;&#039;: Create a web service Interface&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Abstract:&#039;&#039;&#039; We like to have web service interfaces in LimeSurvey 2. This gets very handy if you want to connect other Programms with LimeSurvey. Especially if they are not written in PHP. If the Interface could support REST messages in addition to SOAP. The interface would be wider accepted by other developers and potential users. And the Results API can be also thought as a web service!&lt;br /&gt;
&lt;br /&gt;
=General Information=&lt;br /&gt;
&lt;br /&gt;
Google has been continuously supporting Open Source Projects and students coming together since 2005 through its &#039;&#039;Google Summer of Code Programs&#039;&#039;. GSoC 2009 has been announced and is On!&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is excited about our participation in the program and have been accepted as mentoring organization for the &#039;&#039;&#039;Google Summer of Code 2009&#039;&#039;&#039;. We&#039;ll give students an excellent environment and platform to &#039;&#039;&#039;learn&#039;&#039;&#039; and most importantly to have &#039;&#039;&#039;fun&#039;&#039;&#039; (:lol:)!&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey community, at the same time, will benefit by students&#039; participation and fresh eyes and ideas.&lt;br /&gt;
&lt;br /&gt;
==Google Summer of Code Program Information==&lt;br /&gt;
&lt;br /&gt;
[[File:2009socwithlogo.gif]]&lt;br /&gt;
&lt;br /&gt;
Google Summer of Code is a great program both for Open Source organizations like LimeSurvey as well as students because it gives a platform where several tasks on Open Source Projects are done by students and students in return get paid by Google.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a lot more information available in Google&#039;s Summer of Code [http://code.google.com/opensource/gsoc/2009/faqs.html FAQ] and [http://code.google.com/p/google-summer-of-code/ Knowledge Base]. You can also join #gsoc on irc.freenode.net to get feedback or ask questions about Google Summer of Code in real time.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Specific Information==&lt;br /&gt;
&lt;br /&gt;
Welcome to the LimeSurvey Community (:biggrin:). LimeSurvey is an open source survey engine that allows people to create and deploy surveys (from marketing to academic to engineering applications). LimeSurvey is written in PHP and used by many high profile organizations including [https://wiki.ubuntu.com/ServerTeam &#039;&#039;&#039;Ubuntu Server Team&#039;&#039;&#039;], [http://foundation.gnome.org/ &#039;&#039;&#039;GNOME Foundation&#039;&#039;&#039;] and [http://www.vorarlberg.at/ &#039;&#039;&#039;Office of the Austrian Vorarlberg State Government&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Limesurvey is loved and used by many Universities, Students, Medical Institutes, non-profit organisations, marketing companies and more around the world. In the 2004 &#039;&#039;&#039;U.S. presidential election&#039;&#039;&#039;, the [http://www.verifiedvoting.org/article.php?id=5207 &#039;&#039;&#039;Verified Voting Foundation&#039;&#039;&#039;] used PHPSurveyor (as LimeSurvey was then known) to gather data about voting irregularities. Sourceforge provide LimeSurvey as a free application for open source projects. LimeSurvey keeps turning up in new places.&lt;br /&gt;
&lt;br /&gt;
It&#039;s loved because it is free, flexible and constantly improving. It&#039;s constantly improving because it has a dedicated and committed team of developers who love the challenge and satisfaction of using and building such a tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is widely used. It has been downloaded from Sourceforge over &#039;&#039;&#039;100,000 times&#039;&#039;&#039; in the last year, and is included as a package in the &#039;&#039;&#039;Ubuntu Linux Distribution&#039;&#039;&#039;, as well as being included as a pre-installed application in many standard Web Hosting packages (such as &#039;&#039;&#039;Fantastico&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is recognised as a leader in its field. On November 29, 2007 LimeSurvey won the &#039;&#039;&#039;1st prize award&#039;&#039;&#039; at the [http://www.trophees-du-libre.org/index.php?lang=en &#039;&#039;&#039;Les Troph&amp;amp;eacute;es du Libre&#039;&#039;&#039;] contest in the category Corporate Management. In 2008 LimeSurvey was nominated in the category Best Project for the Enterprise in the SourceForge.net &#039;&#039;&#039;Community Choice Awards 2008&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey is the biggest, most active and most exciting open source online survey project, and we&#039;re building on our success by creating a whole new version of the tool.&lt;br /&gt;
&lt;br /&gt;
LimeSurvey Version 2 is a whole new - built from the ground-up - version that will revolutionise online survey design and use.&lt;br /&gt;
&lt;br /&gt;
More importantly, it&#039;s a perfect opportunity for a GSoC Jedi like yourself to get involved early in a project that has a strong history and an even stronger future.&lt;br /&gt;
&lt;br /&gt;
==GSoC Student Aspirants==&lt;br /&gt;
&lt;br /&gt;
Please visit our [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 ideas page] and see if any idea interests you. If any idea excites you, and you want to implement that feature during the summer of 2009, see how you can [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started get started] on it.&lt;br /&gt;
&lt;br /&gt;
==LimeSurvey Mentors==&lt;br /&gt;
&lt;br /&gt;
The following mentors are willing to Mentor students during Google Summer of Code 2009 program.&lt;br /&gt;
&lt;br /&gt;
Others who are willing to mentor can write their name and details below along with the Idea they are willing to mentor. &#039;&#039;&#039;Potential Mentors, please do not forget to put your ideas on the [http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 ideas page] and contact [mailto:jason@cleeland.org| program administrator]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&amp;lt;center&amp;gt;&#039;&#039;&#039;Mentor Name&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Nick&#039;&#039;&#039;&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;&#039;&#039;&#039;Idea&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Thibault Le Meur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;lemeur&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Handling, Authorization API&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Jason Cleeland&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;jasebo&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Condition Handling, Statistics, Results API, Question Type&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;c_schmitz&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Statistics, Dashboard, Question type, Multilingual Surveys &amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Carsten Wittenberg&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;cwittenb&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Interface Design&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Marcel Minke&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Mazi&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;LimeSurvey Offline with Google Gears&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Josef Prandstetter&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;ElMatador69&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;LimeSurvey Offline with Google Gears&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;center&amp;gt;Tim Wahrendorff&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;rakete&amp;lt;/center&amp;gt;||&amp;lt;center&amp;gt;Webservice Interface&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=GSoC_selection_criteria&amp;diff=1432</id>
		<title>GSoC selection criteria</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=GSoC_selection_criteria&amp;diff=1432"/>
		<updated>2009-03-15T00:07:49Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Google Summer of Code Selection Criteria for LimeSurvey=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey will choose applicants that interest us the most, and we will be using the following criteria when coming to a final decision. Given the limited number of places we will have available, it is important to us to choose carefully.&lt;br /&gt;
&lt;br /&gt;
Please note that the final decision of the LimeSurvey Mentoring Organisation is final and not negotiable; these guidelines are to help you when determining and framing your application.&lt;br /&gt;
&lt;br /&gt;
==What we are looking for?==&lt;br /&gt;
* Functionality&lt;br /&gt;
&lt;br /&gt;
Our current focus for LimeSurvey 2 is to achieve a basic level of functionality as an online survey tool. Version 1.8 has a large number of features, and LimeSurvey 2 needs to match version 1 in order to be a logical upgrade path for 1.8 users.&lt;br /&gt;
&lt;br /&gt;
Students who propose ideas that will improve the basic feature set of LimeSurvey 2 will be high on our list of priorities.&lt;br /&gt;
* Originality or Clarity&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 2 needs to be as feature rich as LimeSurvey 1, but it&#039;s the beginning of a new phase for LimeSurvey. Original ideas will count during the selection process. Where an idea is not original, clarity will be an equivalent alternative. If an application shows a clear and definitive understanding of its purpose and place within LimeSurvey, we&#039;ll be interested.&lt;br /&gt;
* Achievability&lt;br /&gt;
&lt;br /&gt;
We need to be convinced that you&#039;re capable of achieving the idea that you propose.&lt;br /&gt;
&lt;br /&gt;
As part of your application make sure that you think carefully about milestones and deliverables. When we assess your application we&#039;ll be looking at these carefully to see if we think they are measurable and achievable. An application with clearly defined milestones that help us understand that path the student intends to take to finish the project will have an advantage over an application with unclear or uncertain milestones.&lt;br /&gt;
* Realism&lt;br /&gt;
&lt;br /&gt;
Coding projects take time, and this is a 2 month window. Your project needs to be something that can be completed in 2 months. If we think your idea is not realistically achievable, we&#039;re not likely to take it on.&lt;br /&gt;
* Ability&lt;br /&gt;
&lt;br /&gt;
To feel confident that you can achieve your proposal, we&#039;ll need to feel confident in your abilities. Tell us about your experience and/or skills with PHP, CakePHP, javascript and jQuery. Give us some examples of projects you&#039;ve completed, or participated in before.&lt;br /&gt;
* Communication&lt;br /&gt;
&lt;br /&gt;
We need to feel confident that you&#039;ll be a good communicator during the course of your project.&lt;br /&gt;
&lt;br /&gt;
==What we are not looking for?==&lt;br /&gt;
&lt;br /&gt;
We&#039;re pretty open to ideas, but since LimeSurvey 2 is a complete rebuild of a fully functioning version 1, naturally we&#039;re going to be more interested in proposals that build core functionality. If you have a great idea that&#039;s a little out of left-wing, feel free to propose it, but it&#039;ll probably need to be outstandingly brilliant to push aside core feature proposals.&lt;br /&gt;
&lt;br /&gt;
What we&#039;re not looking for are applications that are short, show little effort, and do not indicate a serious and real desire to contribute to the LimeSurvey Open Source Project.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
*[http://inkscape.org/wiki/index.php/SOC_Selection_Criteria Selection Criteria]&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
===LimeSurvey Google Summer of Code 2009===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=Limesurvey+GSoC+2009 Limesurvey GSoC 2009]&lt;br /&gt;
&lt;br /&gt;
An introduction to LimeSurvey and our application for this years Google Summer of Code&lt;br /&gt;
&lt;br /&gt;
===Project Ideas Page===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=LimeSurvey+2+Project+Ideas+for+GSOC+2009 GSoC Ideas Page]&lt;br /&gt;
&lt;br /&gt;
The LimeSurvey Community Ideas Page:&lt;br /&gt;
&lt;br /&gt;
- ideas that the community have come up with and would love to help you create&lt;br /&gt;
&lt;br /&gt;
===Getting Started===&lt;br /&gt;
*[http://docs.limesurvey.org/tiki-index.php?page=GSoC_Getting_Started GSoC Getting Started]&lt;br /&gt;
&lt;br /&gt;
How to Get Started With LimeSurvey:&lt;br /&gt;
&lt;br /&gt;
- setting up the development environment, coding standards, and all the other important stuff that you need to know before the real fun begins!&lt;br /&gt;
&lt;br /&gt;
===Frequently Asked Questions===&lt;br /&gt;
* [http://socghop.appspot.com/document/show/program/google/gsoc2009/faqs Google Summer of Code Faqs]&lt;br /&gt;
* [http://docs.limesurvey.org/tiki-index.php?page=GSoC_Faqs LimeSurvey&#039;s GSoC Faqs]&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Open_Design_Manifesto&amp;diff=2255</id>
		<title>Open Design Manifesto</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Open_Design_Manifesto&amp;diff=2255"/>
		<updated>2008-08-29T03:23:32Z</updated>

		<summary type="html">&lt;p&gt;Jcleeland: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
OPEN DESIGN MANIFESTO FOR LIMESURVEY 2&lt;br /&gt;
&lt;br /&gt;
1. Concentrate on your special sauce&lt;br /&gt;
&lt;br /&gt;
95% of a product is non-differentiating. 5% is the special sauce.&lt;br /&gt;
&lt;br /&gt;
Don&amp;amp;rsquo;t reinvent the 95%. Concentrate on the 5%.&lt;br /&gt;
&lt;br /&gt;
2. Build community without destroying individualism&lt;br /&gt;
&lt;br /&gt;
The user&amp;amp;rsquo;s experience and interaction with LimeSurvey 2 is a significant portion of the 5% special sauce. For the core design (the 95% infrastructure), leverage the global creative community for common design elements and solutions. Leverage the millions of eyes in both the customer community and the design team beyond our version 2 product to identify the best solution.&lt;br /&gt;
&lt;br /&gt;
Global eyes on design.&lt;br /&gt;
&lt;br /&gt;
The Open Design Rule Set&lt;br /&gt;
* Choose a license and distribution model (for LS2: GPL).&lt;br /&gt;
* Set your ideas free: publish your designs on SourceForge, LimeSurvey forums, and design.limesurvey.org. Technical implementation is essential.&lt;br /&gt;
* Release early and often. The rapid evolution and exchange of ideas is key to solving complex problems.&lt;br /&gt;
&lt;br /&gt;
Open Design:&lt;br /&gt;
* Builds community without destroying individualism&lt;br /&gt;
* Negotiates decisions between technical, cultural, and style factors&lt;br /&gt;
* Involves everyone as equals: designers, engineers, architects, project managers, customers&lt;br /&gt;
* Uses the collective experience to create better goods and services&lt;br /&gt;
&lt;br /&gt;
This is the survival of the fittest: the best designs win.&lt;br /&gt;
&lt;br /&gt;
Elegant, beautiful designs grow, evolve and prosper.&lt;br /&gt;
&lt;br /&gt;
Shit design withers.&lt;br /&gt;
&lt;br /&gt;
Evolve or perish.&lt;br /&gt;
&lt;br /&gt;
Open Design Mission&lt;br /&gt;
&lt;br /&gt;
Our designs (patterns, scripts, graphics, ideas, docs) will be available to any designer, to any engineer, to any world citizen, to use and modify without restriction.&lt;br /&gt;
&lt;br /&gt;
by Juhan Sonin, juhan@limesurvey.org&lt;br /&gt;
&lt;br /&gt;
Draft 2, 24.Jun.08&lt;/div&gt;</summary>
		<author><name>Jcleeland</name></author>
	</entry>
</feed>