Skip to main content

FV Decipher Support

All the topics, resources needed for FV Decipher.

 
FocusVision Knowledge Base

Creating a MaxDiff Question - Alternatives Method

 

1:  About Creating a MaxDiff Question - Alternatives Method

The MaxDiff - alternatives question is a special question type that requires custom modifications to your survey to get it up and running. To create this question in your survey, you will:

  • Setup the design file
  • Setup the quota sheet
  • Copy the MaxDiff - alternatives template into your survey
  • Modify the template according to your design requirements
  • Optionally, paste the MaxDiff virtual question template into your survey
  • Optionally, modify the MaxDiff virtual code template

Before starting the steps in this document you should double check to confirm that the data set should be in the alternatives format. With the alternatives method, a design file with 12 attributes where only 4 are shown, a data file is created that consists of values 1 - 4. This indicates which attribute position of those shown was selected. 

Using the indices method is different in that it indicates which item from the entire list of attributes was selected. If you prefer to create a MaxDiff question with the indices method: click here

If you want to use the survey builder instead of the shell environment to create a MaxDiff question, click here.

2:  Setting up the Design File

You can follow along by downloading this design file. To learn more about the design file setup: click here.

First, we'll extract the attributes from the design file. The attributes are the actual text elements that will be displayed to the respondent. If you're following along with the design file above, then pasted below are all of the attributes to be used in this MaxDiff. The order of attributes is important and each attribute should retain its position relative to the other attributes.

  • 1. Traditional
  • 2. Innovative
  • 3. Steady
  • 4. Fast-paced
  • 5. Technology-oriented
  • 6. Community-focused
  • 7. Industry leader
  • 8. Expert
  • 9. Consultative
  • 10. Customer-focused
  • 11. Revenue-focused
  • 12. Proactive

The next step is to convert the raw design file like one shown above into a tab-delimited text document. This can be done by going to the raw design sheet, selecting "Save as", and choosing the tab-delimited format. In Microsoft Excel, there is an option for this. In LibreOffice Calc, you can save the sheet as comma-separate values (CSV) and select the {TAB} character in the "Field delimiter" dropdown. Verify that your tab-delimited text file is named design.txt. Then edit your file name and manually replace ".txt" with the ".dat" extension and save (design.dat). The design file has now been prepared and you should upload it to the project's directory.

3:  Setting Up the Quota Sheet

Setting up the quotas is relatively easy. Each respondent is assigned a single version and will see however many tasks are present for each version. In our example, there are 10 versions accommodated with 12 tasks. You must create a marker for each version present in your design file. Since ours has 10, we only need to create 10 randomly assigned markers. You may name these markers anything, but it's good practice to name them "ver_1" to "ver_10". It is not uncommon to have around 100 different versions. The final quota setup is illustrated below, in a sheet called "Q24_MaxDiff":

If you change the name of the markers, they should still end with _# where # represents the version number as defined in the design file.

After you have created your quota sheet to match your design, upload quota.xls the file to your project's directory.

The final step is to link everything together in our project's XML. Fortunately, most of the heavy lifting has been been automated for us with a template.

Note that you should only have one quota.xls file uploaded to your system files.  If you’ve already created a quota element in your survey then you will need to download the existing quota file from the field report and create your MaxDiff quota as a new tab in that file and rename and upload as quota.xls.  For information on how to do this, see Quota Structure Download.

4:  Copying the MaxDiff Alternatives Template into the Survey

Copy the following MaxDiff template into your survey.xml to initialize the MaxDiff survey elements. Copy it to the location where the MaxDiff question is deployed. This code sets up the logic and question style necessary to achieve the MaxDiff effect. The next step is to modify this template to match your MaxDiff design.

<note>MaxDiff Alternatives Template --Start--</note>
<exec when="init">
def setupMaxDiffFile(fname, fileDelimiter="\t"):
    try:
        f = open("%s/%s" % (gv.survey.path, fname))
        mdObj = [ line.strip("\r\n").split(fileDelimiter) for line in f.readlines() ]
        d = dict( ("v%s_t%s" % (row[0], row[1]), row[2:]) for row in mdObj )
    except IOError:
        d = {}
    return d

def setupMaxDiffItemsA(d, vt, question, parentLabel):
    items = d[vt]

    print "*****STAFF ONLY*****"
    print "Version_Task: %s" % vt
    for r in question.rows:
        r.text = res[ "%s_mditem%s" % (parentLabel, items[r.index]) ]
        print "Item %s: %s" % (r.index+1, items[r.index])
    </exec>
    
    <exec when="init">Q1_md = setupMaxDiffFile("md_design.dat")</exec>

    <res label="Q1_mditem1">Item 1</res>
    <res label="Q1_mditem2">Item 2</res>
    <res label="Q1_mditem3">Item 3</res>
    <res label="Q1_mditem4">Item 4</res>
    <res label="Q1_mditem5">Item 5</res>
    <res label="Q1_mditem6">Item 6</res>
    <res label="Q1_mditem7">Item 7</res>
    <res label="Q1_mditem8">Item 8</res>
    <res label="Q1_mditem9">Item 9</res>
    <res label="Q1_mditem10">Item 10</res>
    <res label="Q1_mditem11">Item 11</res>
    <res label="Q1_mditem12">Item 12</res>
    <res label="Q1_mditem13">Item 13</res>
    <res label="Q1_mditem14">Item 14</res>
    <res label="Q1_mditem15">Item 15</res>


    <quota overquota="noqual" sheet="Q1_Maxdiff"/>
    
    <number label="Q1_Version" size="3" optional="1" verify="range(1,16)" where="execute">
      <title>Q1 - MaxDiff Version</title>
      <exec>
print p.markers
for x in p.markers:
    if "/Q1_Maxdiff/ver_" in x:
        Q1_Version.val = int(x.split("_")[-1])
        break
      </exec>
    </number>
    <suspend/>
    
    <exec>p.startTime = timeSpent()</exec>

    <loop label="Q1_md_loop" vars="task" randomizeChildren="0">
      <title>Q1 - MaxDiff Loop</title>
      <block label="Q1_md_block" randomize="1">

        <radio label="Q1_[loopvar: task]" adim="cols" grouping="cols" unique="1" ss:questionClassNames="Q1_maxdiff">
          <title>Title update [MDcount]</title>
          <comment>Select one</comment>
          <exec>
setupMaxDiffItemsA( Q1_md, "v%d_t%d" % (Q1_Version.val, [loopvar: task]), Q1_[loopvar: task], "Q1")
p.MDcount = str(Q1_md_loop_expanded.order.index([loopvar: task]-1)+1)
          </exec>

          <col label="best">Most Important</col>
          <col label="worst">Least Important</col>
          <row label="item1">Item 1</row>
          <row label="item2">Item 2</row>
          <row label="item3">Item 3</row>
          <row label="item4">Item 4</row>


<style name="question.header" mode="before">
            <![CDATA[
    <style type="text/css">
    .Q1_maxdiff tr.maxdiff-header-legend {
        background-color: transparent;
        border-bottom: 2px solid #d9d9d9;
    }
    .Q1_maxdiff tr.maxdiff-header-legend th.legend {
        background-color: transparent;
        border: none;
    }
    .Q1_maxdiff tr.maxdiff-row td.element {
        border-left: none;
        border-right: none;
        border-top: none;
        border-bottom: 1px solid #d9d9d9;
        text-align: center;
    }
    .Q1_maxdiff tr.maxdiff-row th.row-legend {
        background-color: transparent;
        border-left: none;
        border-right: none;
        border-top: none;
        border-bottom: 1px solid #d9d9d9;
        text-align: center;
    }
    </style>
            ]]>
</style>
 
<style name="question.top-legend">
            <![CDATA[
\@if ec.simpleList
    $(legends)
\@else
    <$(tag) class="maxdiff-header-legend row row-col-legends row-col-legends-top ${"mobile-top-row-legend " if mobileOnly else ""}${"GtTenColumns " if ec.colCount > 10 else ""}colCount-$(colCount)">
        ${"%s%s" % (legends.split("</th>")[0],"</th>")}
       $(left)
        ${"%s%s" % (legends.split("</th>")[1],"</th>")}
    </$(tag)>
    \@if not simple
  </tbody>
  <tbody>
    \@endif
\@endif
            ]]>
</style>
 
<style name="question.row">
            <![CDATA[
\@if ec.simpleList
    $(elements)
\@else
    <$(tag) class="maxdiff-row row row-elements $(style) colCount-$(colCount)">
        ${"%s%s" % (elements.split("</td>")[0],"</td>")}
        $(left)
        ${"%s%s" % (elements.split("</td>")[1],"</td>")}
    </$(tag)>
\@endif
            ]]>
</style>
  </radio>
      </block>
      
      <looprow label="1">
        <loopvar name="task">1</loopvar>
      </looprow>
      
      <looprow label="2">
        <loopvar name="task">2</loopvar>
      </looprow>
      
      <looprow label="3">
        <loopvar name="task">3</loopvar>
      </looprow>
      
      <looprow label="4">
        <loopvar name="task">4</loopvar>
      </looprow>
      
      <looprow label="5">
        <loopvar name="task">5</loopvar>
      </looprow>
      
      <looprow label="6">
        <loopvar name="task">6</loopvar>
      </looprow>
      
      <looprow label="7">
        <loopvar name="task">7</loopvar>
      </looprow>
      
      <looprow label="8">
        <loopvar name="task">8</loopvar>
      </looprow>
      
      <looprow label="9">
        <loopvar name="task">9</loopvar>
      </looprow>
      
      <looprow label="10">
        <loopvar name="task">10</loopvar>
      </looprow>
      
      <looprow label="11">
        <loopvar name="task">11</loopvar>
      </looprow>
      
      <looprow label="12">
        <loopvar name="task">12</loopvar>
      </looprow>
      
      <looprow label="13">
        <loopvar name="task">13</loopvar>
      </looprow>
      
      <looprow label="14">
        <loopvar name="task">14</loopvar>
      </looprow>
      
      <looprow label="15">
        <loopvar name="task">15</loopvar>
      </looprow>
    
    </loop>
    
    <float label="Q1_Timer" size="15" where="execute">
      <title>Q1 - MaxDiff Timer (Minutes)</title>
      <exec>Q1_Timer.val = (timeSpent() - p.startTime) / 60.0</exec>
    </float>
    
    <note>MaxDiff Alternatives Template --End--</note>

5:  Updating the Template

Let's walk through each section of the code in the template above to get a better understanding of what's going on and update it where necessary so that it matches your MaxDiff question design. Click here to skip the walk through and go to the final result.

5.1:  Beginning of the MAXDIFF Template

This section is for informational purposes only, you do not need to update this code.

def setupMaxDiffFile(fname, fileDelimiter="\t"):
    try:
        f = open("%s/%s" % (gv.survey.path, fname))
        mdObj = [ line.strip("\r\n").split(fileDelimiter) for line in f.readlines() ]
        d = dict( ("v%s_t%s" % (row[0], row[1]), row[2:]) for row in mdObj )

This is the beginning of our MAXDIFF class. It takes in the name of our design file as an argument (e.g. "design.dat"). Line 4 in the code above creates a dictionary object where the key represents the version and task number and the value is the attributes items to display. (e.g. {"v1_t1" : [5,1,11,10], ... } where "v1_t1" means version #1, task #1 and the 4 items to show are 5, 1, 11 and 10.)

5.2:  Calling the Alternatives Function

This section is for informational purposes only, you do not need to update this code.

    def setupMaxDiffItemsA(d, vt, question, parentLabel):
    items = d[vt]

    print "*****STAFF ONLY*****"
    print "Version_Task: %s" % vt
    for r in question.rows:
        r.text = res[ "%s_mditem%s" % (parentLabel, items[r.index]) ]
        print "Item %s: %s" % (r.index+1, items[r.index])

This is the function (setupMaxDiffItemsA) that is called if we are using the alternatives data format. It takes in 4 values, the string corresponding to the items we're going to show in the dictionary that was created (e.g. "v3_t1"), the question to apply the function to (e.g. Q1), and the string representing the <res> tag to reference (e.g. "Q1" for "Q1_mditem_1"). You will see how we call this function in just a moment.

This function prints helpful debugging information in the respondent view. You must be logged in to see this.

5.3:  Updating the Design File Name

<exec when="init">
Q1_md = setupMaxDiffFile("md_design.dat")
</exec>

This is where we initialize the MAXDIFF class. It takes in the name of the design file we uploaded to the project's directory. Update md_design.dat to reflect the name of the design file you uploaded to your project directory.

5.4:  Creating a Resource Tag for Each Attribute Item

Create a resource (<res>) tag for each attribute in the MaxDiff question. Replace the current resource tags in the template with the attribute names in your design. Be sure to keep the naming convention of parentlabel_mditem#. 

<res label="Q1_mditem1">Item 1</res>
<res label="Q1_mditem2">Item 2</res>
<res label="Q1_mditem3">Item 3</res>
<res label="Q1_mditem4">Item 4</res>
<res label="Q1_mditem5">Item 5</res>
<res label="Q1_mditem6">Item 6</res>
<res label="Q1_mditem7">Item 7</res>
<res label="Q1_mditem8">Item 8</res>
<res label="Q1_mditem9">Item 9</res>
<res label="Q1_mditem10">Item 10</res>
<res label="Q1_mditem11">Item 11</res>
<res label="Q1_mditem12">Item 12</res>
<res label="Q1_mditem13">Item 13</res>
<res label="Q1_mditem14">Item 14</res>
<res label="Q1_mditem15">Item 15</res>

For example, here are the the resource tags for the design sample covered in this document:

<res label="Q1_mditem1">Traditional</res>
<res label="Q1_mditem2">Innovative</res>
<res label="Q1_mditem3">Steady</res>
<res label="Q1_mditem4">Fast-paced</res>
<res label="Q1_mditem5">Technology-oriented</res>
<res label="Q1_mditem6">Community-focused</res>
<res label="Q1_mditem7">Industry leader</res>
<res label="Q1_mditem8">Expert</res>
<res label="Q1_mditem9">Consultative</res>
<res label="Q1_mditem10">Customer-focused</res>
<res label="Q1_mditem11">Revenue-focused</res>
<res label="Q1_mditem12">Proactive</res>

5.5:  Globally Updating the MaxDiff Question Label

From within the template, do a global find and replace to replace all instances of Q1 to match your question label.

5.6:  Updating the Sheet Name in the Quota File

The following code calls the "Q1_MaxDiff" quota sheet and will assign the respondent a version number. You should update the sheet name in the quota call to match the sheet name in the quota file you created to track the version.

<quota overquota="noqual" sheet="Q1_MaxDiff"/>

5.7:  Updating the Range Specification

Update the range on the _version question to match the number of versions in the quota for your MaxDiff question. 

<number label="Q1_Version" size="3" optional="1" verify="range(1,16)" where="execute">
      <title>Q1 - MaxDiff Version</title>
      <exec>
print p.markers
for x in p.markers:
    if "/Q1_Maxdiff/ver_" in x:
        Q1_Version.val = int(x.split("_")[-1])
        break
      </exec>
    </number>
    <suspend/>

5.8:  Updating the Sheet Name/Default Version Markers

If you updated the quota sheet name or the default version markers, be sure to update the following line of code (if "/Q1_Maxdiff/ver_" in x:) to reflect your changes.

for x in p.markers:
    if "/Q1_Maxdiff/ver_" in x:
        Q1_Version.val = int(x.split("_")[-1])
        break
      </exec>
    </number>
    <suspend/>
 

 

5.9:  Updating the Question & the Loop

This is our MaxDiff question element. It's incorporated into a <loop> and will run for as many tasks that are provided in the <looprow>s. The <style> tags were shortened for the sake of saving space. They simply re-structure the questions format so that a column is presented on both sides of the row options. Here's a list of items that should be updated to reflect your project design:

  • Update the <radio> question's <title> and <comment> tags.  Title and comment tags represent the question and instruction text (respectively) that displays to the respondents for each task in the MaxDiff.
  • If the client requests to randomize tasks in addition to what the randomization design file is already doing, change the randomizeChildren value to "1". By default it is set to "0" and it is typically left unchanged.
  • Update the question's <col> text (e.g. "Most favorite", "Least favorite").
  • Match the number of rows inside your MaxDiff question to the number of items that you want to show to the respondents. Currently, the template code is set to show 4 items. The text programmed for the rows is what will shown when viewing the report and is overwritten by the setupMaxDiffItemsA function to be the corresponding resource tag that should be seen.
  • Update the number of tasks (looprow) to match the number of tasks in your design file.
<loop label="Q1_md_loop" vars="task" randomizeChildren="0">
   <title>Q1 - MaxDiff Loop</title>
   <block label="Q1_md_block" randomize="1">
   <radio label="Q1_[loopvar: task]" adim="cols" grouping="cols" unique="1" ss:questionClassNames="Q1_maxdiff">
    <title>Title update [MDcount]</title>
    <comment>Select one</comment>
    <exec>
setupMaxDiffItemsA( Q1_md, "v%d_t%d" % (Q1_Version.val, [loopvar: task]), Q1_[loopvar: 
task], "Q1")
p.MDcount = str(Q1_md_loop_expanded.order.index([loopvar: task]-1)+1)
    </exec>
    <col label="best">Most Important</col>
    <col label="worst">Least Important</col>
    <row label="item1">Item 1</row>
    <row label="item2">Item 2</row>
    <row label="item3">Item 3</row>
    <row label="item4">Item 4</row>
    <style name="question.header" mode="before">
        <![CDATA[
        ...
     ]]>
     </style>
     <style name="question.row">
        <![CDATA[
        ...
      ]]>
      </style>
      <style name="question.top-legend">
         <![CDATA[
         ...
       ]]>
       </style>
     </radio>
  </block>

<looprow label="1">  <loopvar name="task">1</loopvar>    </looprow>
<looprow label="2">  <loopvar name="task">2</loopvar>    </looprow>
<looprow label="3">  <loopvar name="task">3</loopvar>    </looprow>
<looprow label="4">  <loopvar name="task">4</loopvar>    </looprow>
<looprow label="5">  <loopvar name="task">5</loopvar>    </looprow>
<looprow label="6">   <loopvar name="task">6</loopvar>    </looprow>
<looprow label="7">   <loopvar name="task">7</loopvar>    </looprow>
<looprow label="8">   <loopvar name="task">8</loopvar>    </looprow>
<looprow label="9">   <loopvar name="task">9</loopvar>    </looprow>
<looprow label="10">  <loopvar name="task">10</loopvar> </looprow>
<looprow label="11">  <loopvar name="task">11</loopvar> </looprow>
<looprow label="12">   <loopvar name="task">12</loopvar> </looprow>

</loop> 

5.10  Recording the Respondent's Time

This section is for informational purposes only, you do not need to update this code.

This is the question where the respondent's time is recorded. It is recorded in minutes and will be available in the report. 

<float label="Q1_Timer" size="15" where="execute">
      <title>Q1 - MaxDiff Timer (Minutes)</title>
      <exec>Q1_Timer.val = (timeSpent() - p.startTime) / 60.0</exec>
    </float>

6:  Results of Template Modifications

Below is the revised code adapted to fit the needs of our example design file. For the sake of a good example, it was renamed to "Q24" instead of "Q1" and uses the alternatives data format. Click here to see a working example of this MaxDiff.

The example design file may be downloaded by clicking here, and the example quota.xls file is available here.

<note>MaxDiff Template --Start--</note>
<exec when="init">
def setupMaxDiffFile(fname, fileDelimiter="\t"):
    try:
        f = open("%s/%s" % (gv.survey.path, fname))
        mdObj = [ line.strip("\r\n").split(fileDelimiter) for line in f.readlines() ]
        d = dict( ("v%s_t%s" % (row[0], row[1]), row[2:]) for row in mdObj )
    except IOError:
        d = {}
    return d

def setupMaxDiffItemsA(d, vt, question, parentLabel):
    items = d[vt]

    print "*****STAFF ONLY*****"
    print "Version_Task: %s" % vt
    for r in question.rows:
        r.text = res[ "%s_mditem%s" % (parentLabel, items[r.index]) ]
        print "Item %s: %s" % (r.index+1, items[r.index])
    </exec>
    
    <exec when="init">Q24_md = setupMaxDiffFile("design.dat")</exec>

    
    <res label="Q24_mditem1">Traditional</res>
    <res label="Q24_mditem2">Innovative</res>
    <res label="Q24_mditem3">Steady</res>
    <res label="Q24_mditem4">Fast-paced</res>
    <res label="Q24_mditem5">Technology-oriented</res>
    <res label="Q24_mditem6">Community-focused</res>
    <res label="Q24_mditem7">Industry leader</res>
    <res label="Q24_mditem8">Expert</res>
    <res label="Q24_mditem9">Consultative</res>
    <res label="Q24_mditem10">Customer-focused</res>
    <res label="Q24_mditem11">Revenue-focused</res>
    <res label="Q24_mditem12">Proactive</res>

    <quota overquota="noqual" sheet="Q24_Maxdiff"/>
    
    <number label="Q24_Version" size="3" optional="1" verify="range(1,10)" where="execute">
      <title>Q24 - MaxDiff Version</title>
      <exec>
print p.markers
for x in p.markers:
    if "/Q24_Maxdiff/ver_" in x:
        Q24_Version.val = int(x.split("_")[-1])
        break
      </exec>
    </number>
    <suspend/>
    
    <exec>p.startTime = timeSpent()</exec>

    <loop label="Q24_md_loop" vars="task" randomizeChildren="0">
      <title>Q24 - MaxDiff Loop</title>
      <block label="Q24_md_block" randomize="1">

        <radio label="Q24_[loopvar: task]" adim="cols" grouping="cols" unique="1" ss:questionClassNames="Q24_maxdiff">
          <title>Title update [MDcount]</title>
          <comment>Select one</comment>
          <exec>
setupMaxDiffItemsA( Q24_md, "v%d_t%d" % (Q24_Version.val, [loopvar: task]), Q24_[loopvar: task], "Q24")
p.MDcount = str(Q24_md_loop_expanded.order.index([loopvar: task]-1)+1)
          </exec>

          <col label="best">Most Important</col>
          <col label="worst">Least Important</col>
          <row label="item1">Item 1</row>
          <row label="item2">Item 2</row>
          <row label="item3">Item 3</row>
          <row label="item4">Item 4</row>


<style name="question.header" mode="before">
            <![CDATA[
    <style type="text/css">
    .Q24_maxdiff tr.maxdiff-header-legend {
        background-color: transparent;
        border-bottom: 2px solid #d9d9d9;
    }
    .Q24_maxdiff tr.maxdiff-header-legend th.legend {
        background-color: transparent;
        border: none;
    }
    .Q24_maxdiff tr.maxdiff-row td.element {
        border-left: none;
        border-right: none;
        border-top: none;
        border-bottom: 1px solid #d9d9d9;
        text-align: center;
    }
    .Q24_maxdiff tr.maxdiff-row th.row-legend {
        background-color: transparent;
        border-left: none;
        border-right: none;
        border-top: none;
        border-bottom: 1px solid #d9d9d9;
        text-align: center;
    }
    </style>
            ]]>
</style>
 
<style name="question.top-legend">
            <![CDATA[
\@if ec.simpleList
    $(legends)
\@else
    <$(tag) class="maxdiff-header-legend row row-col-legends row-col-legends-top ${"mobile-top-row-legend " if mobileOnly else ""}${"GtTenColumns " if ec.colCount > 10 else ""}colCount-$(colCount)">
        ${"%s%s" % (legends.split("</th>")[0],"</th>")}
       $(left)
        ${"%s%s" % (legends.split("</th>")[1],"</th>")}
    </$(tag)>
    \@if not simple
  </tbody>
  <tbody>
    \@endif
\@endif
            ]]>
</style>
 
<style name="question.row">
            <![CDATA[
\@if ec.simpleList
    $(elements)
\@else
    <$(tag) class="maxdiff-row row row-elements $(style) colCount-$(colCount)">
        ${"%s%s" % (elements.split("</td>")[0],"</td>")}
        $(left)
        ${"%s%s" % (elements.split("</td>")[1],"</td>")}
    </$(tag)>
\@endif
            ]]>
</style>
  </radio>
      </block>
      
      <looprow label="1">
        <loopvar name="task">1</loopvar>
      </looprow>
      
      <looprow label="2">
        <loopvar name="task">2</loopvar>
      </looprow>
      
      <looprow label="3">
        <loopvar name="task">3</loopvar>
      </looprow>
      
      <looprow label="4">
        <loopvar name="task">4</loopvar>
      </looprow>
      
      <looprow label="5">
        <loopvar name="task">5</loopvar>
      </looprow>
      
      <looprow label="6">
        <loopvar name="task">6</loopvar>
      </looprow>
      
      <looprow label="7">
        <loopvar name="task">7</loopvar>
      </looprow>
      
      <looprow label="8">
        <loopvar name="task">8</loopvar>
      </looprow>
      
      <looprow label="9">
        <loopvar name="task">9</loopvar>
      </looprow>
      
      <looprow label="10">
        <loopvar name="task">10</loopvar>
      </looprow>
      
      <looprow label="11">
        <loopvar name="task">11</loopvar>
      </looprow>
      
      <looprow label="12">
        <loopvar name="task">12</loopvar>
      </looprow>
               
    </loop>
    
    <float label="Q24_Timer" size="15" where="execute">
      <title>Q24 - MaxDiff Timer (Minutes)</title>
      <exec>Q24_Timer.val = (timeSpent() - p.startTime) / 60.0</exec>
    </float>
    
    <note>MaxDiff Template --End--</note>

7:  Adding a MaxDiff Virtual Question Using a Template

If you have programmed the MaxDiff with the alternatives method and need to also have the data in the indices method, you can use the provided template. Simply add the following virtual code template to the survey.xml file.

<note>MaxDiff Indices Hidden --Start--</note>
    <loop label="vQ1_md_loop" vars="task" randomizeChildren="0" suspend="0">
      <title>vQ1 - MaxDiff Loop</title>
      <block label="vQ1_md_block" randomize="1">
        <number label="vQ1_[loopvar: task]" size="2" where="execute">
          <title>Title update</title>
          <exec>
if Q1_[loopvar: task].best.val is not None and Q1_[loopvar: task].worst.val is not None:

    currentItems = Q1_md["v%d_t[loopvar: task]" % Q1_Version.val]

    vQ1_[loopvar: task].best.val = currentItems[Q1_[loopvar: task].best.val]
    vQ1_[loopvar: task].worst.val = currentItems[Q1_[loopvar: task].worst.val]
          </exec>
          <col label="best">Most Important</col>
          <col label="worst">Least Important</col>
        </number>
      </block>

      <looprow label="1">
        <loopvar name="task">1</loopvar>
      </looprow>

      <looprow label="2">
        <loopvar name="task">2</loopvar>
      </looprow>

      <looprow label="3">
        <loopvar name="task">3</loopvar>
      </looprow>

      <looprow label="4">
        <loopvar name="task">4</loopvar>
      </looprow>

      <looprow label="5">
        <loopvar name="task">5</loopvar>
      </looprow>
      <looprow label="6">
        <loopvar name="task">6</loopvar>
      </looprow>

      <looprow label="7">
        <loopvar name="task">7</loopvar>
      </looprow>

      <looprow label="8">
        <loopvar name="task">8</loopvar>
      </looprow>

      <looprow label="9">
        <loopvar name="task">9</loopvar>
      </looprow>

      <looprow label="10">
        <loopvar name="task">10</loopvar>
      </looprow>

      <looprow label="11">
        <loopvar name="task">11</loopvar>
      </looprow>

      <looprow label="12">
        <loopvar name="task">12</loopvar>
      </looprow>

      <looprow label="13">
        <loopvar name="task">13</loopvar>
      </looprow>

      <looprow label="14">
        <loopvar name="task">14</loopvar>
      </looprow>

      <looprow label="15">
        <loopvar name="task">15</loopvar>
      </looprow>

    </loop>
    <note>MaxDiff Indices Hidden --End--</note>

8:  Updating the Virtual Code Template

You will also need to update this virtual code template to match your MaxDiff question design.

8.1:  Updating the Question Label

From within the conversion template, do a global find and replace to replace all instances of Q1 to match your question label.

8.2:  Updating the Number of Tasks

From within the conversion template, update the number of tasks (looprow) to match the number of tasks in your design file. The conversion template contains 15 tasks.