Welcome to the LimeSurvey Community Forum

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

Combine array question with radio button or checkbox

  • Joffm
  • Joffm's Avatar Topic Author
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 8 months ago #243270 by Joffm
Hi, there is this script in the forum,  provided some time ago 
 

Here we merge two questions, an array with three subquestions and two answer options
and a following "multiple short text" question with the same number of subquestions.

Enter this script in the source of the first question
Code:
<script type="text/javascript" charset="utf-8">
    $(document).on('ready pjax:scriptcomplete',function(){
        // Identify the questions
        var q1ID = {QID};
        var thisQuestion = $('#question'+q1ID);
        var nextQuestion = thisQuestion.nextAll('.multiple-short-txt:eq(0)');
        var q2ID = $(nextQuestion).attr('id').replace(/question/, '');
        
        //Hide the multiple-short-text
        nextQuestion.hide();
        
        // Move the text inputs
        $('tr.answers-list', thisQuestion).each(function(i) {
            var thisCode = $(this).attr('id').split('X')[2].split(q1ID)[1];
            $('td.answer-item:first input[type="radio"]', this).css({
                'position': 'absolute',
                'left': '-9999em'
            });
            $('td.answer-item:first', this).removeClass('radio-item').addClass('inserted-text-item').append($('input[type="text"][id$="X'+q2ID+thisCode+'"]', nextQuestion));
        });
        
        // Listeners on the text inputs
        $('input[type="text"]', thisQuestion).on('keyup change', function(e) {
            var thisRadio = $(this).closest('td').find('input[type="radio"]');
            var thisRadioVal = thisRadio.val();
            if($.trim($(this).val()) != '') {
                $(thisRadio).trigger('click');
            }
            else {
                $(thisRadio).prop('checked', false);
                thisRadioVal = '';
            }
            // Reset Expression manager
            checkconditions(thisRadioVal, $(thisRadio).attr('name'), 'radio', 'click');
        });
        
        // Listeners on the radios
        $('input[type="radio"]', thisQuestion).on('click', function(e) {
            if(!$(this).closest('td').hasClass('inserted-text-item')) {
                $(this).closest('tr').find('input[type="text"]').val('');
            }
        });
 
    });
</script>

Joffm

Volunteers are not paid.
Not because they are worthless, but because they are priceless

Please Log in to join the conversation.

  • Joffm
  • Joffm's Avatar Topic Author
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 8 months ago #243311 by Joffm
Hi,

I need to do something similar

But only at first glance.
The other solution was based on an array
As you can imagine this is quite different as an array allows only one response per row.
But here you expect three responses per row

You may use an array(text) and insert checkboxes.
Then you have to handle that each pair is exclusive.

Here's a script I adapted from a former solution of @tpartner.
Code:
<script type="text/javascript" charset="utf-8">  
    
    $(document).on('ready pjax:scriptcomplete',function(){
 
        // Identify this question
        var thisQuestion = $('#question{QID}');
 
        // Column-specific classes
        $('tr.subquestion-list', thisQuestion).each(function(i) {
            $('th, td', this).each(function(i) {
                $(this).addClass('column-'+i);
            });
        });
        
        // Insert checkboxes
        $('.answer-item.column-2, .answer-item.column-4, .answer-item.column-6', thisQuestion).addClass('custom-checkbox-item');
        $('.custom-checkbox-item', thisQuestion).each(function(i) {
            var thisID = $('input:text:eq(0)', this).attr('id');
            $('label', this).before('<input class="" id="'+thisID+'" value="Y" type="checkbox" name="'+thisID.replace(/answer/, '')+'" />');
            if($('input:text:eq(0)', this).val() == 'Y') {
                $('input:checkbox:eq(0)', this).prop('checked', true);
            }
            $(this).removeClass('text-item').addClass('checkbox-item');
            $('input:text:eq(0)', this).remove();
        });
        
        // Identify exclusive items
        $('.answer-item.column-1, .answer-item.column-2', thisQuestion).addClass('exclusive-item1');
        $('.answer-item.column-3, .answer-item.column-4', thisQuestion).addClass('exclusive-item2');
        $('.answer-item.column-5, .answer-item.column-6', thisQuestion).addClass('exclusive-item3');
        
        // Listeners for exclusive items
        $('.exclusive-item1 input:text', thisQuestion).on('keyup change', function(e) {
            if($.trim($(this).val()) != '') {
                $(this).closest('tr.subquestion-list').find('.exclusive-item1 input:checkbox').prop('checked', false);
            }
        });
        $('.exclusive-item1 input:checkbox', thisQuestion).on('change', function(e) {
            if($(this).is(':checked')) {
                var thisItem = $(this).closest('.answer-item');
                $(this).closest('tr.subquestion-list').find('.exclusive-item1 input:text').val('');
            }
        });
 
        $('.exclusive-item2 input:text', thisQuestion).on('keyup change', function(e) {
            if($.trim($(this).val()) != '') {
                $(this).closest('tr.subquestion-list').find('.exclusive-item2 input:checkbox').prop('checked', false);
            }
        });
        $('.exclusive-item2 input:checkbox', thisQuestion).on('change', function(e) {
            if($(this).is(':checked')) {
                var thisItem = $(this).closest('.answer-item');
                $(this).closest('tr.subquestion-list').find('.exclusive-item2 input:text').val('');
            }
        });
 
        $('.exclusive-item3 input:text', thisQuestion).on('keyup change', function(e) {
            if($.trim($(this).val()) != '') {
                $(this).closest('tr.subquestion-list').find('.exclusive-item3 input:checkbox').prop('checked', false);
            }
        });
        $('.exclusive-item3 input:checkbox', thisQuestion).on('change', function(e) {
            if($(this).is(':checked')) {
                var thisItem = $(this).closest('.answer-item');
                $(this).closest('tr.subquestion-list').find('.exclusive-item3 input:text').val('');
            }
        });
 
    });
</script>

Additionally you may adapt the column width and the background colors
Code:
<script type="text/javascript" charset="utf-8">
  $(document).on('ready pjax:scriptcomplete',function(){
    var thisQuestion = $('#question{QID}');
    // Add a question class
    thisQuestion.addClass('custom-array');
 
    // Column-specific classes
    $('table.subquestion-list tr', thisQuestion).each(function(i) {
      $('th, td', this).each(function(i) {
        $(this).addClass('column-'+i);
      });
    });
  });
</script>
<style type="text/css">.custom-array table.subquestion-list col {
    width: auto !important;
  }
 
  .custom-array table.subquestion-list thead .column-0 {  width: 25%; }
  .custom-array table.subquestion-list thead .column-1 {  width: 15%; }
  .custom-array table.subquestion-list thead .column-2 {  width: 10%; background-color:#efefef; }
  .custom-array table.subquestion-list thead .column-3 {  width: 15%; }
  .custom-array table.subquestion-list thead .column-4 {  width: 10%; background-color:#efefef; }
  .custom-array table.subquestion-list thead .column-5 {  width: 15%; }
  .custom-array table.subquestion-list thead .column-6 {  width: 10%; background-color:#efefef; }

  .custom-array table.subquestion-list td.column-2,
  .custom-array table.subquestion-list td.column-4,
  .custom-array table.subquestion-list td.column-6 {
    background-color:#efefef;
  }
</style>

 

What is left for you?
The validation. That each row contains exactly three responses.

Joffm

 

Volunteers are not paid.
Not because they are worthless, but because they are priceless
The following user(s) said Thank You: KaryG

Please Log in to join the conversation.

  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 8 months ago #243327 by tpartner
Hi Joffm, I think we can optimize the checkbox insertion code a bit and make it more generic for additional columns...
Code:
<script type="text/javascript" data-author="Tony Partner">
 
  $(document).on('ready pjax:scriptcomplete',function(){
 
    // Identify this question
    var thisQuestion = $('#question{QID}');
 
    // Insert checkboxes
    $('.answer-item:nth-child(odd)', thisQuestion).each(function(i) {
      $(this).removeClass('text-item').addClass('checkbox-item custom-checkbox-item');
      var thisID = $('input:text:eq(0)', this).attr('id');
      $('label', this).before('<input class="" id="'+thisID+'" value="Y" type="checkbox" name="'+thisID.replace(/answer/, '')+'" />');
      if($('input:text:eq(0)', this).val() == 'Y') {
        $('input:checkbox:eq(0)', this).prop('checked', true);
      }
      $('input:text:eq(0)', this).remove();
    });
 
    // Listeners on the text inputs
    $('.answer-item:nth-child(even) input:text', thisQuestion).on('keyup change', function(e) {
      if($.trim($(this).val()) != '') {
        $(this).closest('.answer-item').next('.custom-checkbox-item').find('input:checkbox').prop('checked', false);
      }
    });
 
    // Listeners on the checkboxes
    $('.custom-checkbox-item input:checkbox', thisQuestion).on('change', function(e) {
      if($(this).is(':checked')) {
        var thisItem = $(this).closest('.answer-item');
        $(this).closest('.answer-item').prev('.text-item').find('input:text').val('');
      }
    });
  });
</script>

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

Please Log in to join the conversation.

  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 8 months ago #243329 by tpartner
I also think we can clean up the styling like this, using the CSS :nth-child() selector.

(no JS required)

Code:
<style type="text/css" data-author="Tony Partner">
  #question{QID} table.subquestion-list col {
    width: auto !important;
  }
 
  #question{QID} table.subquestion-list thead tr > *:nth-child(even) {  width: 15%; }
  #question{QID} table.subquestion-list thead tr > *:nth-child(odd) {  width: 10%; background-color:#efefef; }
  #question{QID} table.subquestion-list thead tr > *:nth-child(1) {  width: 25%; background-color:transparent; }
  
  #question{QID} table.subquestion-list tbody td:nth-child(odd) {
    background-color:#efefef;
  }
</style>

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

Please Log in to join the conversation.

  • Joffm
  • Joffm's Avatar Topic Author
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 8 months ago #243338 by Joffm
Either the entire question is mandatory or not.

You have to set it to "not mandatory" and make sure the first rows are filled by validation.

A workaround could be:
Use two questions.
One mandatory for the first rows, one not mandatory for the "other" rows.
Merge the questions with css classes "no-question" and "no-bottom".

Joffm 

Volunteers are not paid.
Not because they are worthless, but because they are priceless
The following user(s) said Thank You: DenisChenu, KaryG

Please Log in to join the conversation.

  • DenisChenu
  • DenisChenu's Avatar
  • Offline
  • LimeSurvey Community Team & Official Partner
  • LimeSurvey Community Team & Official Partner
More
1 year 8 months ago #243373 by DenisChenu
And if you need a complete system and have some time to learn

See Skelvanilla group in group with columns
(for LimeSurvey 5 or 3, not for 6)

Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member. - Professional support - Plugins, theme and development .
I don't answer to private message.
The following user(s) said Thank You: KaryG

Please Log in to join the conversation.

  • Joffm
  • Joffm's Avatar Topic Author
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
1 year 8 months ago #243452 by Joffm
You can't set the question to "mandatory".
"Mandatory" means "All cells have to be filled"

Use "question validation".
You have to check that there are exactly three cells filled in each row.

Joffm
 

Volunteers are not paid.
Not because they are worthless, but because they are priceless
The following user(s) said Thank You: KaryG

Please Log in to join the conversation.

Moderators: tpartnerholch

Lime-years ahead

Online-surveys for every purse and purpose