Welcome to the LimeSurvey Community Forum

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

Array (numbers) with an exclusive checkbox

  • nique
  • nique's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
6 years 7 months ago #157396 by nique
I have tried searching the forums but I can't quite find anything that solves my issue or I am unsure how to articulate it. Happy to either insert JS or consider other question options.

I am asking participants for numbers to multiple events over the last three years.
Therefore I have set up an Array (texts - only insert numbers) looking something like this:

2015 2016 2017
Event 1
Event 2
Event 3

I want to make this question mandatory as we do need this data but I also want a Not Applicable or Cannot answer option for those who really cannot answer the question.

Is there a way I could add a checkbox to the end of each event row that, if selected, excludes the number arrays and accepts that as an answer? Or add something into each year that they could select?

I thought about maybe a dropdown of values but my options could be 0-100 and that looks messy.

Happy for all suggestions! Thanks in advance.
The topic has been locked.
  • Joffm
  • Joffm's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
6 years 7 months ago #157398 by Joffm
Replied by Joffm on topic Array (numbers) with an exclusive checkbox
Hi, nique,
please have a look at these two topics with Tony's solutions- Maybe you could combine them.

1. www.limesurvey.org/forum/design-issues/1...with-yes-no-question
2. www.limesurvey.org/forum/design-issues/1...work-in-array-number

IMHO a slider is a very appealing way to enter numbers between 0 and 100.

3. Have a look at "arrayTextAdapt".

Best regards
Joffm

Volunteers are not paid.
Not because they are worthless, but because they are priceless
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
6 years 7 months ago - 6 years 7 months ago #157400 by tpartner
Replied by tpartner on topic Array (numbers) with an exclusive checkbox
Regarding the exclusive aspect, you could...
  • Insert a fourth "N/A" column (x-scale sub-question)
  • Use JavaScript to do the following:
    • Hide the column 4 text inputs
    • Insert check-boxes into column 4 cells
    • If a column 4 box is checked, insert a value of 1 in its hidden input and clear all column 1-3 inputs
    • If a column 1-3 text input is populated, un-check column 4 and clear the column 4 hidden input
  • Add a question validation equation so that, in every row, either columns 1-3 are populated OR the hidden input in column 4 is populated

The JavaScript would look like this:

Code:
<script type="text/javascript" charset="utf-8">
  $(document).ready(function(){  
 
    // Identify this question
    var qID = {QID};
    var thisQuestion = $('#question'+qID);
 
    // Add some classes
    $(thisQuestion).addClass('with-exclusive-items');
    $('td.answer-item', thisQuestion).addClass('non-exclusive-item');
 
    // Loop through the last-column cells
    $('td.answer-item:last-child', thisQuestion).each(function(i) {
      varThisID = $('input[type="text"]', this).attr('id');
 
      // Add a class
      $(this).removeClass('non-exclusive-item').addClass('exclusive-item');
 
      // Hide the text input
      $('td.answer-item:last-child input[type="text"]', thisQuestion).hide();
 
      // Insert checkboxes
      $(this).append('<div class="checkbox">\
                <input class="checkbox" name="" id="'+varThisID+'_cbox" value="N/A" type="checkbox">\
                <label for="'+varThisID+'_cbox" class="answertext inserted-label"></label>\
              </div>'); 
    });
 
    // Listener on the checkboxes
    $('.exclusive-item input[type="checkbox"]', thisQuestion).on('change', function(e) {
      var thisRow = $(this).closest('tr.subquestion-list');
      var thisCell = $(this).closest('td.answer-item');
      if($(this).is(':checked')) {
        $('input[type="text"]', thisCell).val('1');
        $('.non-exclusive-item input[type="text"]', thisRow).val('');
      }
      else {
        $('input[type="text"]', thisCell).val('');
      }
 
      // Fire Expression Manager
      $('input[type="text"]', thisRow).each(function(i) {
        $(this).trigger('keyup');
      });
    });
 
    // Listener on the text inputs
    $('.non-exclusive-item input[type="text"]', thisQuestion).on('keyup change', function(e) {
      var thisRow = $(this).closest('tr.subquestion-list');
      if($.trim($(this).val()) != '') {
        $('.exclusive-item input[type="checkbox"]', thisRow).prop('checked',false);
        $('.exclusive-item input[type="text"]', thisRow).val('');
      }
 
      // Fire Expression Manager
      $('.exclusive-item input[type="text"]', thisRow).trigger('keyup');
    });
 
    // Insert some styles (these could be in template.css)
    // For the LS 2.67 default template
    var newStyles = '.with-exclusive-items thead th.answertext {\
              text-align: center;\
            }\
            .with-exclusive-items .exclusive-item {\
              text-align: center;\
              vertical-align: middle;\
              cursor: pointer;\
            }\
            .with-exclusive-items .checkbox {\
              padding-left: 0;\
            }\
            .with-exclusive-items .inserted-label {\
              width: 24px;\
              min-height: 24px;\
              padding: 0;\
            }\
            .with-exclusive-items .inserted-label::before {\
              margin: 4px 0 0 4px;\
            }\
            .with-exclusive-items .inserted-label::after {\
              margin: 4px 0 0 4px;\
            }';  
    $('head').append('<style type="text/css">'+newStyles+'</style>');  
  });  
