Welcome to the LimeSurvey Community Forum

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

Find 3 highest or lowest rated options in Array (Numbers) question?

  • cberghoff
  • cberghoff's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
10 years 7 months ago #98898 by cberghoff
Hi all,

I have an Array (Numbers) item with 12 items on the y-axis and 1 response column on the x-axis (range from -6 to +6). I'm computing this variable with an equation item, so I can change the item type if there is a better way to do this. I need to first ignore any items that are scored as 0. Of the remaining items, I need to select the 3 highest rated (I'll also do the lowest for another group, but I'm hoping a solution will be easily altered for that). My ultimate goal is to tailor a List (Radio) item with these 3 responses, force them to pick one, and proceed through the survey focusing on that one item.

So, my plan was to get the 3 maximum scores, use a hidden multiple choice item to transfer the information to, and use array filter on the radio item. However, max only gives me the one highest item, and I need 3. Someone could rate 4 items all at the max, in which case I don't care which 3 I get, but I only want 3. I tried looking at unique in the documentation, but nothing is there and php.net doesn't have anything about unique either. Also, I'm not really sure how to use max to check an option in the hidden question, much less how to check 3 boxes!. Is there any way to do this using expression manager, or a tutorial I haven't come across? I've spent most of the day in the manual and forum trying to find an answer, and I'm not having much luck.

Thanks,
Chris
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
10 years 7 months ago #98982 by tpartner
I'm not sure you can get there with Expression Manager but should be able to do it with JavaScript. Can you attach a sample survey for me to play with?

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • cberghoff
  • cberghoff's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
10 years 7 months ago #99004 by cberghoff
Thanks for looking at this Tony! Sorry for my late reply. 15 hours in the office working on a dissertation proposal today.

I have two groups, MM & VC and each gets the questions coded for their group. Participants answer 2 questions, then I am doing some transformations in a hidden question because I need some responses to be negative numbers (seems this isn't possible directly through response codes, so I'm hoping it works this way). Then, I am calculating the product of the two variables and saving into an Array (Numbers) question. Now I need to sort out the top 3 for MM or the bottom 3 for VC, and I planned on placing the result into a multiple choice question so I can use array filter on the next list (radio) item (and through the rest of the survey). There is no group beginning with the multiple choice, so answers always go to the same item at this point.

Chris
The topic has been locked.
  • cberghoff
  • cberghoff's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
10 years 7 months ago #99009 by cberghoff
Looks like the file didn't attach. Sorry about that, and here it is!

Attachment limesurvey_survey_726669.lss not found

Attachments:
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
10 years 7 months ago #99049 by tpartner
Hi Chris,

I've had a look at the survey and have a couple of questions:

1) Is it possible to run the survey in "group-by-group" mode so we can put the Array (Numbers) and the Multiple Options on the same page?

2) How do you want to handle it if there is no clear "top 3" and "bottom 3"? In testing, I get results like this in the Array (Numbers): -1, -2, -2, 0, -1, -1

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • cberghoff
  • cberghoff's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
10 years 7 months ago #99050 by cberghoff
Hi Tony,

1) Group-by-group is fine, I'll just have to change one or two items prior to this section of the survey. No big deal.

2) The "correct" answer here would be: top = -1, -1, -1; bottom = -2, -2, and any of the -1s, it doesn't matter which. If they were all -1s, then any 3.

And if they are all 0s, then a random 3 (this is the only case where a 0 would get selected). I was playing with sending the data back to my site so I could play with it in PHP (I'm no good with js) and was just shuffling an array of all the options in that case.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
10 years 7 months ago #99057 by tpartner
Regarding the shuffling, how about setting the array to "Random answer order". That way after looping through the array rows and sorting the answers, we will have effective randomization of equal answers.

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • cberghoff
  • cberghoff's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
10 years 7 months ago #99058 by cberghoff
I think that would work. Is there a way to tell the array to display only 3 items (e.g., if all items are 0, display only 3 random ones)?
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
10 years 7 months ago #99059 by tpartner
Well, we could do that with JavaScript but, given the the whole thing will be hidden anyway (I assume), I don't see that it will help.

My thinking was to loop through all "none-0" array rows an build two sorted JavaScript arrays - one ascending and one descending by answer value.

Then we:
- grab the first 3 items from the descending array and click their corresponding items in a multi-options for your MM guys
- grab the first 3 items from the ascending array and click their corresponding items in a second multi-options for your VC guys

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
10 years 7 months ago - 10 years 7 months ago #99065 by tpartner
Okay, here's your survey back with the following changes:

- Switched to "group-by-group" mode
- Moved the multi-options question into the "Comp" group and changed its code to 'top3".
- Added a copy of that question to the "Comp" group with question code "bottom3" (for VC).
- Added the following script to the source of question "Comp" in group "Comp". I think the comments in the script describe what it does fairly well, but ask if you're confused.

Code:
<script type="text/javascript" charset="utf-8">  
  $(document).ready(function(){
    // Identify the questions
    var arrayQ = $('.array-multi-flexi:first');
    var arrayQID = $(arrayQ).attr('id').split('question')[1];
    var topQ = $('.multiple-opt:eq(0)');
    var topQID = $(topQ).attr('id').split('question')[1];
    var bottomQ = $('.multiple-opt:eq(1)');
    var bottomQID = $(bottomQ).attr('id').split('question')[1];
 
    // Loop through the numeric dropdowns and build an array of key:value objects
    var compArr = new Array();    
    $('select', arrayQ).each(function(i) {
      var ansCode = $(this).closest('tr').attr('id').split('X'+arrayQID)[1];
      if($(this).val() != 0) {
        compArr.push({
          name: ansCode, val: $(this).val()
        });
      }
      else {
        $(this).addClass('zero');
      }
    });
 
    // If less than 3 items, pad the array with "0" response(s)
    function padArray() {
      if(compArr.length < 3) {
        var zeroAns = $('select.zero:eq(0)', arrayQ);
        $(zeroAns).removeClass('zero');
        var ansCode = $(zeroAns).closest('tr').attr('id').split('X'+arrayQID)[1];
        compArr.push({
          name: ansCode, val: $(zeroAns).val()
        });
        padArray();
      }
    }
    padArray();
 
    // Sort the array descending
    compArr.sort(function(a,b) {
      return b.val - a.val;
    });
 
    // Loop through the first 3 items and check the corresponding items in the first multi-opt
    $(compArr).each(function(i) {
      if(i < 3) {
        var ansCode = this['name'];
        $('input[id$="X'+topQID+ansCode+'"]').attr('checked', true);
      }
    });
 
    // Sort the array ascending
    var compArrAsc = compArr.reverse();
 
    // Loop through the first 3 items and check the corresponding items in the second multi-opt
    $(compArrAsc).each(function(i) {
      if(i < 3) {
        var ansCode = this['name'];
        $('input[id$="X'+bottomQID+ansCode+'"]').attr('checked', true);
      }
    });
  });
</script>


Attachment limesurvey_survey_726669_TP.lss not found


Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Attachments:
Last edit: 10 years 7 months ago by tpartner.
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
10 years 7 months ago #99066 by tpartner
Oh, one other note - I set the Array (numbers) question to display answers in random order.

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
  • cberghoff
  • cberghoff's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
10 years 7 months ago #99411 by cberghoff
Hey Tony,

Thanks for all your help. Of course, my dissertation committee requested a change, but I was able to modify your code (I only ended up needing the bottom 3).

The js works perfectly, as long as both the number array and checkbox questions are visible. I tried putting the js in an equation question and that worked when hidden, but not if I hid either of the other two items. Indeed, the source code does not include the non-equation-type questions that are set to always hide from users, so obviously the script won't run if included in, or find the items it is looking for, when items are hidden.

I'm working on hiding the questions using CSS (so far unsuccessfully), but this really seems to be an oversight in LS. Shouldn't 'always hide from users' just set the style to display: hidden and perhaps modify the 'required' property, rather than remove the item from the source? Seems that others are expecting a different behavior as well ( www.limesurvey.org/en/forum/design-issue...ding-questions#99067 ) and your comments here lead me to believe you expected something different too.

Any suggestions?

Thanks,
Chris
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose