Welcome to the LimeSurvey Community Forum

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

Alternate ranking question - Dynamic answer options

  • Gensz78
  • Gensz78's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
6 years 5 months ago #159798 by Gensz78
Hi all!

I've created an alternate ranking question, using the workaround in the manual: an array question where answer options are numbers from 1 to x. That system is working flawlessly. (She finds the regular Ranking style question to be too error-prone)

I'm also using array filters so the number of subquestions varies depending on participants. My problem is that the number of answers options also needs to vary; that's where I get stuck. See attached image. Two subquestions were filtered from a previous question (Option 1 and Option 2), and I would like the answers options (or rankings) to be only 1 and 2; if three subquestions are filtered, I'd like the answer options to be 1, 2 and 3; etc. Can I do this with LimeSurvey?

Note: I'm using Version 2.65.1+170522 of LimeSurvey on a university server. I cannot change the template or install plugins (I have to use it as it is), but I can run javascript within questions.

Thanks for your help!

Gen
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
6 years 5 months ago #159800 by tpartner
It would help if you give us the JS used, or at least point us to the workaround used, and attach a small test survey containing only the relevant questions.

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • Gensz78
  • Gensz78's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
6 years 5 months ago #159802 by Gensz78
Apologies for not giving more information! You'll find a sample survey attached.

I used the workaround discussed here (a simple array) and here .

In my sample survey, the testrank question filters answers from behavioursSELECT and behavOtherIDENTIFY. That works great! What I can't figure out is how to dynamically adapt the answer options in testrank depending on the number of subquestions that appear, so 1 to 5 if 5 subquestions appear, etc. Participants then have to rank the x subquestions by importance from 1 to x.

I also tried using this script to make sure participants can't choose the same ranking twice:

<script type="text/javascript" charset="utf-8">

$(document).ready(function() {

// Identify this question
var qID = {QID};

// Answers are exclusive by column
$('#question'+qID+' input[type="radio"]').click(function(event){
var thisAnsCode = $(this).attr('id').split('-')[1];
$('#question'+qID+' input[id$="-'+thisAnsCode+'"]').prop('checked', false);
$(this).prop('checked', true);
});
});
</script>

But it only seems to work for radio buttons and not dropdowns.

Let me know if this is enough information!

Thanks!

Gen
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
6 years 4 months ago - 6 years 4 months ago #159829 by tpartner
Regarding the linked workaround - that's not working because you didn't append ".NAOK" to the variables in the question validation equation and tip. You need this because some variables included in the "self" array may be hidden by relevance.

Code:
unique(self.NAOK)
Code:
{if(!unique(self.NAOK), 'No duplicate rankings.', '')}


Regarding filtering the ranking drop-downs - that would be far easier if the ranking question was on a following page. Is that possible?

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 6 years 4 months ago by tpartner.
The following user(s) said Thank You: zserban
The topic has been locked.
  • Gensz78
  • Gensz78's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
6 years 4 months ago #159833 by Gensz78
Many thanks for the question validation equation and tip solution, it's working great now! Is it also possible to erase a previously given answer in a subquestion if a participant choose the same answer in another subquestion, i.e. if a participant tries to give the same ranking to another subquestion (like the above js does for radio buttons)?

Regarding filtering the ranking drop-downs, it's definitely possible for the ranking question to be on another page!

Thanks again!

Gen
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
6 years 4 months ago - 6 years 4 months ago #159843 by tpartner

Is it also possible to erase a previously given answer in a subquestion if a participant choose the same answer in another subquestion, i.e. if a participant tries to give the same ranking to another subquestion

Why do you need that if the unique() validation works?

Regarding filtering the drop-downs...

1) Move the ranking question to a following group.

2) Set the answer codes in the ranking question to sequential numerics (not the default A1, A2...).

3) Add the following script to the source of the ranking question:

Code:
<script type="text/javascript" charset="utf-8">
  $(document).on('ready pjax:complete',function() {
 
    // Identify this question
    var thisQuestion = $('#question{QID}');
 
    // Define some "Choose" text
    var choosetext = 'Please choose...';
 
    // Number of visible rows
    var rowCount = $('tr.answer-item:visible', thisQuestion).length;
 
    // Loop through all drop-downs
    $('tr.answer-item select', thisQuestion).each(function(i) {
 
      // Reset if value is above the number of visible rows
      if($(this).val() > rowCount) {
        $(this).prepend('<option value="">'+choosetext+'</option>').val('');
        checkconditions(this.value, this.name, this.type);
      }
 
      // Remove all unnecessary options
      $('option', this).filter(function() {
        return this.value > rowCount;
      }).remove(); 
    });
 
  });
</script>



Sample survey attached:

File Attachment:

File Name: limesurvey...5621.lss
File Size:46 KB

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 6 years 4 months ago by tpartner.
The topic has been locked.
  • Gensz78
  • Gensz78's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
6 years 4 months ago #159848 by Gensz78
Wow, thank you so much, it's working great!

