ssum-berkeley
ssum-berkeley

Reputation: 110

Carry forward new rank order from Pick Group Rank selected choices to Slider

I am working on Pick, Group and Rank question type wherein I want to carry forward the selected drag and drop choices in the new rank order as answer options to the following slider bar question.

I managed to use Qualtric's "Carry Forward" feature to display only the selected choices, but it retains the old order, not the new rank order.

In this working example, if you drag options "b", "a", and "d" to the PGR group box, the slider options will only display "a", "b", and "d", but in that order. How can I get the slider options to display the selected choices in the new order?

I am trying the following approach but get stuck at step 2.

  1. Multi-answer checkboxes -> carry forward selected choices using Qualtrics' function to
  2. Rank order -> carry forward to
  3. Sliders, where I use JavaScript to replace the slider labels with an array of sorted selected choices (according to the new rank order assigned in 2).

Step 3 works with an array that I declared in the JavaScript code.

   var choicesObject = this.getQuestionInfo().Choices;
   //choices is the array of choiceids
   var choices = Object.keys(choicesObject);
   var Qno = choices.length;
   var test = ['this', 'is', 'rad'];

   for (var x = 0; x < Qno; x++) {
     var id = choices[x];
     //var y = id + 1;
     var qid = "QID12-" + id + "-label";
     document.getElementById(qid).innerHTML = test[x];
   }
// This works

However, I have not figured out how to save the new rank order, and description in the environment as an array, or even as embedded data. I've tried saving it in an 2D array, sorting by rank and then saving it into embedded data fields as instructed here.

This is my code in a blank page after the Rank question:

   // hide next button
      $('NextButton') && $('NextButton').hide();

      // store rank in first column, description in second column of array "choice"

      // le was saved as embedded data from Rank question to inform the current code how many choices to loop through

      var le = '${e://Field/gp1length}';
      var len = parseInt(le);

      var choiceArray = [];

      // create blank 2D array containing descriptions and rank orders
      for (var x = 0; x < len; x++) {
        choiceArray[x] = [];
        for (var y = 0; y < 2; y++) {
          choiceArray[x][y] = 0;
        }
      }

      // this does not work, the array contains NaNs
      for (var x = 0; x < len; x++) {
        var y = x + 1;
        var rank = "${q://QID11/ChoiceNumericEntryValue/x" + y + "}";
        var desc = "${q://QID11/ChoiceDescription/x" + y + "}";
        choiceArray[x][0] = parseInt(rank);
        choiceArray[x][1] = desc;
      }

      // attempt to sort array by rank order column
      choiceArray = choiceArray.sort(function(a, b) {
        return a[0] - b[0];
      });

      for (var x = 0; x < len; x++) {
        var y = x + 1;
        var name = "gp1r" + y;
        Qualtrics.SurveyEngine.setEmbeddedData(name, choiceArray[x][1]);
      }

      // advance to next screen
      this.clickNextButton();

But retrieving choiceValues by concatenating choice-ids with a + does not work in Qualtrics. More ever, as I am using the carry forward function, the choice-ids are remnants from the first multiple choice question, so a for loop strategy is not working as they do not go in sequential order (i.e. not 1, 2, 3, 4...).

I would greatly appreciate any help and suggestions!

Upvotes: 0

Views: 1046

Answers (2)

T. Gibbons
T. Gibbons

Reputation: 5029

You would have to pipe the rankings into the slider question's JavaScript and rearrange the sliders' slider containers based on the rankings.

Update based on updated question:

You don't need an intermediate page or embedded variables. Not having them will keep your response data clean. You can pipe the ranks into an array, remove the NaNs, sort, and reorder the sliders. jQuery makes this easier. Just one script on your slider question:

Qualtrics.SurveyEngine.addOnload(function() {
    var ranks = [
        {"choice":"xx1", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x1}")},
        {"choice":"xx2", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x2}")},
        {"choice":"xx3", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x3}")},
        {"choice":"xx4", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x4}")},
        {"choice":"xx5", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x5}")},
        {"choice":"xx6", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x6}")},
        {"choice":"xx7", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x7}")},
        {"choice":"xx8", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x8}")},
        {"choice":"xx9", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x9}")},
        {"choice":"xx10", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x10}")},
        {"choice":"xx11", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x11}")},
        {"choice":"xx12", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x12}")},
        {"choice":"xx13", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x13}")},
        {"choice":"xx14", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x14}")},
        {"choice":"xx15", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x15}")},
        {"choice":"xx16", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x16}")},
        {"choice":"xx17", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x17}")},
        {"choice":"xx18", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x18}")},
        {"choice":"xx19", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x19}")},
        {"choice":"xx20", "rank": parseInt("${q://QID68/ChoiceNumericEntryValue/x20}")}
    ];
    var tbody = jQuery("#"+this.questionId+" div.ChoiceStructure > table.sliderGrid > tbody");
    var cleanRanks = [];
    jQuery.each(ranks, function(index) { if(!isNaN(this["rank"])) cleanRanks.push(this); });    //remove NaNs
    cleanRanks.sort(function(a,b) { return a.rank - b.rank; }); //sort by rank
    jQuery.each(cleanRanks, function() {
        tbody.append(tbody.find("tr[choiceid="+this["choice"]+"]"));    //order sliders
    });
});

Working example survey.

Update 2:

I've updated the code above to change the removal of NaNs from the array. Also, extended number of choices to 20.

Upvotes: 1

ssum-berkeley
ssum-berkeley

Reputation: 110

I managed to figure it out with no intermediate page, and no embedded data as what T.Gibbons suggested. The approach is very similar to his suggestion, but with no jQuery, and uglier code, as I am very new to JavaScript. I just need to add the following script to the slider question's JavaScript box:

Qualtrics.SurveyEngine.addOnload(function() {
   var choicesObject = this.getQuestionInfo().Choices;
   //choices is the array of choiceids
   var choices = Object.keys(choicesObject);

   rankArray = [
     "${q://QID11/ChoiceNumericEntryValue/x1}",
     "${q://QID11/ChoiceNumericEntryValue/x2}",
     "${q://QID11/ChoiceNumericEntryValue/x3}",
     "${q://QID11/ChoiceNumericEntryValue/x4}",
     "${q://QID11/ChoiceNumericEntryValue/x5}"
   ];

var rankArray = rankArray.filter(function(n) {
 return n != ''
   });

descArray = [
     "${q://QID11/ChoiceDescription/x1}",
     "${q://QID11/ChoiceDescription/x2}",
     "${q://QID11/ChoiceDescription/x3}",
     "${q://QID11/ChoiceDescription/x4}",
     "${q://QID11/ChoiceDescription/x5}"
  ];

   var descArray = descArray.filter(function(n) {
     return n != ''
   });

   var all = [];

   for (var i = 0; i < descArray.length; i++) {
     all.push({
       'rankArray': rankArray[i],
       'descArray': descArray[i]
     });
   }

   all.sort(function(a, b) {
     return a.rankArray - b.rankArray;
   });

   rankArray = [];
   descArray = [];

   for (var i = 0; i < all.length; i++) {
     rankArray.push(all[i].rankArray);
     descArray.push(all[i].descArray);
   }

   for (var x = 0; x < descArray.length; x++) {
     var id = choices[x];
     var qid = "QID12-" + id + "-label";
     document.getElementById(qid).innerHTML = descArray[x];
   }
});

Upvotes: 0

Related Questions