</script>

And, for the validation, assuming...
  • Question code: Q1
  • Y-scale sub-question codes: Y1, Y2, Y3
  • X-scale sub-question codes: X1, X2, X3, X4
...the validation equation would look like this (line-breaks added for clarity):

Code:
(count(Q1_Y1_X1, Q1_Y1_X2, Q1_Y1_X3)>2 OR count(Q1_Y1_X4)>0)
AND
(count(Q1_Y2_X1, Q1_Y2_X2, Q1_Y2_X3)>2 OR count(Q1_Y2_X4)>0)
AND
(count(Q1_Y3_X1, Q1_Y3_X2, Q1_Y3_X3)>2 OR count(Q1_Y3_X4)>0)



Sample survey attached:

File Attachment:

File Name: limesurvey...8-04.lss
File Size:20 KB

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 6 years 7 months ago by tpartner.
The following user(s) said Thank You: krosser
The topic has been locked.
More
5 years 3 months ago #177165 by krosser
Replied by krosser on topic Array (numbers) with an exclusive checkbox

tpartner wrote: Regarding the exclusive aspect, you could...

  • Insert a fourth "N/A" column (x-scale sub-question)
  • Use JavaScript to do the following:
    • Hide the column 4 text inputs
    • Insert check-boxes into column 4 cells
    • If a column 4 box is checked, insert a value of 1 in its hidden input and clear all column 1-3 inputs
    • If a column 1-3 text input is populated, un-check column 4 and clear the column 4 hidden input
  • Add a question validation equation so that, in every row, either columns 1-3 are populated OR the hidden input in column 4 is populated

The JavaScript would look like this:

Code:
<script type="text/javascript" charset="utf-8">
  $(document).ready(function(){  
 
    // Identify this question
    var qID = {QID};
    var thisQuestion = $('#question'+qID);
 
    // Add some classes
    $(thisQuestion).addClass('with-exclusive-items');
    $('td.answer-item', thisQuestion).addClass('non-exclusive-item');
 
    // Loop through the last-column cells
    $('td.answer-item:last-child', thisQuestion).each(function(i) {
      varThisID = $('input[type="text"]', this).attr('id');
 
      // Add a class
      $(this).removeClass('non-exclusive-item').addClass('exclusive-item');
 
      // Hide the text input
      $('td.answer-item:last-child input[type="text"]', thisQuestion).hide();
 
      // Insert checkboxes
      $(this).append('<div class="checkbox">\
                <input class="checkbox" name="" id="'+varThisID+'_cbox" value="N/A" type="checkbox">\
                <label for="'+varThisID+'_cbox" class="answertext inserted-label"></label>\
              </div>'); 
    });
 
    // Listener on the checkboxes
    $('.exclusive-item input[type="checkbox"]', thisQuestion).on('change', function(e) {
      var thisRow = $(this).closest('tr.subquestion-list');
      var thisCell = $(this).closest('td.answer-item');
      if($(this).is(':checked')) {
        $('input[type="text"]', thisCell).val('1');
        $('.non-exclusive-item input[type="text"]', thisRow).val('');
      }
      else {
        $('input[type="text"]', thisCell).val('');
      }
 
      // Fire Expression Manager
      $('input[type="text"]', thisRow).each(function(i) {
        $(this).trigger('keyup');
      });
    });
 
    // Listener on the text inputs
    $('.non-exclusive-item input[type="text"]', thisQuestion).on('keyup change', function(e) {
      var thisRow = $(this).closest('tr.subquestion-list');
      if($.trim($(this).val()) != '') {
        $('.exclusive-item input[type="checkbox"]', thisRow).prop('checked',false);
        $('.exclusive-item input[type="text"]', thisRow).val('');
      }
 
      // Fire Expression Manager
      $('.exclusive-item input[type="text"]', thisRow).trigger('keyup');
    });
 
    // Insert some styles (these could be in template.css)
    // For the LS 2.67 default template
    var newStyles = '.with-exclusive-items thead th.answertext {\
              text-align: center;\
            }\
            .with-exclusive-items .exclusive-item {\
              text-align: center;\
              vertical-align: middle;\
              cursor: pointer;\
            }\
            .with-exclusive-items .checkbox {\
              padding-left: 0;\
            }\
            .with-exclusive-items .inserted-label {\
              width: 24px;\
              min-height: 24px;\
              padding: 0;\
            }\
            .with-exclusive-items .inserted-label::before {\
              margin: 4px 0 0 4px;\
            }\
            .with-exclusive-items .inserted-label::after {\
              margin: 4px 0 0 4px;\
            }';  
    $('head').append('<style type="text/css">'+newStyles+'</style>');  
  });  
</script>

And, for the validation, assuming...
  • Question code: Q1
  • Y-scale sub-question codes: Y1, Y2, Y3
  • X-scale sub-question codes: X1, X2, X3, X4
...the validation equation would look like this (line-breaks added for clarity):

Code:
(count(Q1_Y1_X1, Q1_Y1_X2, Q1_Y1_X3)>2 OR count(Q1_Y1_X4)>0)
AND
(count(Q1_Y2_X1, Q1_Y2_X2, Q1_Y2_X3)>2 OR count(Q1_Y2_X4)>0)
AND
(count(Q1_Y3_X1, Q1_Y3_X2, Q1_Y3_X3)>2 OR count(Q1_Y3_X4)>0)



Sample survey attached:

File Attachment:

File Name: limesurvey...8-04.lss
File Size:20 KB



Hi Tony,

I am trying to update your code because the checkboxes are not places properly in LS 3.15.
I've combined and edited a couple of code, which resulted in this:
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);
      });
    });
 
    // Add some classes
    $(thisQuestion).addClass('with-exclusive-items');
    $('td.answer-item', thisQuestion).addClass('non-exclusive-item');
 
      // Insert checkboxes
    $('.answer-item.column-4:lt(3)', 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="NA" type="checkbox" name="'+thisID.replace(/answer/, '')+'" />');
      if($('input:text:eq(0)', this).val() == 'NA') {
        $('input:checkbox:eq(0)', this).prop('checked', true);
      }
      $(this).removeClass('text-item').addClass('checkbox-item');
      $('input:text:eq(0)', this).remove();
    });
 
    // Listener on the checkboxes
    $('.custom-checkbox-item input[type="checkbox"]', thisQuestion).on('change', function(e) {
      var thisRow = $(this).closest('tr.subquestion-list');
      var thisCell = $(this).closest('td.answer-item');
      if($(this).is(':checked')) {
        $('input[type="text"]', thisCell).val('1');
        $('.non-exclusive-item input[type="text"]', thisRow).val('');
      }
      else {
        $('input[type="text"]', thisCell).val('');
      }
 
      // Fire Expression Manager
      $('input[type="text"]', thisRow).each(function(i) {
        $(this).trigger('keyup');
      });
    });
 
    // Listener on the text inputs
    $('.non-exclusive-item input[type="text"]', thisQuestion).on('keyup change', function(e) {
      var thisRow = $(this).closest('tr.subquestion-list');
      if($.trim($(this).val()) != '') {
        $('.custom-checkbox-item input[type="checkbox"]', thisRow).prop('checked',false);
        $('.custom-checkbox-item input[type="text"]', thisRow).val('');
      }
 
      // Fire Expression Manager
      $('.custom-checkbox-item input[type="text"]', thisRow).trigger('keyup');
    });
 
  });  
