Replicating Multiple Conditional Display Variables in Sawtooth using Javascript

Version 6.4 of Software’s SSI Web allows you to use conditional relationships to display specific text based on the combination of up to four separate attributes. However, for a recent project I did where I needed to combine the results of seven attributes in order to display a certain price, the built in capabilities wasn’t enough and I had to use to achieve my goal. In case anyone is interested, here is (basically) how I did it.

The Attributes

For my study I had a total of eight attributes. Seven of them were binary product features (either the feature was included or it wasn’t), and the ninth was the price level. The structure basically looked something like this:

Feature (Included or Not Includes)
Feature 2 (Included or Not Includes)
Feature 3 (Included or Not Includes)
Feature 4 (Included or Not Includes)
Feature 5 (Included or Not Includes)
Feature 6 (Included or Not Includes)
Feature 7 (Included or Not Includes)
Price Level (L1,L2,L3,L4,L5)

What was tricky here is that I wanted to be able to display different ranges of prices depending on how many different Features were included. That is, products that only included one feature would be tested at five specific price points, while products that included three of the features (doesn’t matter which ones) would be tested at a different set of price points.

Think of it as if I had an ice-cream store and that I had seven different flavors of ice cream for you to choose from. You could have anywhere from one scoop to seven scoops, and your pricing would be determined based on the number of scoops of ice cream you buy — not by which flavors you choose.

If we were talking about just three different features (or three different flavors of ice cream) it would be easy enough to use the internal conditional display functionality (three features plus a price level variable = four attributes). I would simply calculate all of the prices for each combination of variables and hard code them into the conditional relationship tool. However, since I needed to be able to include eight different variables in the mix, I needed to go another route.

One possibility was to combine some of my binary attributes. So instead of giving each of the seven features its own attribute, I could combine four of the attributes into one “mega attribute” which included every possible combination of the four features, like this:

Conjoint method of forcing the seven product features into two attributes.

So what I’ve done above is take four of the Features (F1-F4) and infused them into one attribute with 16 different levels. I’ve then taken the other three features (F5-F7) and infused them into a second attribute with 8 levels. The remaining attribute (price level) goes into the third attribute, and it is then fairly easy to combine the three variables using the built in conditional pricing tool.

However, this solution didn’t seem particularly elegant, and not being a mathematical genius I couldn’t say whether doing this would really achieve what I was try to accomplish. I really wanted to leave each product feature as its own attribute, so I had to come up with another way to calculate the prices on the fly without being able to use the built in tool.

The Javascript Method

The solution I came up with basically involved using the Free Format question type to stuff the value of each attribute (in each scenario) into Javascript variables, which I could then do math with to set the appropriate price level based on the number of features which were included.

Setting up the Attributes. I started by setting the display levels of each of my attributes to something that Javascript could easily work with — in this case, 1s (for when the feature was included) and 0s (when the feature was not included. That made it easy to determine the total number of features that were included by simply adding up the values that SSI Web inserted into the web page. I did something similar with my pricing variable — instead of putting in something like “Level 1” or “Level 2” I just put the numbers 1,2,3,4,5 (for each of my five levels.

Setting up the Free Format Questions. I then inserted Free Format questions for each question in the “Write Questionnaire” section (see the SSI Web documentation for a detailed explanation of how this works).

function col1F1()       {return '[%CBCDesignLevelText(CBCRAN1,1,1)%]';}
function col1F2()       {return '[%CBCDesignLevelText(CBCRAN1,1,2)%]';}
function col1F3()       {return '[%CBCDesignLevelText(CBCRAN1,1,3)%]';}
function col1F4()       {return '[%CBCDesignLevelText(CBCRAN1,1,4)%]';}
function col1F5()       {return '[%CBCDesignLevelText(CBCRAN1,1,5)%]';}
function col1F6()       {return '[%CBCDesignLevelText(CBCRAN1,1,6)%]';}
function col1F7()       {return '[%CBCDesignLevelText(CBCRAN1,1,7)%]';}
function col1Level()    {return '[%CBCDesignLevelText(CBCRAN1,1,8)%]';}

function col2F1()       {return '[%CBCDesignLevelText(CBCRAN1,2,1)%]';}
function col2F2()       {return '[%CBCDesignLevelText(CBCRAN1,2,2)%]';}
function col2F3()       {return '[%CBCDesignLevelText(CBCRAN1,2,3)%]';}
function col2F4()       {return '[%CBCDesignLevelText(CBCRAN1,2,4)%]';}
function col2F5()       {return '[%CBCDesignLevelText(CBCRAN1,2,5)%]';}
function col2F6()       {return '[%CBCDesignLevelText(CBCRAN1,2,6)%]';}
function col2F7()       {return '[%CBCDesignLevelText(CBCRAN1,2,7)%]';}
function col2Level()    {return '[%CBCDesignLevelText(CBCRAN1,2,8)%]';}

function col3F1()       {return '[%CBCDesignLevelText(CBCRAN1,3,1)%]';}
function col3F2()       {return '[%CBCDesignLevelText(CBCRAN1,3,2)%]';}
function col3F3()       {return '[%CBCDesignLevelText(CBCRAN1,3,3)%]';}
function col3F4()       {return '[%CBCDesignLevelText(CBCRAN1,3,4)%]';}
function col3F5()       {return '[%CBCDesignLevelText(CBCRAN1,3,5)%]';}
function col3F6()       {return '[%CBCDesignLevelText(CBCRAN1,3,6)%]';}
function col3F7()       {return '[%CBCDesignLevelText(CBCRAN1,3,7)%]';}
function col3Level()    {return '[%CBCDesignLevelText(CBCRAN1,3,8)%]';}

I know…I absolutely could have used an array for these variable names and probably saved myself some coding down the line. However, for various reasons relating to other projects this was the easiest and fastest way to capture each of the values.

Now that I had an easy way to access each of the features (for example, I could find out whether Feature 1 was included in the middle scenario by checking the contents of variable col1F1()) I needed some functions to do the math for me.

To find out how many features were included in the scenario, I created a function to add them up:

function CountFeatures(F1,F2,F3,F4,F5,F6,F7) {
var v = Number(F1) + Number(F2) + Number(F3) + Number(F4) + Number(F5) +
        Number(F6) + Number(F6);
return v; }

Note that in the function above, the functions shown in the previous section of code would be pushed into this function, depending on which scenario I was working with.

Once I knew how many features, it was easy enough to return a price using a function like this (in which I pushed in the number of features and the price level):

function lookupprice(pcount, level) {
var lookupval = pcount + '-' + level;
switch(lookupval) {
case '1-1' : return 10;
case '1-2' : return 12;
case '1-3' : return 14;
case '1-4' : return 15;
case '1-5' : return 17;
case '2-1' : return 13;
case '2-2' : return 14;
case '2-3' : return 116;
case '2-4' : return 137;
case '2-5' : return 159;
case '3-1' : return 110;
case '3-2' : return 142;
case '3-3' : return 175;
case '3-4' : return 107;
case '3-5' : return 139;
case '4-1' : return 155;
case '4-2' : return 100;
case '4-3' : return 146;
case '4-4' : return 191;
case '4-5' : return 137;
case '5-1' : return 191;
case '5-2' : return 147;
case '5-3' : return 103;
case '5-4' : return 159;
case '5-5' : return 115;
case '6-1' : return 126;
case '6-2' : return 193;
case '6-3' : return 159;
case '6-4' : return 126;
case '6-5' : return 192;
case '7-1' : return 162;
case '7-2' : return 139;
case '7-3' : return 116;
case '7-4' : return 193;
case '7-5' : return 170;}}

The value returned could then be formatted as money and inserted into the scenario.

This is the basic outline of how I got my project to work — obviously it leaves out several details, such as how to get it onto the page, how to display each of the included features (you do, after all, have to show them which features are included!) but it makes for a fair starting point. If you have specific questions send me a note.

Leave a Reply