Have an idea?

Visit Sawtooth Software Feedback to share your ideas on how we can improve our products.

Check if same answer option was selected for multiple questions

Hi everyone,

I have a series  of matching questions on a page where respondents are required to assign brand names to logos.

There are 12 logos (= 12 questions, i.e. dropdown selects in a grid format, grid orientation set to rows)
and 20 Brand names plus a don' know option (=21 answer options).

The issue:
- each brand name should be assigned to one logo only, i.e. each answer option can be selected only once across questions
- this does not apply for the 21st answer option, as the don't know option is allowed multiple times.

I tried this as custom javascript verification:

var logos = 12; // Amount of Logos or questions
var KAValue = 21; // List value of Don't know option
var NonNotApplicableAssignments = [% ListLength(BrandNamesAssigned) %];

var Fragename = "BL02";

var KAcount = 0;
for (var i = 1; i <= logos; i++) {
      if (SSI_GetValue(Fragename + '_r' + i + '_c1') == KAValue) {
          KAcount += 1;
    }
}

if (KAcount + NonNotApplicableAssignments < logos)  {
    strErrorMessage = 'Brand names cannot be assigned to different logos at the same time.';
  }



where I tried to collect all answers that are not =21 (Don't Know) in a list called BrandNamesAssigned as follows:
AIC(BL02_r1_c1)
AIC(BL02_r2_c1)
AIC(BL02_r3_c1)
AIC(BL02_r4_c1)
AIC(BL02_r5_c1)
AIC(BL02_r6_c1)
AIC(BL02_r7_c1)
AIC(BL02_r8_c1)
AIC(BL02_r9_c1)
AIC(BL02_r10_c1)
AIC(BL02_r11_c1)
AIC(BL02_r12_c1)
Remove(BrandNamesToAssign,21)

I think the problem is that this list is only built after submitting the page?
Is there a better way to approach this issue?

Best
Kathrin
asked Apr 15, 2021 by Kathrin (415 points)

1 Answer

0 votes
You are correct that your constructed list will not work correctly unless it were ran on the next page.  Being on the current page, the list will run on those AIC calls when the page loads, see that none of them have been chosen yet, and produce an empty constructed list.  Because of this, we need to use 100% JavaScript for problems like this.

I'm glad to see you've taken a stab at writing your own JavaScript.  Putting constants like the question name and row count at the top of the code is a great choice: if these values have to change in the future, you can easily change these values and be back in business.

You can try out this custom JavaScript verification:

// Params
var rows = 12;
var dontKnowItem = 21;

// Run
var resps = {};
for (var i = 1; i <= rows; i++) {
    var resp = SSI_GetValue('[% QuestionName() %]_r' + i + '_c1');
    if (resp != dontKnowItem && resps[resp]) {
        strErrorMessage = 'Error message...';
        break;
    }
    resps[resp] = true;
}


Notice how we were able to avoid having to create a question name variable by instead using the Sawtooth Script function QuestionName.  This code uses an object to record which responses have been given in previous rows so it can produce an error message if it sees a response it has already seen.

Grid questions come with hidden HTML elements that tell us what rows and columns they include.  If we want to go a step further, we could use this and remove another one of our parameters from the start of the code:

// Params
var dontKnowItem = 21;

// Run
var resps = {};
var rows = $('input[name="hid_row_list_[% QuestionName() %]"]').val().split(',');
rows.forEach(function(row){
    var resp = SSI_GetValue('[% QuestionName() %]_r' + row + '_c1');
    if (resp != dontKnowItem && resps[resp]) {
        strErrorMessage = 'Error message...';
        break;
    }
    resps[resp] = true;
});
answered Apr 15, 2021 by Zachary Platinum Sawtooth Software, Inc. (193,300 points)
...