NOTE: This integration requires knowledge of the JavaScript programming language.

Introduction

This describes how to embed the morphii technology into a Decipher survey. This integration encapsulates most of the the coding needed. Note that this is not the only way to integrate morphii into a Decipher survey, but this document focuses on using the integration.

Limitations

The integration does have limitations. This does not mean that these things cannot be done, just they are limitations for this integration implementation.

  • Marking morphii questions as required is not supported.
  • Requiring comments for morphii questions is not supported.
  • The integration only supported on modern browsers. No support for old browsers such as IE8.

Integration

Morphii Questions

Decipher survey questions that are associated with the morphii widget should be Comment (cm) type questions.

Comment(cm)

Edit XML

You can also add morphii questions via the Edit XML section.

Edit XML

Loading Integration Script

Add the Decipher integration and Widget JavaScript source location to the top of the survey definition. Use the Decipher directive ss:includeJS. If you already have JavaScript listed in a ss:includeJS then add the 2 links below to your existing links.

ss:includeJS="https://widget.morphii.com/v2/morphii-widget.min.js,https://survey-integration.morphii.com/v1/decipher-integration.min.js"

Include JS

JavaScript

The integration requires that JavaScript be added to the Decipher survey. This JavaScript should be contained in a <style mode="after" name="respview.client.js"> tag.

NOTE: This JavaScript is executed for every page load. So if you have a multi-page survey, each time the user advances to the next page this JavaScript will execute if a morphii question is on the page that is loading.

JavaScript

Below is canned JavaScript. There are multiple properties that need to be modified in the following code.

  1. Morphii account_id, client_key, respondent_id, survey_id, and session_id values must be entered.
  2. The questions array needs to be updated. This is where morphiis are associated with each question. The morphii ids for each question may be different than the ones listed in this sample.
  3. Optional: The preview property is either true or false. If omitted the default value is false.
  4. Optional: The additional_info property with: audience, category, and timing.
  5. Optional: custom logic when a morphii is selected can be added to the function onMorphiiSelectionChange.
  6. Optional: custom logic when a user types into the morphii widget comment field the code will be in the function onMorphiiCommentChange.

NOTE: The with attribute on the style tag. The with attribute should contain the label for each morphii question in the survey. In this example, there are 2 morphii questions; cm5 and cm7.

<style mode="after" name="respview.client.js" with="cm5,cm7" wrap="ready"><![CDATA[

  // Configurable values: account_id, client_key, additional_info, and questions
  var integrationParams = {
    account_id: '<ACCOUNT ID HERE>',
    client_key: '<CLIENT KEY HERE>',
    preview: false,
    additional_info: {
      audience: 'customer',
      category: 'satisfaction',
      timing: 'post-event'
    },
    respondent_id: '<RESPONDENT ID HERE>',
    survey_id: '<SURVEY ID HERE>',
    session_id: '<SESSION ID HERE>',
    callbacks: {
      selection_change: onSelectionChange,
      comment_change: onCommentChange
    },
    questions: [
      {
        id: 'cm5',
        comment: {
          show: true,
          maxlength: 512,
          label: {
            en: 'Want to explain that feeling?'
          }
        },
        slider: {
          show_animation: true
        },
        morphii_ids: [
          { id: '6202184382145363968', name: { en: 'Excited' } },
          { id: '6362666072115564544', name: { en: 'Delighted' } },
          { id: '6363734358316589056', name: { en: 'Frustrated' } },
          { id: '6363735117617217536', name: { en: 'Disgusted' } },
          { id: '6363735353273270272', name: { en: 'Worried' } },
          { id: '6363488681244622848', name: { en: 'Disappointed' } },
          { id: '6202184384594837504', name: { en: 'Meh' } }
        ],
        hidden_action_ids: {
          id: 'cm5_morphii_id',
          intensity: 'cm5_morphii_intensity',
          name: 'cm5_morphii_name',
          question: 'cm5_morphii_question',
          comment: 'cm5_morphii_comment'
        }
      },
      {
        id: 'cm7',
        comment: {
          show: true,
          maxlength: 512,
          label: {
            en: 'Want to explain that feeling?'
          }
        },
        morphii_ids: [
          { id: '6202184382145363968', name: { en: 'Excited' } },
          { id: '6362666072115564544', name: { en: 'Happy' } },
          { id: '6363488681244622848', name: { en: 'Sad' } },
          { id: '6363734358316589056', name: { en: 'Angry' } },
          { id: '6363735353273270272', name: { en: 'Anxious' } },
          { id: '6202184384594837504', name: { en: 'Meh' } }
        ],
        hidden_action_ids: {
          id: 'cm7_morphii_id',
          intensity: 'cm7_morphii_intensity',
          name: 'cm7_morphii_name',
          question: 'cm7_morphii_question',
          comment: 'cm7_morphii_comment'
        }
      }
    ]
  };

  function onSelectionChange(event) {
    // Add custom logic when morphii is selected.
  }

  function onCommentChange(event) {
    // Add custom logic when text is entered into comment field.
  }

  if (!window._morphiiIntegration) {
    window._morphiiIntegration = new Morphii.DecipherIntegration();
    if (window._morphiiIntegration) {
      window._morphiiIntegration.init(integrationParams, function(error, results) {
        if (error) {
          console.log('integration error: ' + JSON.stringify(error, null, 2));
          alert('There was an error loading the survey. Please try again later.');
        }
        else {
          console.log('integration results: ' + JSON.stringify(results, null, 2));
        }
      });
    }
  }
]]></style>

Account Id and Client Key

The Vizbii team will provide the account id and client key when the account has been provisioned. These values will look something like:

var account_id = '15521928';
var client_key = 'db055eeb-af22-5c2b-b2df-e11eec55c789';

Preview

When testing your Decipher survey, it is best to set the preview property in the JavaScript to true. This will mark reaction results as testing and omit them in final analysis results. Do not forget to remove this property or set it to false before going live with your survey. When this flag is set to true you will see the following message output in the console: INFO: Morphii integration is currently in PREVIEW mode.

var integrationParams = {
  account_id: '<ACCOUNT ID HERE>',
  client_key: '<CLIENT KEY HERE>',
  preview: true,
  ...
};

Respondent Id

The respondent_id should contain the unique id of the respondent taking the survey.

Survey Id

The survey_id should contain the unique id of this survey. It would be best if this value can be pulled via JavaScript instead of hardcoding.

Session Id

The session_id should contain the unique id of this session. You could use the same value as the respondent_id.

Additional Information

The additional_info object contains information about items like audience, category, and timing. Valid property values:

  • audience: ‘customer’, ‘employee’, ‘patient’, ‘community’, ‘general’, ‘other’
  • category: ‘satisfaction’, ‘engagement’, ‘hr’, ‘mood’
  • timing: ‘pre-event’, ‘during-event’, ‘post-event’, ‘n/a’
var additional_info = {
  audience: 'customer',
  category: 'satisfaction',
  timing: 'post-event'
};

Questions Array

The questions array contains objects that define the morphiis to use for specific questions.

var questions = [
  {
    id: 'cm5',
    comment: {
      show: true,
      maxlength: 512,
      label: {
        en: 'Want to explain that feeling?'
      }
    },
    slider: {
      show_animation: true
    },
    morphii_ids: [
      { id: '6202184382145363968', name: { en: 'Excited' } },
      { id: '6362666072115564544', name: { en: 'Delighted' } },
      { id: '6363734358316589056', name: { en: 'Frustrated' } },
      { id: '6363735117617217536', name: { en: 'Disgusted' } },
      { id: '6363735353273270272', name: { en: 'Worried' } },
      { id: '6363488681244622848', name: { en: 'Disappointed' } },
      { id: '6202184384594837504', name: { en: 'Meh' } }
    ],
    hidden_action_ids: {
      id: 'cm5_morphii_id',
      intensity: 'cm5_morphii_intensity',
      name: 'cm5_morphii_name',
      question: 'cm5_morphii_question',
      comment: 'cm5_morphii_comment'
    }
  },
  {
    id: 'cm7',
    comment: {
      show: true,
      maxlength: 512,
      label: {
        en: 'Want to explain that feeling?'
      }
    },
    morphii_ids: [
      { id: '6202184382145363968', name: { en: 'Excited' } },
      { id: '6362666072115564544', name: { en: 'Happy' } },
      { id: '6363488681244622848', name: { en: 'Sad' } },
      { id: '6363734358316589056', name: { en: 'Angry' } },
      { id: '6363735353273270272', name: { en: 'Anxious' } },
      { id: '6202184384594837504', name: { en: 'Meh' } }
    ],
    hidden_action_ids: {
      id: 'cm7_morphii_id',
      intensity: 'cm7_morphii_intensity',
      name: 'cm7_morphii_name',
      question: 'cm7_morphii_question',
      comment: 'cm7_morphii_comment'
    }
  }
];

id

The id property is the label of the comment Decipher element. This can be found in the Edit Survey or XML area of the Build menu.

comment

The comment property is used to configure the comment field. It contains 3 properties:

  • show: Flag to display the morphii comment field or not. Default: false
  • maxlength: The max character length of the comment field. Default: 512
  • label: The property that holds the text in each supported language. The label above the comment field. Each translation is defined separately. The en version of the label is required if any other language is declared. Default: Please leave a comment

Example:

var comment: {
  show: true,
  maxlength: 10,
  label: {
    en: 'Please leave a comment',
    es: 'Por favor deja un comentario',
    zh: '请发表评论'
  }
};

slider

The slider property is used to configure the the initial intensity and if the slider should animate when a morphii is selected.

  • initial_intensity: The initial intensity of the morphii when selected. The number must be between 0 and 1. Default: 0.2
  • show_animation: Flag to animated the slider/morphii when selected. Default: false

Example:

var slider = {
  initial_intensity: 0.2,
  show_animation: true
};

morphii_ids

The morphii_ids property is an array of morphii objects to use for the question. The object contains the following properties:

  • id: This property is required. It is the unique id of the morphii.
  • name: The property that holds the morphii name for each supported language. Each translation is defined separately. The en translation of the name is required if any other language is declared. If omitted the default morphii name will be used.
  • weight: An arbitrary integer value assigned to this morphii. If omitted the value will be 0. Setting this property is helpful if using the morphii selection callback.

Example:

// Define custom names.
var morphiiIds1 = [
  {
    id: '6363734358316589056',
    name: {
      en: 'Angry',
      es: 'Enojado',
      zh: '愤怒'
    },
    weight: 1
  },
  {
    id: '6362666072115564544',
    name: {
      en: 'Happy',
      es: 'Contento',
      zh: '快乐'
    },
    weight: 2
  },
  {
    id: '6363488681244622848',
    name: {
      en: 'Sad',
      es: 'Triste',
      zh: '伤心'
    },
    weight: 3
  }
];

// Use default names.
var morphiiIds2 = [
  { id: '6363734358316589056', weight: 1 },
  { id: '6362666072115564544', weight: 2 },
  { id: '6363488681244622848', weight: 3 },
  { id: '6363735117617217536', weight: 4 },
  { id: '6362674737212084224', weight: 5 }
];

hidden_action_ids

The hidden_action_ids property is used to configure the Hidden Input Elements that are mapped to this question. The integration will hide these text survey elements when the page loads.

  • id: The label of the text element to store the selected morphii id.
  • intensity: The label of the text element to store the selected morphii intensity.
  • name: The label of the text element to store the selected morphii name.
  • question: The label of the text element to store the question text.
  • comment: The label of the text element to store the comment, if one is entered.

NOTE: If a property is omitted or the ID is incorrect, that specific data will not be stored in the Decipher database.

Example:

var hidden_action_ids = {
  id: 'cm5_morphii_id',
  intensity: 'cm5_morphii_intensity',
  name: 'cm5_morphii_name',
  question: 'cm5_morphii_question',
  comment: 'cm5_morphii_comment'
};

The id for the hidden input element can be found in the Edit Survey or XML area of the Build menu. These are defined using Decipher text elements. It is recommended that the text element labels use the pattern: (comment element label) + _morphii_id. For example, the morphii question that is associated with the comment element cm5 would be:

  • cm5_morphii_id
  • cm5_morphii_intensity
  • cm5_morphii_name
  • cm5_morphii_comment
  • cm5_morphii_question

Each of these text elements can be defined in the survey XML. These elements must be defined on the same page as the morphii question.

<text
  label="cm5_morphii_id">
  <title>cm5_morphii_id</title>
</text>

<text
  label="cm5_morphii_intensity">
  <title>cm5_morphii_intensity</title>
</text>

<text
  label="cm5_morphii_name">
  <title>cm5_morphii_name</title>
</text>

<text
  label="cm5_morphii_question">
  <title>cm5_morphii_question</title>
</text>

<text
  label="cm5_morphii_comment">
  <title>cm5_morphii_comment</title>
</text>

Edit XML

Morphii Selection Change Callback

The onMorphiiSelectionChange function is for custom logic when a morphii is selected. The function is passed the morphii selection event. This data contains properties to identify which morphii was select/unselected and which target the morphii is associated with.

Example:

{
  "selection_required_valid": true,
  "type": "selection_changed",
  "widget": {
    "id": "f0f3c13d-3bc8-449b-bce1-88a6b9362d36",
    "target_id": "cm5",
    "morphii": {
      "selected": true,
      "weight": "2"
    }
  }
}

The event properties:

  • selection_required_valid: This property indicates that all selection requirements have been met across all morphii widgets on the page.
  • type: The type of event. This value will be selection_changed.
  • widget: Information about the specific widget firing the event.
    • id: The unique id of the widget. This property is not valid for this survey integration implementation.
    • target_id: The id of the target associated with this widget. For this implementation this will the label of the Decipher comment element associated with the widget. For example, cm5.
    • morphii: Information about the specific morphii in the widget.
      • selected: A flag if the morphii is selected or not.
      • weight: The weight value assigned to this morphii in the Morphii Ids section. This value will help determine which morphii was selected/unselected in the list.

Morphii Comment Change Callback

The onMorphiiCommentChange function is for custom logic when a user changes text in the morphii widget comment field. The function is passed the morphii comment changed event. This data contains properties to identify the change to the comment text and which target the morphii is associated with.

Example:

{
  "comment_required_valid": true,
  "type": "comment_changed",
  "widget": {
    "id": "f0f3c13d-3bc8-449b-bce1-88a6b9362d36",
    "target_id": "cm5",
    "comment": {
      "required": false,
      "length": 9,
      "value": "Test text"
    }
  }
}

The event properties:

  • comment_required_valid: This property indicates that all selection requirement have been met across all morphii widgets on the page.
  • type: The type of event. This value will be comment_changed.
  • widget: Information about the specific widget firing the event.
    • id: The unique id of the widget. This property is not valid for this survey integration wrapper implementation.
    • target_id: The id of the target associated with this widget. For this implementation this will the label of the Decipher comment element associated with the widget. For example, cm5.
    • comment: Information about the specific comment in the widget.
      • required: A flag indicating if the comment field was required or not.
      • length: The length of the text currently in the comment field.
      • value: The text value currently in the comment field.

Exporting Survey Data

When exporting Decipher survey data to a CVS, the morphii data will be included in the export. The column names will map to the hidden_action_ids values.

Data Export

Testing

When testing your Decipher survey, it is best to set the preview property in the JavaScript to true. This will mark reaction results as testing and omit them in final analysis results. Do not forget to remove this property or set it to false before going live with your survey. For example:

var integrationParams = {
  account_id: '<ACCOUNT ID HERE>',
  client_key: '<CLIENT KEY HERE>',
  preview: true,
  ...
};

Integration Functions

This integration currently provides one public function which is used to initialize the integration.

init(params, callback)

This function initializes the integration.

Parameters:

  • params: The parameters defining the integration.
  • callback: A callback for determining if the integration initialized correctly.

Example:

// Configurable values: account_id, client_key, additional_info, and questions
var integrationParams = {
  account_id: '<ACCOUNT ID HERE>',
  client_key: '<CLIENT KEY HERE>',
  preview: false,
  additional_info: {
    audience: 'customer',
    category: 'satisfaction',
    timing: 'post-event'
  },
  respondent_id: '<RESPONDENT ID HERE>',
  survey_id: '<SURVEY ID HERE>',
  session_id: '<SESSION ID HERE>',
  callbacks: {
    selection_change: onSelectionChange,
    comment_change: onCommentChange
  },
  questions: [
    {
      id: 'cm5',
      comment: {
        show: true,
        maxlength: 512,
        label: {
          en: 'Want to explain that feeling?'
        }
      },
      slider: {
        show_animation: true
      },
      morphii_ids: [
        { id: '6202184382145363968', name: { en: 'Excited' } },
        { id: '6362666072115564544', name: { en: 'Delighted' } },
        { id: '6363734358316589056', name: { en: 'Frustrated' } },
        { id: '6363735117617217536', name: { en: 'Disgusted' } },
        { id: '6363735353273270272', name: { en: 'Worried' } },
        { id: '6363488681244622848', name: { en: 'Disappointed' } },
        { id: '6202184384594837504', name: { en: 'Meh' } }
      ],
      hidden_action_ids: {
        id: 'cm5_morphii_id',
        intensity: 'cm5_morphii_intensity',
        name: 'cm5_morphii_name',
        question: 'cm5_morphii_question',
        comment: 'cm5_morphii_comment'
      }
    },
    {
      id: 'cm7',
      comment: {
        show: true,
        maxlength: 512,
        label: {
          en: 'Want to explain that feeling?'
        }
      },
      morphii_ids: [
        { id: '6202184382145363968', name: { en: 'Excited' } },
        { id: '6362666072115564544', name: { en: 'Happy' } },
        { id: '6363488681244622848', name: { en: 'Sad' } },
        { id: '6363734358316589056', name: { en: 'Angry' } },
        { id: '6363735353273270272', name: { en: 'Anxious' } },
        { id: '6202184384594837504', name: { en: 'Meh' } }
      ],
      hidden_action_ids: {
        id: 'cm7_morphii_id',
        intensity: 'cm7_morphii_intensity',
        name: 'cm7_morphii_name',
        question: 'cm7_morphii_question',
        comment: 'cm7_morphii_comment'
      }
    }
  ]
};

function onSelectionChange(event) {
  // Add custom logic when morphii is selected.
}

function onCommentChange(event) {
  // Add custom logic when text is entered into comment field.
}

if (!window._morphiiIntegration) {
  window._morphiiIntegration = new Morphii.DecipherIntegration();
  if (window._morphiiIntegration) {
    window._morphiiIntegration.init(integrationParams, function(error, results) {
      if (error) {
        console.log('integration error: ' + JSON.stringify(error, null, 2));
        alert('There was an error loading the survey. Please try again later.');
      }
      else {
        console.log('integration results: ' + JSON.stringify(results, null, 2));
      }
    });
  }
}