If people mistakenly select the same rankings twice and click next (because they don't notice the No duplicate rankings message), is it possible to mark the subquestions with the same rankings in red? Or is it possible to mark them in red while they are still ranking subquestions? Just to make it more noticeable for them.

Regarding erasing a previously given answer in a subquestion if a participant choose the same answer in another subquestion, I like the possibility because people can find it confusing to figure out which ranking they chose twice. But it can either be erasing answers or marking them in red, whichever is easier!

Thank you!

Gen
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
6 years 4 months ago #159857 by tpartner

...is it possible to mark the subquestions with the same rankings in red?


1) Use this script in the source of the ranking question:

Code:
<script type="text/javascript" charset="utf-8"> 
  $(document).on('ready pjax:complete',function() {
 
    // Identify this question
    var thisQuestion = $('#question{QID}');
 
    // Define some "Choose" text
    var choosetext = 'Please choose...';
 
    // Number of visible rows
    var rowCount = $('tr.answer-item:visible', thisQuestion).length;
 
    // Loop through all drop-downs
    $('tr.answer-item select', thisQuestion).each(function(i) {
 
      // Reset if value is above the number of visible rows
      if($(this).val() > rowCount) {
        $(this).prepend('<option value="">'+choosetext+'</option>').val('');
        checkconditions(this.value, this.name, this.type);
      }
 
      // Remove all unnecessary options
      $('option', this).filter(function() {
        return this.value > rowCount;
      }).remove(); 
    });
 
    // Listener on the dropdowns
    $('tr.answer-item select', thisQuestion).on('change', function(e) {
      // Handle non-unique answers
       handleDuplicates();
    });
 
    function handleDuplicates() {
      $('.question-item', thisQuestion).removeClass('duplicate-row');
      $('tr.answer-item select', thisQuestion).each(function(i) {
        if(!$(this).closest('.question-item').hasClass('duplicate-row') &amp;&amp; $(this).val() != '') {
          var thisSelect = $(this);
          var selectedValue = $(this).val();
          $('tr.answer-item select', thisQuestion).not(this).each(function(i) {
            if($(this).val() == selectedValue) {
              $(this).closest('.question-item').addClass('duplicate-row');
              $(thisSelect).closest('.question-item').addClass('duplicate-row');
            }
          });
        }
      });
    }
    handleDuplicates();
 
  });
</script>

2) Add something like this to the end of template.css:

Code:
.duplicate-row {
  background-color: #E74C3C;
}
 
.duplicate-row .answertext {
  color: #FFFFFF;
}



Sample survey attached:

File Attachment:

File Name: limesurvey...8562.lss
File Size:47 KB

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • Gensz78
  • Gensz78's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
6 years 4 months ago #159905 by Gensz78
Sadly, this solution doesn't work because I don't have access to the template.

Thanks for everything!

Gen
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
6 years 4 months ago #159906 by tpartner
Try this (where the styles are inserted via JavaScript):

Code:
<script type="text/javascript" charset="utf-8"> 
  $(document).on('ready pjax:complete',function() {
 
    // Identify this question
    var thisQuestion = $('#question{QID}');
 
    // Define some "Choose" text
    var choosetext = 'Please choose...';
 
    // Number of visible rows
    var rowCount = $('tr.answer-item:visible', thisQuestion).length;
 
    // Loop through all drop-downs
    $('tr.answer-item select', thisQuestion).each(function(i) {
 
      // Reset if value is above the number of visible rows
      if($(this).val() > rowCount) {
        $(this).prepend('<option value="">'+choosetext+'</option>').val('');
        checkconditions(this.value, this.name, this.type);
      }
 
      // Remove all unnecessary options
      $('option', this).filter(function() {
        return this.value > rowCount;
      }).remove(); 
    });
 
    // Listener on the dropdowns
    $('tr.answer-item select', thisQuestion).on('change', function(e) {
      // Handle non-unique answers
       handleDuplicates();
    });
 
    function handleDuplicates() {
      $('.question-item', thisQuestion).removeClass('duplicate-row');
      $('tr.answer-item select', thisQuestion).each(function(i) {
        if(!$(this).closest('.question-item').hasClass('duplicate-row') &amp;&amp; $(this).val() != '') {
          var thisSelect = $(this);
          var selectedValue = $(this).val();
          $('tr.answer-item select', thisQuestion).not(this).each(function(i) {
            if($(this).val() == selectedValue) {
              $(this).closest('.question-item').addClass('duplicate-row');
              $(thisSelect).closest('.question-item').addClass('duplicate-row');
            }
          });
        }
      });
    }
    handleDuplicates();
 
    //Insert new style rules
    var newStyle = '<style type="text/css">\
              .duplicate-row {\
                background-color: #E74C3C;\
              }\               
              .duplicate-row .answertext {\
                color: #FFFFFF;\
              }\
            </style>';    
    $("head link[rel='stylesheet']").last().after(newStyle);
 
  });
</script>

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • Gensz78
  • Gensz78's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
6 years 4 months ago #159907 by Gensz78
This doesn't seem to work for some reason. It doesn't remove the unneeded rankings and doesn't mark duplicates in red. It also breaks the filtering of the behavOtherIDENTIFY question. Maybe it's because I don't have access to the template?

Thanks!

Gen
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
6 years 4 months ago #159908 by tpartner
That indicates a javascript error but I don't have time to debug today.

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose