Actions

Workarounds: Manipulating a survey at runtime using Javascript - LimeSurvey 3.0+: Difference between revisions

From LimeSurvey Manual

mNo edit summary
m (Text replacement - " enclose="div"" to "")
 
(5 intermediate revisions by 2 users not shown)
Line 3: Line 3:
Other workarounds can be found at
Other workarounds can be found at
* [[Theme editor|The theme editor - LimeSurvey 3.0+]]
* [[Theme editor|The theme editor - LimeSurvey 3.0+]]
* [[Workarounds: Question design, layout and theme-ing - LimeSurvey 3.0+]]
* [[Workarounds: Survey behaviour - LimeSurvey 3.0+]].
* [[Workarounds: Survey behaviour - LimeSurvey 3.0+]].
* [[Workarounds: Further solutions provided by LimeSurvey users - LimeSurvey 3.0+]]
* [[Workarounds: Further solutions provided by LimeSurvey users - LimeSurvey 3.0+]]
Line 8: Line 9:
<div class="simplebox"><center><br />'''Please keep in mind that these workarounds are not official LimeSurvey extensions - they are solutions that users have created for themselves.<br /><span style='color:#EE0000,#FFFFFF'>Therefore LimeSurvey can't offer guarantees or support for these solutions.</span><br />If you have questions, please contact the users that, thankfully, shared their solutions with the community.'''<br /><br /></center></div>
<div class="simplebox"><center><br />'''Please keep in mind that these workarounds are not official LimeSurvey extensions - they are solutions that users have created for themselves.<br /><span style='color:#EE0000,#FFFFFF'>Therefore LimeSurvey can't offer guarantees or support for these solutions.</span><br />If you have questions, please contact the users that, thankfully, shared their solutions with the community.'''<br /><br /></center></div>


<div class="simplebox">Note:  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, Expression Manager (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.<br /><br /></div>
 
{{Note|'''If you would like to receive survey design support, please contact one of the authorized LimeSurvey partners listed here:''' https://limesurvey.com .}}
 
 
<div class="simplebox">Note:  ExpressionScript (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, ExpressionScript (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.<br /><br /></div>


__TOC__
__TOC__
Line 17: Line 22:


Finally it's imported to mark all your code with code tags, other wise you might break this page.
Finally it's imported to mark all your code with code tags, other wise you might break this page.
*Start tag: '''<nowiki><syntaxhighlight lang="php" enclose="div"></nowiki>'''
*Start tag: '''<nowiki><syntaxhighlight lang="php"></nowiki>'''
*End tag: '''<nowiki></syntaxhighlight></nowiki>'''.
*End tag: '''<nowiki></syntaxhighlight></nowiki>'''.


Line 37: Line 42:
A simple test to see if JavaScript is enabled is to echo an alert. Use this code:
A simple test to see if JavaScript is enabled is to echo an alert. Use this code:


<syntaxhighlight lang="javascript" enclose="div"><script type="text/javascript" charset="utf-8">
<syntaxhighlight lang="javascript"><script type="text/javascript" charset="utf-8">
   alert("Test!");
   alert("Test!");
</script></syntaxhighlight>
</script></syntaxhighlight>
Line 43: Line 48:
It is a good practice to use the jQuery $(document).on('ready pjax:complete') event to prevent the code from executing until the page is fully loaded, it is especially needed when using the ajax-mode in the 3.0.0 and upper default templates:
It is a good practice to use the jQuery $(document).on('ready pjax:complete') event to prevent the code from executing until the page is fully loaded, it is especially needed when using the ajax-mode in the 3.0.0 and upper default templates:


<syntaxhighlight lang="javascript" enclose="div"><script type="text/javascript" charset="utf-8">
<syntaxhighlight lang="javascript"><script type="text/javascript" charset="utf-8">
   $(document).on('ready pjax:complete',function() {
   $(document).on('ready pjax:complete',function() {
       alert("Test!");
       alert("Test!");
Line 50: Line 55:


===Usage of brackets (<nowiki>{ and }</nowiki>)===
===Usage of brackets (<nowiki>{ and }</nowiki>)===
{{Alert|title=Caution when using brackets (<nowiki>{ and }</nowiki>) in scripts|text=[[Expression Manager#Syntax|Expression manager]] uses brackets (<nowiki>{ and }</nowiki>) to enclose expressions. If you have to use brackets in your JavaScript, you must add a space or line feed after the opening bracket (<nowiki>{</nowiki>) and before the closing bracket (<nowiki>}</nowiki>) }}
{{Alert|title=Caution when using brackets (<nowiki>{ and }</nowiki>) in scripts|text=[[ExpressionScript#Syntax|Expression manager]] uses brackets (<nowiki>{ and }</nowiki>) to enclose expressions. If you have to use brackets in your JavaScript, you must add a space or line feed after the opening bracket (<nowiki>{</nowiki>) and before the closing bracket (<nowiki>}</nowiki>) }}


===Examples of usage of brackets===
===Examples of usage of brackets===


Expression Manager will try to parse this JavaScript:  
ExpressionScript will try to parse this JavaScript:  
<syntaxhighlight lang="javascript" enclose="div"><script type="text/javascript" charset="utf-8">
<syntaxhighlight lang="javascript"><script type="text/javascript" charset="utf-8">
   $(function() {console.log('broken javascript');});
   $(function() {console.log('broken javascript');});
</script>
</script>
</syntaxhighlight>
</syntaxhighlight>


Adding line feed prevents Expression Manager from parsing
Adding line feed prevents ExpressionScript from parsing
<syntaxhighlight lang="javascript" enclose="div"><script type="text/javascript" charset="utf-8">
<syntaxhighlight lang="javascript"><script type="text/javascript" charset="utf-8">
   $(function() {
   $(function() {
       console.log('Adding a line feed for javascript');
       console.log('Adding a line feed for javascript');
Line 68: Line 73:
</syntaxhighlight>
</syntaxhighlight>


Expression Manager will try to parse this JavaScript:  
ExpressionScript will try to parse this JavaScript:  
<syntaxhighlight lang="javascript" enclose="div"><script type="text/javascript" charset="utf-8">
<syntaxhighlight lang="javascript"><script type="text/javascript" charset="utf-8">
   if(myvar==1) {console.log('broken javascript');};
   if(myvar==1) {console.log('broken javascript');};
</script>
</script>
</syntaxhighlight>
</syntaxhighlight>


Adding spaces inside the brackets prevents Expression Manager from parsing
Adding spaces inside the brackets prevents ExpressionScript from parsing
<syntaxhighlight lang="javascript" enclose="div"><script type="text/javascript" charset="utf-8">
<syntaxhighlight lang="javascript"><script type="text/javascript" charset="utf-8">
   if(myvar==1) { console.log('Adding a space for javascript'); };
   if(myvar==1) { console.log('Adding a space for javascript'); };
</script>
</script>
</syntaxhighlight>
</syntaxhighlight>
=Array numbers with dropdown answer options=
'''Source''': {https://www.limesurvey.org/es/comunidad/foros/can-i-do-this-with-limesurvey/107401-array-with-drop-down-box-and-numercial-text-value Forum Link}
<syntaxhighlight lang="javascript">
<script type="text/javascript" charset="utf-8">
$(document).on('ready pjax:scriptcomplete',function(){
var thisQuestion = $('#question{QID}');
// Insert selects
$('.answer-item', thisQuestion).append('<select class="inserted-select form-control list-question-select">\
<option value="">Please choose...</option>\
<option value="1">Yes</option>\
<option value="2">No</option>\
<option value="3">Do not know</option>\
</select>'); 
// Listeners
$('.inserted-select', thisQuestion).on('change', function(i) {
if($(this).val() != '') {
$(this).closest('.answer-item').find('input:text').val($.trim($(this).val())).trigger('change');
}
else {
$(this).closest('.answer-item').find('input:text').val('').trigger('change');
}
});
// Returning to page
$('input:text', thisQuestion).each(function(i) {
var thisCell = $(this).closest('.answer-item');
var inputVal = $.trim($(this).val());
$('select.inserted-select', thisCell).val(inputVal);
});
// Clean-up styles
$('select.inserted-select', thisQuestion).css({
'max-width': '100%'
});
$('input:text', thisQuestion).css({
'position': 'absolute',
'left': '-9999em'
});
});
</script>
</syntaxhighlight>
==Array texts with dropdown answers==
'''Example:'''[[Media:Array texts dropdown.zip]]
The code is similar to the one above:
<syntaxhighlight lang="javascript">
<script type="text/javascript" charset="utf-8">
$(document).on('ready pjax:scriptcomplete',function(){
var thisQuestion = $('#question{QID}');
// Insert selects
$('.answer-item', thisQuestion).append('<select class="inserted-select form-control list-question-select">\
<option value="">Please choose...</option>\
<option value="1">Yes</option>\
<option value="2">No</option>\
<option value="3">Do not know</option>\
</select>'); 
// Listeners
$('.inserted-select', thisQuestion).on('change', function(i) {
if($(this).val() != '') {
$(this).closest('.answer-item').find('input:text').val($.trim($('option:selected', this).text())).trigger('change');
}
else {
$(this).closest('.answer-item').find('input:text').val('').trigger('change');
}
});
// Returning to page
$('input:text', thisQuestion).each(function(i) {
var thisCell = $(this).closest('.answer-item');
var inputText = $.trim($(this).val());
var selectval = $('select.inserted-select option', thisCell).filter(function () { return $(this).html() == inputText; }).val();
$('select.inserted-select', thisCell).val(selectval);
});
// Clean-up styles
$('select.inserted-select', thisQuestion).css({
'max-width': '100%'
});
$('input:text', thisQuestion).css({
'position': 'absolute',
'left': '-9999em'
});
});
</script>
</syntaxhighlight>
'''Source''': {https://www.limesurvey.org/es/comunidad/foros/can-i-do-this-with-limesurvey/107401-array-with-drop-down-box-and-numercial-text-value Forum Link}
To be introduced: https://www.limesurvey.org/forum/can-i-do-this-with-limesurvey/92707-list-with-comment-text?q=/en/forum/can-i-do-this-with-limesurvey/92707-list-with-comment-text&start=10#119513

Latest revision as of 15:04, 16 February 2022

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.

Other workarounds can be found at


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



If you would like to receive survey design support, please contact one of the authorized LimeSurvey partners listed here: https://limesurvey.com .


Note: ExpressionScript (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, ExpressionScript (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.

How to add a javascript workaround solution to this Wiki page?

Well, this is pretty easy. Click the edit icon and create your own headline within the javascript section starting with "!". Then add a short note about the version you have used when creating your workaround, you can copy/paste this code snippet ''Tested with: (enter LimeSurvey version and maybe browser)''.

Finally it's imported to mark all your code with code tags, other wise you might break this page.

  • Start tag: <syntaxhighlight lang="php">
  • End tag: </syntaxhighlight>.

How to use Script (eg. JavaScript etc.) in LimeSurvey

Plugin addScriptToQuestion allow to use a simple textarea for easily adding javascript.

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.

  • Go to Global settings --> Security and set "Filter HTML for XSS" to "Off".
  • Add a new question
  • Edit the question and click the "Source" button in the editor toolbar:
  
  • Enter your script after the question text:
  
  • Save the question

A simple test to see if JavaScript is enabled is to echo an alert. Use this code:

<script type="text/javascript" charset="utf-8">
   alert("Test!");
</script>

It is a good practice to use the jQuery $(document).on('ready pjax:complete') event to prevent the code from executing until the page is fully loaded, it is especially needed when using the ajax-mode in the 3.0.0 and upper default templates:

<script type="text/javascript" charset="utf-8">
   $(document).on('ready pjax:complete',function() {
       alert("Test!");
   });
</script>

Usage of brackets ({ and })

  Caution when using brackets ({ and }) in scripts : Expression manager uses brackets ({ and }) to enclose expressions. If you have to use brackets in your JavaScript, you must add a space or line feed after the opening bracket ({) and before the closing bracket (})


Examples of usage of brackets

ExpressionScript will try to parse this JavaScript:

<script type="text/javascript" charset="utf-8">
   $(function() {console.log('broken javascript');});
</script>

Adding line feed prevents ExpressionScript from parsing

<script type="text/javascript" charset="utf-8">
   $(function() {
      console.log('Adding a line feed for javascript');
   });
</script>

ExpressionScript will try to parse this JavaScript:

<script type="text/javascript" charset="utf-8">
   if(myvar==1) {console.log('broken javascript');};
</script>

Adding spaces inside the brackets prevents ExpressionScript from parsing

<script type="text/javascript" charset="utf-8">
   if(myvar==1) { console.log('Adding a space for javascript'); };
</script>

Array numbers with dropdown answer options

Source: {https://www.limesurvey.org/es/comunidad/foros/can-i-do-this-with-limesurvey/107401-array-with-drop-down-box-and-numercial-text-value Forum Link}

<script type="text/javascript" charset="utf-8">
	$(document).on('ready pjax:scriptcomplete',function(){
		var thisQuestion = $('#question{QID}');
 
		// Insert selects
		$('.answer-item', thisQuestion).append('<select class="inserted-select form-control list-question-select">\
													<option value="">Please choose...</option>\
													<option value="1">Yes</option>\
													<option value="2">No</option>\
													<option value="3">Do not know</option>\
												</select>');  
 
		// Listeners
		$('.inserted-select', thisQuestion).on('change', function(i) {
			if($(this).val() != '') {
				$(this).closest('.answer-item').find('input:text').val($.trim($(this).val())).trigger('change');
			}
			else {
				$(this).closest('.answer-item').find('input:text').val('').trigger('change');
			}
		});
 
		// Returning to page
		$('input:text', thisQuestion).each(function(i) {
			var thisCell = $(this).closest('.answer-item');
			var inputVal = $.trim($(this).val());
			$('select.inserted-select', thisCell).val(inputVal);
		});
 
		// Clean-up styles
		$('select.inserted-select', thisQuestion).css({
			'max-width': '100%'
		});
		$('input:text', thisQuestion).css({
			'position': 'absolute',
			'left': '-9999em'
		});
	});
</script>


Array texts with dropdown answers

Example:Media:Array texts dropdown.zip

The code is similar to the one above:

<script type="text/javascript" charset="utf-8">
	$(document).on('ready pjax:scriptcomplete',function(){
		var thisQuestion = $('#question{QID}');
 
		// Insert selects
		$('.answer-item', thisQuestion).append('<select class="inserted-select form-control list-question-select">\
													<option value="">Please choose...</option>\
													<option value="1">Yes</option>\
													<option value="2">No</option>\
													<option value="3">Do not know</option>\
												</select>');  
 
		// Listeners
		$('.inserted-select', thisQuestion).on('change', function(i) {
			if($(this).val() != '') {
				$(this).closest('.answer-item').find('input:text').val($.trim($('option:selected', this).text())).trigger('change');
			}
			else {
				$(this).closest('.answer-item').find('input:text').val('').trigger('change');
			}
		});
 
		// Returning to page
		$('input:text', thisQuestion).each(function(i) {
			var thisCell = $(this).closest('.answer-item');
			var inputText = $.trim($(this).val());
			var selectval = $('select.inserted-select option', thisCell).filter(function () { return $(this).html() == inputText; }).val();
			$('select.inserted-select', thisCell).val(selectval);
		});
 
		// Clean-up styles
		$('select.inserted-select', thisQuestion).css({
			'max-width': '100%'
		});
		$('input:text', thisQuestion).css({
			'position': 'absolute',
			'left': '-9999em'
		});
	});
</script>

Source: {https://www.limesurvey.org/es/comunidad/foros/can-i-do-this-with-limesurvey/107401-array-with-drop-down-box-and-numercial-text-value Forum Link}


To be introduced: https://www.limesurvey.org/forum/can-i-do-this-with-limesurvey/92707-list-with-comment-text?q=/en/forum/can-i-do-this-with-limesurvey/92707-list-with-comment-text&start=10#119513