Introduction

The morphii widget is a convenient way to embed morphiis into a new or existing website. This documentation will provide details on the morphii widget, its options, and functions.

Sample

Sample code is located on the public Github repository: https://github.com/Vizbii/widget-sample. You can also find a working sample here.

Collection

The Collection object is used to embed one or more morphii widgets into a web page. Each widget in the collection can have different configurations.

  • Production: https://widget.morphii.com/v2/morphii-widget.min.js

Collection sample

index.html

<!-- index.html -->
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Widget (v2) Sample</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
    <link href="index.css" rel="stylesheet" type="text/css">
  </head>

  <body>
    <label>Language: </label>
    <select id="language-selection">
      <option value="en-US">English</option>
      <option value="es">Spanish</option>
    </select>

    <div id="target-container">
      <h4 id="q1">How did you feel before your visit?</h4>
      <div id="widget-q1"></div>

      <h4 id="q2">How did you feel after your visit?</h4>
      <div id="widget-q2"></div>

      <div class="center-div">
        <button id="submit-button" type="button" class="btn btn-default">Submit</button>
      </div>
    </div>

    <script src="https://widget.morphii.com/v2/morphii-widget.min.js"></script>
    <script src="index.js"></script>
  </body>
</html>

index.js

// index.js
(function(window, document, undefined) {
  'use strict';

  // Define the widget collection.
  var collection = null;

  // Documentation: https://docs.morphii.com/widget_documentation_2_0.html
  // Define the morphii ids that will be used in the widgets.
  // Publicly available: https://docs.morphii.com/morphii_list.html
  var morphiiIds = [
    { id: '6533704109450043392_2' },
    { id: '6533717691772903424' },
    { id: '6533717823323430912' },
    { id: '6533717983040057344' },
    { id: '6533718112033349632' },
    { id: '6533718265862295552' },
    { id: '6533723337566945280' }
  ];

  // Setup the widget when the page is ready.
  window.onload = function() {
    createWidget();

    // Add change event to language selection.
    var langSelection = document.getElementById('language-selection');
    if (langSelection) {
      langSelection.addEventListener('change', langSelectionChange);
    }

    // Call submit function when Submitt button is clicked.
    var submitButton = document.getElementById('submit-button');
    if (submitButton) {
      submitButton.addEventListener('click', submit);

      // Disable submit button util a morphii is selected.
      submitButton.setAttribute('disabled', 'disabled');
    }
  }

  function langSelectionChange(event) {
    if (collection) {
      var lang = document.getElementById('language-selection').value;
      collection.language(lang);
    }
  }

  // Define the widget options.
  function widgetOptions(qId) {
    return {
      div_id: 'widget-' + qId,
      morphii: {
        ids: morphiiIds,
        show_name: true,  // Set to `false` to not display morphii names.
        wrap_name: true
      },
      target : {
        id: qId,
        type : 'question'
      },
      comment: {
        show: false,   // Set to `true` to see comment field.
        required: false
      },
      slider: {
        initial_intensity: 0.2,
        show_animation: true,
        anchor_labels: {
          show: true
        }
      },
      selection: {
        required: true  // Set to `false` to not require selection.
      },
      instructions: {
        show: true
      },
      options: {
        stage: 'test'
      }
    };
  }

  function createWidget() {
    var collectionOptions = {
      client_key: '349ec444-474f-4084-9dcd-b373ddb444cd',
      account_id: '17254444',
      project: {
        id: 'widget-sample',
        description: 'Sample widget code.'
      },
      application: {
        name: 'sample-application',
        description: 'Sample demo of Widget v2.',
        version: '1.0'
      },
      user: {
        id: 'user-id'
      },
      callbacks: {
        error: errorCallback,
        selection_change: selectionChangeCallback
      }
    };

    collection = new MorphiiWidgets.Collection();
    collection.init(collectionOptions, function(error, valid) {
      if (valid === true) {
        // Add the widget to each question on the page.
        ['q1', 'q2'].forEach(function(qId) {
          var option = widgetOptions(qId);
          collection.add(option, function(error, results) {
            if (error) {
              console.log('Collection add error: ' + JSON.stringify(error, null, 2));
            }
            else {
              var divId = results.configuration.div_id;
              var targetId = results.configuration.target.id;

              // The target id (in the widget options) was set as the element id
              // for the question text.
              var questionText = document.getElementById(targetId).textContent;

              // Add additional metadata to widget.
              collection.addMetadata(divId, 'question_id', targetId);
              collection.addMetadata(divId, 'question', questionText);

              collection.addMetadata(divId, 'foo1', 'bar1');
              collection.addMetadata(divId, 'foo2', 'bar2');
              collection.addMetadata(divId, 'foo3', 'bar3');
            }
          });
        });
      }
      else {
        console.log('Init error: ' + JSON.stringify(error, null, 2));
      }
    });
  }

  // The Collection widget error callback
  function errorCallback(error) {
    console.log('Error callback: ' + JSON.stringify(error, null, 2));
  }

  // Selection Change callback
  function selectionChangeCallback(event) {
    console.log('Selection Change callback: ' + JSON.stringify(event, null, 2));
    // Enable/disable the Submit button based on if a morphii is selected.
    // If you do not want this behavior then set the selection->required to
    // false in the widget options above.
    // If selection required is set to false then this callback is not needed.
    var submitButton = document.getElementById('submit-button');
    if (submitButton) {
      if (event.selection_required_valid === true) {
        submitButton.removeAttribute('disabled');
      }
      else {
        submitButton.setAttribute('disabled', 'disabled');
      }
    }
  }

  // Submit the data for the collection.
  function submit(event) {
    if (collection) {
      // Submit all the widget in the collection at once.
      collection.submit(function(error, results) {
        if (error) {
          console.log('Submit results (error): ' + JSON.stringify(error, null, 2));
        }
        else {
          // To view the results, iterator over each record.
          var length = results.length;
          for (var i = 0; i < length; i++) {
            var record = results[i];
            if (record && record.submitted === true) {
              console.log('Submit record: ' + JSON.stringify(record, null, 2));

              // You have access to all the data submitted at this point. For example,
              // you may want the morphii Id, name, intensity, and comment to store
              // in your database.
              // You can pull other information from the results if you like (i.e. referer, user agent, etc...)
              console.log('Results for target id: ' + record.target_id);
              console.log('reaction id: ' + record.reaction_id);
              if (record.reaction_record) {
                console.log('morphii id: ' + record.reaction_record.morphii.id);
                console.log('morphii part name: ' + record.reaction_record.morphii.part_name);
                console.log('morphii display name: ' + record.reaction_record.morphii.display_name);
                console.log('morphii intensity: ' + record.reaction_record.morphii.intensity);
                if (record.reaction_record.comment) {
                  console.log('comment locale: ' + record.reaction_record.comment.locale);
                  console.log('comment text: ' + record.reaction_record.comment.text);
                }
                else {
                  console.log('No comment provided');
                }
              }
              else {
                console.log('Subscription for this account has expired or reached the reaction limit.');
              }
            }
            else {
              console.log('Morphii data not submitted.');
              console.log('Submit results: ' + JSON.stringify(record, null, 2));
            }
          }
        }
      });
    }
  }
})(window, document);

Functions

This section describes the public function for the Collection Widget.

init(options, callback)

This function is used to initialize the collection widget. The function has 2 required parameters: the Collection Options and a callback. The options parameter is a JSON object and is explained in the previous sections. The init function uses the standard callback definition with an error and results. If the widget is initialized successfully the error will be null and results will have a value of true.

Parameters:

  • options: The options defining a Collection. The options parameter is a JSON object and is explained in Collection Options.
  • callback: A callback for the error or results of the function. The results will contain true if the collection was successfully created.

Return: void.

Example:

var collection = new MorphiiWidgets.Collection();
collection.init(collectionOptions, function(error, results) {
  if (error) {
    console.log('Error initializing: ' + JSON.stringify(error, null, 2));
  }
  else {
    console.log('Initialized: ' + JSON.stringify(results, null, 2));
  }
});

add(options, callback)

This function adds a new widget to the collection. The function has 2 required parameters: the widget options and a callback. The options parameter is a JSON object and is explained in Widget Options. The init function uses the standard callback definition with an error and results. If the widget is added to the collection successfully the error will be null and results will contain new widget’s unique id.

Parameters:

  • options: The options defining a widget. The options parameter is a JSON object and is explained in Widget Options.
  • callback: A callback for the error or results of the function. The results will contain the new widget’s unique id.

