Welcome to the LimeSurvey Community Forum

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

display secondary options in multiple response questions

  • KompetenzZ
  • KompetenzZ's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
5 years 6 months ago #175775 by KompetenzZ
Hi,

I use this workaround and the available Demo survey to display secondary options in multiple response questions:

manual.limesurvey.org/Workarounds:_Manip..._options.22_question

The workaround is very helpful, many thanks to the developer.

I am using LS 3.14 now and the question built with this workaround shows an unusual behaviour: The secondary answer options are visible by default even if you do not check an answer (the screenshot shows that).
Please, is it possible to change the code in such a way that the secondary options only pop up (become visible) if the associated primary option is checked. In my older verison LS 2.62 the secondary options pop up, such as intended.



Cheers kompetenzz
Attachments:
The topic has been locked.
  • KompetenzZ
  • KompetenzZ's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
5 years 5 months ago #175985 by KompetenzZ
Hi,

sorry to write again on this topic, I don't get any further.
Is it correct to insert the following javascript at the end of custom.js in the theme editor(see screenshot)?
Can someone give me a hint why the code is not working for LimeSurvey version 3.14?


Code:
// A function to handle "secondary" checkboxes
function secondaryCheckboxes(qID, primaryPosition, secondaryCount) {
  // Identify the elements
  var thisQuestion = $('#question'+qID);
  $('div.question-item', thisQuestion).parent().addClass('answer-row');
  var primaryRow = $('div.question-item:eq('+(primaryPosition-1)+')', thisQuestion).closest('.answer-row');
  var primaryInput = $('input.checkbox', primaryRow);
  var secondaryRows = primaryRow.nextAll('div.answer-row:lt('+(secondaryCount)+')');
  var secondaryInputs = $('input.checkbox', secondaryRows);
 
  // Indent the secondaries
  secondaryRows.css({ 'margin-left':'2.5em' });
 
  // Initial states of the secondary answers
  if (primaryInput.prop('checked') == false ) {
    secondaryRows.hide(); 
  } 
 
  // A listener on the primary answer to show or hide secondary answers 
  primaryInput.click(function (event) { 
 
    // Hide/show the secondary answers accordingly
    if (!$(this).is(':checked')) {
      secondaryRows.hide();        
      secondaryInputs.prop('checked', false);
      secondaryInputs.each(function(i) {
        checkconditions(this.value, this.name, this.type);
      });
    }
    else {
      secondaryRows.show(); 
    }
  });
}

Cheers kompetenzz
Attachments:
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 5 months ago - 5 years 5 months ago #176008 by tpartner
In version 3.x, add this script to the end of your theme custom.js file:

Code:
// A function to handle "secondary" checkboxes
function secondaryCheckboxes(qID, primaryPosition, secondaryCount) {
  // Identify the elements
  var thisQuestion = $('#question'+qID);
  var primaryRow = $('li.question-item:eq('+(primaryPosition-1)+')', thisQuestion).closest('li.question-item');
  var primaryInput = $('input:checkbox', primaryRow);
  var secondaryRows = primaryRow.nextAll('li.question-item:lt('+(secondaryCount)+')');
  var secondaryInputs = $('input:checkbox', secondaryRows);
 
  // Indent the secondaries
  secondaryRows.css({ 'margin-left':'2.5em' });
 
  // Initial states of the secondary answers
  if (primaryInput.prop('checked') == false ) {
    secondaryRows.hide(); 
  } 
 
  // A listener on the primary answer to show or hide secondary answers 
  primaryInput.on('change', function (event) { 
 
    // Hide/show the secondary answers accordingly
    if (!$(this).is(':checked')) {
      secondaryRows.hide();        
      secondaryInputs.prop('checked', false).trigger('change');
    }
    else {
      secondaryRows.show(); 
    }
  });
}

I have updated the Workarounds page - manual.limesurvey.org/Workarounds:_Manip...meSurvey_version_3.x

Attached is a sample survey with that script in the source of the first multiple-choice question:

File Attachment:

File Name: limesurvey...4912.lss
File Size:28 KB

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 5 years 5 months ago by tpartner.
The topic has been locked.
  • KompetenzZ
  • KompetenzZ's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
5 years 5 months ago #176128 by KompetenzZ
Hello tpartner,
big fat giant thank you. I appreciate you help a lot. It works perfectly.

Cheers kompetenzz
The topic has been locked.
  • KompetenzZ
  • KompetenzZ's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
5 years 5 months ago - 5 years 5 months ago #176407 by KompetenzZ
Hi,

I tried to combine the secondary answer options with relevance for subquestions in a multiple choice question, but it did not work. The secondary answer options stay visible although it should disappear (because of relevance). Is there a solution to this problem? A test survey (.lss) is attached (with an explanation in the question group description). A theme (.zip) is also attached because a javascript part needs to be added so that secondary answer options will work.

Limesurvey version: 3.14

File Attachment:

File Name: limesurvey...3531.lss
File Size:25 KB

File Attachment:

File Name: extends1_b...tch1.zip
File Size:187 KB

Cheers kompetenzz
Last edit: 5 years 5 months ago by KompetenzZ.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 5 months ago - 5 years 5 months ago #176415 by tpartner
Add this to the end of your custom.css file:

Code:
.js .answer-container .ls-hidden {
    display: none !important;
}

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 5 years 5 months ago by tpartner.
The topic has been locked.
  • KompetenzZ
  • KompetenzZ's Avatar Topic Author
  • Offline
  • Premium Member
  • Premium Member
More
5 years 5 months ago #176420 by KompetenzZ
Thank you for your quick reply. It works fine :)

Cheers kompetenzz
The topic has been locked.
  • elissa
  • elissa's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 2 months ago - 5 years 2 months ago #180297 by elissa
Dear Colleagues,
I'm trying to extend this workaroundworkaround to manage one more level of options, i.e. tertiary options. But as a complete amateur in JS I'm failed. I'll be very grateful for your help.


.
Thanks and regards

Elzbieta Lesinska
LS voluntary Polish translator and supervisor
Last edit: 5 years 2 months ago by elissa.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 2 months ago #180355 by tpartner
Hi Elzbieta, what LimeSurvey version are you using?

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • elissa
  • elissa's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 2 months ago #180356 by elissa
Hi Tony, the latest one: LS 3.15.8+190130.

Elzbieta Lesinska
LS voluntary Polish translator and supervisor
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 2 months ago #180360 by tpartner
Okay, here's a new workaround. In this case we call the function using sub-question codes for the primary/secondary/tertiary items.

1) Copy this script into your custom.js file:

Code:
// A function to handle "child" checkboxes
function dependantCheckboxes(qID, primaryCodes, secondaryCodes, tertiaryCodes) {
  // Identify the elements annd assign classes/attributes
  var thisQuestion = $('#question'+qID);
  thisQuestion.addClass('with-dependants');
  $.each(primaryCodes, function(i, val) {
    var thisItem = $('li[id$="X'+qID+val+'"]');
    $(thisItem).addClass('level-1 parent-item').attr('data-code', val).attr('data-level', '1');
  });  
  $.each(secondaryCodes, function(i, val) {
    var thisItem = $('li[id$="X'+qID+val+'"]');
    var thisParent1 = $(thisItem).prevAll('li[data-level="1"]:eq(0)');
    $(thisItem).addClass('level-2 parent-item child-item').attr('data-code', val).attr('data-level', '2').attr('data-parent-1', $(thisParent1).attr('data-code'));
  });  
  $.each(tertiaryCodes, function(i, val) {
    var thisItem = $('li[id$="X'+qID+val+'"]');
    var thisParent1 = $(thisItem).prevAll('li[data-level="1"]:eq(0)');
    var thisParent2 = $(thisItem).prevAll('li[data-level="2"]:eq(0)');
    $(thisItem).addClass('level-3 child-item').attr('data-code', val).attr('data-level', '3').attr('data-parent-1', $(thisParent1).attr('data-code')).attr('data-parent-2', $(thisParent2).attr('data-code'));
  });  
 
  // A function to handle the states of child items
  function handleChildren(el) { 
    var thisitem = $(el).closest('li');
    var thisCode = $(thisitem).attr('data-code');
    var thisLevel = $(thisitem).attr('data-level');
    var thisChildren = $('li[data-level="'+(Number(thisLevel)+1)+'"][data-parent-'+thisLevel+'="'+thisCode+'"]', thisQuestion);
 
    // Hide/show the secondary answers accordingly
    if (!$(el).is(':checked')) {
      $(thisChildren).fadeOut(300, function(e) {      
        $('input:checkbox', thisChildren).prop('checked', false).trigger('change');
      });  
    }
    else {
      $(thisChildren).fadeIn(300); 
    }
  }
 
  // Initial states of the secondary answers 
  $('.parent-item input:checkbox', thisQuestion).each(function(i) { 
    handleChildren($(this));
  });
 
  // A listener on the primary answer to show or hide secondary answers 
  $('.parent-item input:checkbox', thisQuestion).on('change', function(e) { 
    handleChildren($(this));
  });
}


2) Copy these rules into your custom.css file:

Code:
.with-dependants .child-item {
  display: none;
}
 
.with-dependants li.level-2 {
  margin-left: 2.5em;
}
 
.with-dependants li.level-3 {
  margin-left: 5em;
}


2) Call the function by adding something like this to the question source (this uses sub-question codes from the survey attached below):

Code:
<script type="text/javascript" charset="utf-8">
 
  $(document).on('ready pjax:scriptcomplete',function(){
    dependantCheckboxes(
      {QID}, 
      ['SQ1', 'SQ2'], // First-level sub-question codes 
      ['SQ11', 'SQ12', 'SQ21', 'SQ22'], // Second-level sub-question codes
      ['SQ111', 'SQ112', 'SQ121', 'SQ122', 'SQ211', 'SQ212', 'SQ213', 'SQ221', 'SQ222'] // Third-level sub-question codes
    );
    });  
</script>

Here is a sample survey with all JavaScript and CSS in the source of the first question:

File Attachment:

File Name: limesurvey...2-12.lss
File Size:41 KB

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The following user(s) said Thank You: elissa
The topic has been locked.
  • elissa
  • elissa's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 2 months ago #180365 by elissa
Tony,
It works perfectly. I'm impressed. Thank you very much!
Regards

Elzbieta Lesinska
LS voluntary Polish translator and supervisor
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose