Introduction

The morphii widget is a convenient way to embed morphiis into a new or existing website. This documentation will provide details on each widget, their 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 Widget

The Collection Widget is used when you need one or more morphii widgets embedded on the page. Each widget in the Collection Widget can have different options.

  • Development: https://widget-dev.morphii.com/v1/morphii-widget.min.js
  • Production: https://widget.morphii.com/v1/morphii-widget.min.js

Options

The widget options as passed as the first parameter of the init function. The options are passed as 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.
  • user : This property defines the user object. The client is the owner of the user, not the widget. This property has 4 children: anonymous, id, type, and properties. The user property is required and must contain the anonymous property. If the anonymous property is set to false, then the id and type properties are required.
    • anonymous : This property signifies if the user is anonymous or not. Value is true or false. If this property is set to false, then the properties id and type are required.
    • id : This property is the user id assigned by the client. This property is required if the anonymous property is set to false.
    • type : This property is the type of user. Values can be, but not limited to: external, facebook, twitter, or google. This property is required if the anonymous property is set to false.
    • properties : This property is optional. This property can be used to define additional information about the user such as name or email address.
  • project : User defined project information. This property is optional. This property will be copied to each widget in the collection. This property has 2 children: id and description.
    • id : The user defined project id. This property is required when defining a project.
    • description : The project description.
  • 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 anonymous user.

var collectionOptions = {
  client_key: 'my-client-key',
  account_id: 'my-account-id',
  user: {
    anonymous: true
  },
  project: {
    id: 'my-project-id',
    description: 'my-project-description'
  },
  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 external user.

var collectionOptions = {
  client_key: 'my-client-key',
  account_id: 'my-account-id',
  user: {
    anonymous: false,
    id: 'test_user_id_12345',
    type: 'external',
    properties: {
      name: 'test user',
      email: 'test.user@mailinator.com'
    }
  },
  project: {
    id: 'my-project-id',
    description: 'my-project-description'
  },
  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 3: Collection sample

<!-- index.html -->
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Widget 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>
    <div id="target-container">
      <h4 align="center">How did you feel before your visit?</h4>
      <div id="widget-1"></div>

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

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

    <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
    <script src="https://widget-dev.morphii.com/v1/morphii-widget.min.js"></script>
    <script src="index.js"></script>
  </body>
</html>
// index.js
$(function() {

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

  // Define the morphii ids that will be used in the widgets. We can provide you
  // with a list of all the publicly available morphii ids.
  var morphiiIds = [
    {
      id: '6363734358316589056',
      name: 'Frustrated'
    },
    {
      id: '6363488681244622848',
      name: 'Disappointed'
    },
    {
      id: '6202184384594837504',
      name: 'Meh'
    },
    {
      id: '6363735117617217536',
      name: 'Disgusted'
    },
    {
      id: '6362666072115564544',
      name: 'Delighted'
    }
  ];

  // Setup the widget when the page is ready.
  $(document).ready(function() {
    createWidget();

    // Call submit function when Submitt button is clicked.
    $('#submit-button').on('click', submit);

    // Disable submit button util a morphii is selected.
    $('#submit-button').prop('disabled', true);
  });

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

  function createWidget() {
    var collectionOptions = {
      client_key: 'my-client-key',
      account_id: 'my-account-id',
      project: {
        id: 'widget-sample',
        description: 'Sample widget code.'
      },
      user: {
        anonymous: true
      },
      callbacks: {
        error: errorCallback,
        selection_change: selectionChangeCallback
      }
    };

    collection = new MorphiiWidgets.Collection();
    collection.init(collectionOptions, function(error, valid) {
      if (valid === true) {
        // Add the first widget to the collection.
        var option = widgetOptions('widget-1', 'How did you feel before your visit?');
        collection.add(option, function(error, results) {
          if (error) {
            console.log('Collection add error: ' + JSON.stringify(error, null, 2));
          }
          else {
            // Add a second widget.
            option = widgetOptions('widget-2', 'How did you feel after your visit?');
            collection.add(option, function(error, results) {
              if (error) {
                console.log('Collection add error: ' + JSON.stringify(error, null, 2));
              }
            });
          }
        });
      }
      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.
    if (event.selection_required_valid === true) {
      $('#submit-button').prop('disabled', false);
    }
    else {
      $('#submit-button').prop('disabled', true);
    }
  }

  // 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('Question: ' + record.reaction_record.target.metadata.question);
                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));
            }
          }
        }
      });
    }
  }
});

Functions

The Collection Widget has 6 public functions.

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 the Basic Widget Options section. 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.

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.
    collection.add(widgetOptions, function(error, results) {
      if (error) {
        console.log('Collection add error: ' + JSON.stringify(error, null, 2));
      }
      else {
        console.log('Added widget: ' + results);
      }
    });
  }
});

get(index)

This function returns widget at a specific index in the collection. The function has 1 required parameter. The index is 0-based. If index is outside the range null is returned. Basic Widget Functions

// Assumes collection widget has been initialized.
if (collection) {
  // Get the 3 widget in the collection.
  var widget = collection.get(2);
  if (widget) {
    console.log('Morphii selected: ' + widget.morphiiSelected());    
  }
}

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.

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));
  }
});

length()

This function returns the number of widgets in the collections.

// Assumes collection widget has been initialized.
if (collection) {
  console.log('Collection length: ' + collection.length());
}

reset(options)

This function iterates over each widget in the collection and resets the widget to its initialized values. The function has 1 required parameter. 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.
// Assumes collection widget has been initialized.
if (collection) {
  collection.reset({
    slider: true,
    comment: true,
    submit_button: true,
    morphii_selection: true
  });
}

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. 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.
// Assumes collection widget has been initialized.
if (collection) {
  collection.submit(function(error, results) {
    if (error) {
      console.log('Submit results (error): ' + JSON.stringify(error, null, 2));
    }
    else {
      console.log('Submit results: ' + JSON.stringify(results, null, 2));
    }
  });
}

Basic Widget Options

This section descriptions the options used when adding a basic widget to a collection.

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. This property has 2 children: ids and show_name. 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 is the display name to assign to the morphii. If no name is provided the widget will assign the name in the morphii database.
      • 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.
    • show_name : This is a flag to show the morphii name or not. By default this value is true. The name assigned to the morphii is display below the morphii image.
  • 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 property has 3 children: id, type, and metadata. The target property is required and must contain the id and type 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…
    • metadata : The metadata property is optional. This property can be used to define additional data about the target or specific instance of the widget.
  • 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 is the label that is above the comment text field. The default value is “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.
  • selection : This property defines the selection options.
    • required : This property is a flag to indicate that a morphii must be selected to submit the data from the widget. If this value is set to false and the morphii is submitted, no data is saved in the database. Value is true or false. The default value is true.
  • 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 2 morphii ids.

var options = {
  div_id: 'morphii-widget-1',
  morphii: {
    ids : [
      {
        id: '6194588456543322112',
        name: 'Happy',
        weight: 1
      },
      {
        id: '6194588453733138432',
        name: 'Sad',
        weight: 0
      }
    ],
    show_name: true
  },
  target : {
    id : 'my-target-id',
    type : 'video',
    metadata: {
      prop1: 'property-1'
    }
  },
  comment: {
    show: true,
    required: false,
    maxlength: 255,
    label: 'Please leave a comment'
  },
  slider: {
    initial_intensity: 0.2
  },
  selection: {
    required: true
  },
  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',
        name: 'Happy',
        weight: 1
      },
      {
        id: '6194588453733138432',
        name: 'Sad',
        weight: 0
      }
    ]
  },
  target : {
    id : 'my-target-id',
    type : 'video',
    metadata: {
      prop1: 'property-1',
      prop2: 'property-2'
    }
  }
};

Basic Widget Functions

Functions

The Basic Widget has 6 public functions.

comment()

This function can be used to get the current text in the comment field. If the comment.show option is set to false the function will return null.

// Assumes morphii widget has been initialized.
if (widget) {
  console.log('Widget comment text: ' + JSON.stringify(widget.comment(), null, 2));
}

id()

This function returns the unique id assigned to the widget.

// Assumes morphii widget has been initialized.
if (widget) {
  console.log('Widget id: ' + JSON.stringify(widget.id(), null, 2));
}

metadata(metadata)

This function gets/sets the metadata in the target object. This function will overwrite any metadata value that was previously set. The function has 1 optional parameter. If the parameter is omitted or is null, the function will return the current metadata set in the target. If no metadata is set, the function will return an empty object. To clear the previous metadata value pass in an empty object { }.

// Assumes morphii widget has been initialized.
if (widget) {
  widget.metadata({
    property_1 : 'test property 1',
    property_2 : 'test property 2',
    property_3 : 'test property 3'
  });

  console.log('Metadata: ' + JSON.stringify(widget.metadata(), null, 2));
}

morphiiSelected()

This function returns if the widget has a morphii selected. The function will return true or false.

// Assumes morphii widget has been initialized.
if (widget) {
  console.log('Morphii selected: ' + widget.morphiiSelected());
}

options()

This function returns the options that were passed in the init function.

// Assumes morphii widget has been initialized.
if (widget) {
  console.log('Widget options: ' + JSON.stringify(widget.options(), null, 2));
}

reset(options)

This function resets the widget to its initialized values. The function has 1 required parameter. 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.
  • submit_button : This property is a flag to indicate if the submit button should be reset. 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.
// Assumes morphii widget has been initialized.
if (widget) {
  widget.reset({
    slider: true,
    comment: true,
    submit_button: true,
    morphii_selection: true
  });
}