Return: void.

Example:

var collectionOptions = {
  client_key: 'my-client-key',
  account_id: 'my-account-id',
  project: {
    id: 'widget-sample',
    description: 'Sample widget code.'
  },
  callbacks: {
    error: function(error) { console.log('Error callback: ' + JSON.stringify(error, null, 2)); },
  }
};

var collection = new MorphiiWidgets.Collection();
collection.init(collectionOptions, function(error, results) {
  if (error) {
    console.log('Error initializing: ' + JSON.stringify(error, null, 2));
  }
  else {
    console.log('Initialized: ' + JSON.stringify(results, null, 2));

    // Add a widget to the collection.
    var widgetOptions = {
      div_id: 'widget-div',
      morphii: {
        ids: [ { id: '6362674737212084224' }, { id: '6362666072115564544' }, { id: '6363488681244622848' } ]
      },
      target : {
        id: 'target-widget-div',
        type : 'question'
      }
    };
    collection.add(widgetOptions, function(error, results) {
      if (error) {
        console.log('Collection add error: ' + JSON.stringify(error, null, 2));
      }
      else {
        console.log('Added widget: ' + results);
      }
    });
  }
});

remove(divId)

This function remove a widget from the collection for a specific div id.

Parameters:

  • divId: The div id of the widget.

Return: Return true is widget was removed, else false.

Example:

if (collection) {
  collection.remove('widget-div');
}

metadata(divId)

This function returns the metadata for the widget associated with a specific div id.

Parameters:

  • divId: The div id of the widget.

Return: Returns the metadata for the widget with div id, else null.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  var metadata = collection.metadata('widget-div');
  console.log('metadata: ' + JSON.stringify(metadata, null, 2));
}

addMetadata(divId, key, value)

This function adds the metadata key/value pair to the widget associated with a specific div id. If the key already exist, the value will be replaced with the new value.

NOTE any key name that begins and ends with an underscore (_) is reserved. For example, _type_. See reserved metadata keys for more information.

WARNING: Do not add any Personal Identifying Information(PII) as metadata.

Parameters:

  • divId: The div id of the widget.
  • key: The metadata key.
  • value: The metadata value.

Return: Returns an object with the results. The object contains 2 properties: results and error. The results will be true is the metadata is added, else false. If the results is false, then the error property will contain more information about the error.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  var res = collection.addMetadata('widget-div', 'question', 'How are you feeling today?');
  if (res.results === false) {
    console.log('Error adding metadata: ' + res.error);    
  }
}

removeMetadata(divId, key)

This function removes the metadata with the specific key from the widget associated with a specific div id. NOTE any key name that begins and ends with an underscore (_) is reserved. For example, _type_. See reserved metadata keys for more information.

Parameters:

  • divId: The div id of the widget.
  • key: The metadata key.

Return: Returns an object with the results. The object contains 2 properties: results and error. The results will be true is the metadata is removed, else false. If the results is false, then the error property will contain more information about the error.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  var res = collection.removeMetadata('widget-div', 'question');
  if (res.results === false) {
    console.log('Error removing metadata: ' + res.error);    
  }
}

application(data)

This function sets or gets the application data for the collection. If the data parameter is null then the current application data for the collection is returned. If the data parameter is not null the data will be set on the collection.

Parameters:

Return: Return the Application data or an empty object.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  // Set application for collection.
  var data = {
    name: 'application-name-optional',
    description: 'application-description-optional',
    version: 'application-version-optional',
    properties: {
      key1: 'value1',
      key2: 'value2',
      key3: 'value3'
    }    
  };
  collection.application(data);
}

project(data)

This function sets or gets the project data for the collection. If the data parameter is null then the current project data for the collection is returned. If the data parameter is not null the data will be set on the collection.

Parameters:

Return: Return the Project data or an empty object.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  // Set project for collection.
  var data = {
    id: 'project_id',
    description: 'Project description.'
  };
  collection.project(data);
}

language(lang)

This function sets or gets the language for the collection. If the parameter is null then the current language for the collection is returned. If the parameter is not null the language will be set on the collection. Setting the language will cause a redraw of all the widgets in the collection. Any selection or comment data will be lost.

Parameters:

  • lang: The language to set for the collection. The parameter should be the 2 letter language codes from the ISO 639 standard. The parameter can also contains the country codes from ISO 3166. For example, zh-CN.

Return: Return the current language of the collection.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  // Set language for collection to Spanish.
  collection.language('es');
}

commentRequired(divId, required)

This function sets if the comment is required (or not) for the widget associated with a specific div id.

Parameters:

  • divId: The div id of the widget.
  • required: A flag if the comment is required (true) or not (false).

Return: Returns true if the widget with div id is found and value is set, else false.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  collection.commentRequired('widget-div', true);
}

selectionRequired(divId, required)

This function sets if the selection is required (or not) for the widget associated with a specific div id.

Parameters:

  • divId: The div id of the widget.
  • required: A flag if the selection is required (true) or not (false).

Return: Returns true if the widget with div id is found and value is set, else false.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  collection.selectionRequired('widget-div', true);
}

isHidden(divId)

This function returns if the widget associated with a specific div id is hidden.

Parameters:

  • divId: The div id of the widget.

Return: Returns true if the widget with div id is hidden, else false.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  if (collection.isHidden('widget-div')) {
    console.log('widget-div is hidden');
  }
  else {
    console.log('widget-div is not hidden');
  }
}

show(divId)

This function shows the widget associated with a specific div id.

Parameters:

  • divId: The div id of the widget.

Return: Returns true if the widget with div id is found, else false.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  collection.show('widget-div');
}

hide(divId)

This function hides the widget associated with a specific div id.

Parameters:

  • divId: The div id of the widget.

Return: Returns true if the widget with div id is found, else false.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  collection.hide('widget-div');
}

comment(divId)

This function returns the comment text for the widget with a specific div id in the collection.

Parameters:

  • divId: The div id of the widget.

Return: Return a string if comment is available, else null.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  var text = collection.comment('widget-div');
  console.log('Comment: ' + text);
}

isMorphiiSelected(divId)

This function returns if a morphii is selected for the widget with a specific div id in the collection.

Parameters:

  • divId: The div id of the widget.

Return: Return a true is a morphii is selected, else false.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  console.log('Morphii selected: ' + collection.isMorphiiSelected('widget-div'));
}

reset(options)

This function resets all the widgets in the collection to their initialize values. The function has 1 required parameter. The options parameter is a JSON object with the following structure.

Parameters:

  • options: The options to reset. The options parameter is a JSON object with the following structure:
    • slider: This property is a flag to indicate if the slider should be reset to its original initialized value. Value is true or false.
    • comment: This property is a flag to indicate if the comment field should be reset to its original initialized value. Value is true or false.
    • morphii_selection: This property is a flag to indicate if the morphii selection should be reset. This will deselect the current selected - morphii, if any. Value is true or false.

Return: void

Example:

// Assumes collection widget has been initialized.
if (collection) {
  collection.reset({
    slider: true,
    comment: true,
    morphii_selection: true
  });
}

submitByDivId(divId, callback)

This function submits the information for the widget in the collection associated with a specific div id. The function has 2 required parameter. The function uses the standard callback definition with an error and results. If the submission is successful the error will be null and results will contain information that can be used to retrieve the reaction record.

Parameters:

  • callback: A callback for the error or results of the function. If the submission is successful the error will be null and results will contain information that can be used to retrieve the reaction record. The results contains the widget results. The JSON results will have the following structure:

    • submitted: This property is a flag to indicate if the widget has been submitted. Value is true or false.
    • widget_id: The unique id of the widget that submitted the data.
    • div_id: The div element id the widget is attached to.
    • target_id: The target id that was assigned to the widget.
    • reaction_id: The unique id of the reaction record in the database. This value can be used to retrieve the detailed record using the reactions REST API.
    • reaction_record: This property will be available if the account has not exceeded the subscription limit. This property contains the full reaction record that was submitted.

Return: void.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  // Submit the widget in the collection at once.
  collection.submitByDivId('widget-div', function(error, results) {
    if (error) {
      console.log('Submit results (error): ' + JSON.stringify(error, null, 2));
    }
    else {
      if (results && results.submitted === true) {
        console.log('Submit record: ' + JSON.stringify(results, null, 2));

        // You have access to all the data submitted at this point. For example,
        // you may want the morphii Id, name, intensity, and comment to store
        // in your database.
        // You can pull other information from the results if you like (i.e. referer, user agent, etc...)
        console.log('Results for target id: ' + results.target_id);
        console.log('reaction id: ' + results.reaction_id);
        if (results.reaction_record) {
          console.log('morphii id: ' + results.reaction_record.morphii.id);
          console.log('morphii display name: ' + results.reaction_record.morphii.display_name);
          console.log('morphii intensity: ' + results.reaction_record.morphii.intensity);
          if (results.reaction_record.comment) {
            console.log('comment locale: ' + results.reaction_record.comment.locale);
            console.log('comment text: ' + results.reaction_record.comment.text);
          }
          else {
            console.log('No comment provided');
          }
        }
        else {
          console.log('Subscription for this account has expired or reached the reaction limit.');
        }
      }
      else {
        console.log('Morphii data not submitted.');
        console.log('Submit results: ' + JSON.stringify(results, null, 2));
      }
    }
  });
}

submit(callback)

This function submits the information for all widgets in the collection. The function has 1 required parameter: a callback. The submit function uses the standard callback definition with an error and results. If the submission is successful the error will be null and results will contain information that can be used to retrieve the reaction record.

Parameters:

  • callback: A callback for the error or results of the function. If the submission is successful the error will be null and results will contain information that can be used to retrieve the reaction record. The results contains an array of each widget results. The JSON results will have the following structure:

    • submitted: This property is a flag to indicate if the widget has been submitted. Value is true or false.
    • widget_id: The unique id of the widget that submitted the data.
    • div_id: The div element id the widget is attached to.
    • target_id: The target id that was assigned to the widget.
    • reaction_id: The unique id of the reaction record in the database. This value can be used to retrieve the detailed record using the reactions REST API.
    • reaction_record: This property will be available if the account has not exceeded the subscription limit. This property contains the full reaction record that was submitted.

Return: void.

Example:

// Assumes collection widget has been initialized.
if (collection) {
  // Submit all the widget in the collection at once.
  collection.submit(function(error, results) {
    if (error) {
      console.log('Submit results (error): ' + JSON.stringify(error, null, 2));
    }
    else {
      // To view the results, iterator over each record.
      var length = results.length;
      for (var i = 0; i < length; i++) {
        var record = results[i];
        if (record && record.submitted === true) {
          console.log('Submit record: ' + JSON.stringify(record, null, 2));

          // You have access to all the data submitted at this point. For example,
          // you may want the morphii Id, name, intensity, and comment to store
          // in your database.
          // You can pull other information from the results if you like (i.e. referer, user agent, etc...)
          console.log('Results for target id: ' + record.target_id);
          console.log('reaction id: ' + record.reaction_id);
          if (record.reaction_record) {
            console.log('morphii id: ' + record.reaction_record.morphii.id);
            console.log('morphii display name: ' + record.reaction_record.morphii.display_name);
            console.log('morphii intensity: ' + record.reaction_record.morphii.intensity);
            if (record.reaction_record.comment) {
              console.log('comment locale: ' + record.reaction_record.comment.locale);
              console.log('comment text: ' + record.reaction_record.comment.text);
            }
            else {
              console.log('No comment provided');
            }
          }
          else {
            console.log('Subscription for this account has expired or reached the reaction limit.');
          }
        }
        else {
          console.log('Morphii data not submitted.');
          console.log('Submit results: ' + JSON.stringify(record, null, 2));
        }
      }
    }
  });
}

Collection Options

The options are passed as the first parameter of the init function. The options are in a JSON object.

  • client_key: The unique key assigned to this client. This property is required.
  • account_id: The account id of the client. This property is required.
  • session_id: The session id to assign to the collection and associated widgets. If property is omitted a default session id will be assigned to the collection and associated widgets. Populate this property if you are creating multiple collections in an application (or survey) and want to group the data across a common id.
  • sub_account: This optional property defines the Sub Account. This can help clients that sell their products to multiple organizations keep the morphii reaction data separate. This property has 2 children: id and name.
    • id: This property is the sub account id assigned by the client.
    • name: This property is the sub account name assigned by the client.
  • user: This optional property defines the User Data. The client is the owner of the user, not the widget.
    • id: This property is the user id assigned by the client. This property is required.
  • project: User defined Project Information. This property is required. This property has 2 children: id and description.
    • id: The user defined project id. This property is required.
    • description: The project description. This property is optional.
  • application: User defined Application Data. This property is optional. This property has 3 optional children:
    • name: The application name.
    • description: The application description.
    • properties: This property can be used to define additional information about the application using the widget.
  • caller: The property is the object that created the widget. This property is optional.
  • callbacks: This property defines the callbacks that can be registered for the widget.
    • error: An optional callback for errors. This callback is called when an error happens in a widget in the collection. The callback has one parameter (error). The parameter object contains 2 properties: error and caller. The error property is an object that contains the error information. The caller property is optional and is included if caller property was set when widget was added.
    • comment_change: An optional callback to receive an event when the comment field is changed. This callback is triggered on the keyup event. The callback has one parameter (event). The parameter object contains 3 properties:
      • type: The type of event. Currently comment_changed. comment_required_valid: A flag indicating if all comments fields have satisfied their requirements. Value is true or false.
      • widget: The widget that contains the modified comment area.
        • id: The unique id of the widget.
        • comment: This property defines the comment object.
          • required: A flag indicating if the comment field is required. Value is true or false.
          • length: The current number of characters in the comment field.
          • value: The current text in the comment field.
      • caller: This property is optional and is included if the caller property was set when widget was added.
    • selection_change: An optional callback to receive an event when a morphii is selected. The callback has one parameter (event). The parameter object contains 3 properties:
      • type: The type of event. Currently selection_changed.
      • selection_required_valid: A flag indicating if all widgets have satisfied their requirement of a morphii selected. Value is true or false.
      • widget: The widget that contains the selected morphii.
        • id: The unique id of the widget.
        • morphii: Additional information about the morphii selected.
          • selected: A flag indicating if a morphii is selected in the widget. Value is true or false.
          • weight: The user defined weight assigned to the morphii. If no value was assigned it will default to zero (0).
      • caller: This property is optional and is included if the caller property was set when widget was added.

Sample 1: Collection options with no user.

var collectionOptions = {
  client_key: 'my-client-key',
  account_id: 'my-account-id',
  sub_account: {
    id: 'sub_account_id',
    name: 'Sub account name'
  },
  project: {
    id: 'my-project-id',
    description: 'my-project-description'
  },
  application: {
    name: 'application-name-optional',
    description: 'application-description-optional',
    version: 'application-version-optional',
    properties: {
      key1: 'value1',
      key2: 'value2',
      key3: 'value3'
    }
  },
  callbacks: {
    error: function(error) {
      console.log('Error callback: ' + JSON.stringify(error, null, 2));
    },
    comment_change: function(event) {
      console.log('Comment change callback: ' + JSON.stringify(event, null, 2));
    },
    selection_change: function(event) {
      console.log('Selection change callback: ' + JSON.stringify(event, null, 2));
    }
  }
};

Sample 2: Collection options with user.

var collectionOptions = {
  client_key: 'my-client-key',
  account_id: 'my-account-id',
  sub_account: {
    id: 'sub_account_id',
    name: 'Sub account name'
  },
  user: {
    id: 'user-id'
  },
  project: {
    id: 'my-project-id',
    description: 'my-project-description'
  },
  application: {
    name: 'application-name-optional',
    description: 'application-description-optional',
    version: 'application-version-optional',
    properties: {
      key1: 'value1',
      key2: 'value2',
      key3: 'value3'
    }
  },
  callbacks: {
    error: function(error) {
      console.log('Error callback: ' + JSON.stringify(error, null, 2));
    },
    comment_change: function(event) {
      console.log('Comment change callback: ' + JSON.stringify(event, null, 2));
    },
    selection_change: function(event) {
      console.log('Selection change callback: ' + JSON.stringify(event, null, 2));
    }
  }
};

Sub Account

The sub account data can help clients that sell their products to multiple organizations keep the morphii reaction data separate. This data is optional when creating a Collection.

  • id: The id of the sub account.
  • name: The name of the sub account.
var data = {
  id: 'sub_account_id',
  name: 'Sub account name'
};

Application Data

The application data allows the client to define more information about the application that is using the morphii widget. This data is optional.

  • name: The name of the application.
  • description: A description of the application.
  • version: The version number (as a string).
  • properties: An object of properties (key-value pairs).
var data = {
  name: 'my_app_name',
  description: 'My application description',
  version: '1.0',
  properties: {
    sampleKey1: 'sample value 1',
    sampleKey2: 'sample value 2',
    env: 'prod'
  }    
};

Project Data

The project data allows the client to define information about the project is associated with the collection. This data is required when creating a Collection.

  • id: The id of the project (required).
  • description: The description of the project (optional).
var data = {
  id: 'project_id',
  description: 'Project description.'
};

Widget Options

The widget options are provided as the first parameter of the Collection add function. The options are passed as a JSON object.

  • div_id: The id of the div element on the page the widget will attach to. This property is required.
  • morphii: This property defines the morphiis to be used for the widget. The morphii property is required and must contain the ids property.
    • ids: This is an array of id objects. The id object contains 2 child properties: id and name. The id property is required.
      • id: This is the unique id of the morphii. This property is required.
      • name: This property 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: This is a user defined integer value assigned to the morphii. If no value is provided the widget will assign a zero (0). Note this value is included in the event object that is used in the selection_changed callback.
      • static_feedback: If a static morphii is being used, an additional property can we added to ask the user for additional information. If this property is omitted then selecting the static morphii will just hide the slider.
        • show: This is a flag to show the additional question for when the static morphii is selected.
        • label: This property holds the text for the input field for each supported language. Each translation is defined separately. The en version of the label is required if any other language is declared.
    • show_name: This is a flag to show the morphii name. By default this value is true. The name assigned to the morphii is display below the morphii image.
    • wrap_name: This is a flag to wrap the morphii name text. By default this value is true. If value is false, the name will be truncated and end with ellipsis.
  • target: This property defines the target information for this widget. The target is the content the morphii is associated with. The client is the owner of the target, not the widget. This object contains an id and type. The target property is required and must contain both these properties.
    • id: This is the id of the target. The client defines and owns the target and the target id.
    • type: The type of target. Values can be, but not limited to: questions, video, tweet, article, link, etc…
  • comment: This property defines the options for the comment area of the widget.
    • show: This property is the flag to show the comment area. Value is true or false. The default value is true.
    • required: This property is the flag to indicate if the comment is required. Value is true or false. The default value is false.
    • maxlength: This property is the max number of character of the comment. If the value is 0 the character count is unlimited. The default value is 255.
    • label: This property holds the text for the label above the comment field for each supported language. Each translation is defined separately. The en version of the label is required if any other language is declared. Default: “Please leave a comment”
  • slider: This property defines the options for the slider of the widget.
    • initial_intensity: This property is the initial intensity value of the slider. The value must be between 0 and 1. If the value is outside the range, the value will default to 0.5. The default value is 0.5.
    • anchor_labels: This property defines the options for the anchor text on each side of the slider.
      • show: This property is the flag to show the anchor text. Value is true or false. The default value is false.
      • left: This property is used to override the default text for the left anchor text. Each translation is defined separately. The en version of the label is required if any other language is declared.
      • right: This property is used to override the default text for the right anchor text. Each translation is defined separately. The en version of the label is required if any other language is declared.
  • instructions: This property defines the options for the instruction text.
    • show: This property is the flag to show the instruction text. Value is true or false. The default value is false.
    • pre_select_label: This property is used to override the default text for the instruction text that is displayed when a morphii selection has not been made. Each translation is defined separately. The en version of the label is required if any other language is declared.
    • post_select_label: This property is used to override the default text for the instruction text that is displayed when a morphii is selected. Each translation is defined separately. The en version of the label is required if any other language is declared.
  • selection: This property defines if the selection is required. This is optional.
    • required: This property is a flag to indicate that a morphii must be selected to submit the data from the widget. Value is true or false. The default value is false.
  • intensity: This property defines if the intensity is required. This is optional.
    • required: This property is a flag to indicate that the intensity must be set to submit the data from the widget. Value is true or false. The default value is false.
  • suppress_fields: This property defines an array of fields you want to suppress from the results. Valid values are user-agent and ip. If listed, these fields will not be returned in the morphii results or stored in the morphii reaction database. This is optional.
  • preselect: This property defines the pre-selection options.
    • morphii: This property defines the morphii to be pre-selected when the widget is initially rendered. This property has 2 children: id and intensity.
      • id: The unique id of the morphii to pre-select. This property is required.
      • intensity: The intensity render the pre-selected morphii. If this value is not provided the widget will use the initial_intensity value.
    • comment: This property defines the comment text to be set when the widget is initially rendered.
      • text: The comment text.
  • border: This property defines the options for the border around the widget. Note, this property is only used for testing purposes.
    • show: This property is the flag to show the border. Value is true or false. The default value is false.
    • style: This property is the CSS style to use for the border. The default value is “1px dashed slategray”.
  • options: This property defines additional options for the widget.
    • stage: This property is used to indicate the stage of the widget. This is used for testing purposes. The default value is live. Values are defined as:
      • test: The data will not be processed by the data analytics pipeline.
      • validation : The data will be processed by the data analytics pipeline, but will not show up in any report data, etc…
      • live: All stages of the data analytics pipeline will be processed.
  • caller: This property is the object that created the widget. This property is optional.

Sample 1: Options using 3 morphii ids in English and Spanish.

var options = {
  div_id: 'morphii-widget-1',
  morphii: {
    ids : [
      {
        id: '6194588456543322112',
        name: {
          en: 'Happy',
          es: 'Contento'
        }
        weight: 1
      },
      {
        id: '6194588453733138432',
        name: {
          en: 'Sad',
          es: 'Triste'
        }
        weight: 0
      },
      {
        id: '6206533129830662144',
        static_feedback: {
          show: true,
          label: {
            en: 'Please type your answer below:',
            es: 'Por favor escriba su respuesta a continuación:'
          }
        }
      }
    ],
    show_name: true,
    wrap_name: true
  },
  target : {
    id : 'my-target-id',
    type : 'video'
  },
  comment: {
    show: true,
    required: false,
    maxlength: 255,
    label: {
      en: 'Please leave a comment'
      es: 'Por favor deja un comentario'
    }
  },
  slider: {
    initial_intensity: 0.2,
    show_animation: false,
    anchor_labels: {
      show: true,
      left: {
        en: 'Less emotional',
        es: 'Menos emocional'
      },
      right: {
        en: 'More emotional',
        es: 'Mas emocional'
      }
    }
  },
  instructions: {
    show: true,
    pre_select_label: {
      en: 'Select the graphic above that best represents how you feel.',
      es: 'Seleccione el gráfico de arriba que mejor represente cómo se siente.'
    },
    post_select_label: {
      en: 'Move the slider to show how intense your feeling is.',
      es: 'Mueva el control deslizante para mostrar qué tan intenso es su sentimiento.'
    }
  },
  selection: {
    required: false
  },
  intensity: {
    required: false
  },
  preselect: {
    morphii: {
      id: '6194588456543322112',
      intensity: 0.75
    },
    comment: {
      text: 'My comment text'
    }
  },
  border: {
    show: false,
    style: '1px dashed slategray'
  },
  options: {
    stage: 'live'
  }
};

Sample 2: Options using all default values.

var options = {
  div_id: 'morphii-widget-1',
  morphii: {
    ids : [ { id: '6194588456543322112' }, { id: '6194588453733138432' } ]
  },
  target : {
    id : 'my-target-id',
    type : 'video'
  }
};

User Data

The user data allows the client to associate a user id to a collection. This data is optional.

  • id: User defined id for the user. Recommended this value is the internal id you assign to the user, not an email address or other PII data.
var data = {
  id: 'user_id'
};

Reserved Metadata

Any key name that begins and ends with an underscore (_) is reserved. The following predefined keys are reserved and are validated when added to the metadata.

  • _audience_: The audience you are interacting with (customer, employee, etc…). Validate values are:
    • customer
    • employee
    • patient
    • community
    • general
    • other
  • _category_: The category (or type) of questions you are asking (satisfaction survey, etc…). Validate values are:
    • satisfaction
    • engagement
    • hr
    • mood
  • _timing_: The timing of when you are gather the data (before/after event, etc…). Validate values are:
    • pre-event
    • during-event
    • post-event
    • n/a