</script>

It works, but I am not sure if that is 100% correct. So, if you could give it a quick look from an expert perspective, it would be great!

Sample survey attached.

File Attachment:

File Name: limesurvey...2018.lss
File Size:23 KB

I'm using the latest LS 3.22 hosted on LS servers, not installed locally.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 3 months ago #177208 by tpartner
Replied by tpartner on topic Array (numbers) with an exclusive checkbox
I see a few problems:

1) The labels for the inserted check-boxes will have the wrong "for" attributes
2) You are removing the text inputs (instead of hiding them) so I relevance will be broken
3) The values for the checked boxes will be incorrect when returning to the page

I would use something like this:

Code:
<script type="text/javascript" charset="utf-8">
  $(document).on('ready pjax:scriptcomplete',function(){  
 
    // Identify this question
    var thisQuestion = $('#question{QID}');
 
    if($('.custom-checkbox-item input[type="checkbox"]', thisQuestion).length == 0) {
 
      // Column-specific classes
      $('tr.subquestion-list', thisQuestion).each(function(i) {
        $('th, td', this).each(function(i) {
          $(this).addClass('column-'+i);
        });
      });
 
      // Add some classes
      $(thisQuestion).addClass('with-exclusive-items');
      $('td.answer-item:not(:last-child)', thisQuestion).addClass('non-exclusive-item');
 
      // Hide the text inputs
      $('td.answer-item:last-child input:text', thisQuestion).css({
        'position': 'absolute',
        'left': '-9999em'
      });
 
      // Insert checkboxes
      $('td.answer-item:last-child', thisQuestion).each(function(i) {
        var thisSGQ = $('input:text:eq(0)', this).attr('id').replace(/answer/, '');
        $('label', this).before('<input class="" id="inserted_'+thisSGQ+'" value="NA" type="checkbox" name="inserted_'+thisSGQ+'" />');
        if($('input:text:eq(0)', this).val() == 1) {
          $('input:checkbox:eq(0)', this).prop('checked', true);
        }
        $('label:eq(0)', this).attr('for', 'inserted_'+thisSGQ+'');
      }).removeClass('text-item').addClass('checkbox-item custom-checkbox-item exclusive-item');
 
      // Listener on the checkboxes
      $('.custom-checkbox-item input[type="checkbox"]', thisQuestion).on('change', function(e) {
        var thisRow = $(this).closest('tr.subquestion-list');
        var thisCell = $(this).closest('td.answer-item');
        if($(this).is(':checked')) {
          $('input[type="text"]', thisCell).val('1');
          $('.non-exclusive-item input[type="text"]', thisRow).val('');
        }
        else {
          $('input[type="text"]', thisCell).val('');
        }
 
        // Fire Expression Manager
        $('input[type="text"]', thisRow).each(function(i) {
          $(this).trigger('change');
        });
      });
 
      // Listener on the text inputs
      $('.non-exclusive-item input[type="text"]', thisQuestion).on('keyup', function(e) {
        var thisRow = $(this).closest('tr.subquestion-list');
        if($.trim($(this).val()) != '') {
          $('.custom-checkbox-item input[type="checkbox"]', thisRow).prop('checked',false).trigger('change');
          $('.custom-checkbox-item input[type="text"]', thisRow).val('');
        }
 
        // Fire Expression Manager
        $('input[type="text"]', thisRow).each(function(i) {
          $(this).trigger('change');
        });
      });
    }
  });  
</script>



Sample survey attached:

File Attachment:

File Name: limesurvey...4793.lss
File Size:25 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: krosser
The topic has been locked.
More
5 years 3 months ago #177330 by krosser
Replied by krosser on topic Array (numbers) with an exclusive checkbox
Thanks man! I'll try to learn from this example.

I'm using the latest LS 3.22 hosted on LS servers, not installed locally.
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose