NAV Navbar
Logo
javascript

Widget Works Widget API

Overview

The Widget is made up of four components that work together to embed the tool on your webpage.

  1. Host page - your webpage that will host the Widget.
  2. Widget - the Widget and all of its associated assets - loaded into an iframe on the host page.
  3. Helper library - The iframeUtil library loaded on the host page that allow communication between the host page and Widget.
  4. Configuration - the customisation and configuration data for the Widget.

Page setup

Copy and pase this into your HTML to add a Widget to your page:

<!-- Start Widget Works - do not change -->
<script src="https://calcs.widgetworks.com.au/s/bimade/live.js"></script>
<iframe id="wiwo-bimade" width="100%" height="200" src="" frameborder="0" data-wiwo-init="false"></iframe>
<script src="https://calcs.widgetworks.com.au/widget/widget-scout.min.js"></script>
<!-- End Widget Works -->

First, copy and insert the Widget embed code from Widget Manager. Our examples will use the following Mortgage Repayment Widget:

You can have multiple Widgets on the same page, just use the iframe id to refer to each instance specifically.

Data In, Data Out (dido) API

All Widget Works Widgets provide an interaction API.

The namespace for all Widget Works libraries is : wiwo

The namespace for the asynchronous cross-frame API is : _wiwo

Once a Widget is embedded in a page you can use our simple API to set and get calculation-specific data from the Widget. The Widget itself runs in the iframe and you can’t communicate to it directly due to cross domain limitations.

Our helpful scout provides a secure, cross-frame communications API which you can use to interact with the Widget. The API is event based and asynchronous - all events sent to or from the Widget are asynchronous.

In most cases the response from the Widget will be virtually immediate.

Responses always provide:

Example: get data from Widget

Example: Getting data from the Widget.

This will return the full dataset (user inputs and calculated fields) from the Widget:

// `getData` example
var _wiwo = _wiwo || [];

// 1. Invoke the `getData` method on the iframeUtil:
_wiwo.push(['getData', 'wiwo-bimade', function(e, result){
  // 2. This callback function will be invoked when the Widget raises the `wiwo.dido.getDataResult` event:
  if (result.success){
    console.log('Received data from Widget ID=', e.frameId, ', data=', result.data);
  } else {
    console.warn('Unable to get data from Widget ID=', e.frameId, ', reason=', result.message);
  }

}]);

Console output from the above example:

'Received data from Widget ID=wiwo-bimade, data='{
  "data": {
    "output": {       
      "repaymentResultModel": {
        "hasFixedRepayment": false,
        "fixedRepayment": 0,
        "ongoingRepayment": 690.911525212645,
        "totalInterestPayable": 89094.6689249568,
        "totalLoanAmount": 189094.66892495676,
        "loanDuration": {
          "rawPeriods": 300,
          "totalYears": 25,
          "years": 25,
          "periods": 0
        },
        "chartSeries": {
            "lastTerm": 25,
            "repaymentSeries": [
                [
                  0,
                  189094.67
                ]
                //, ....
            ]
          }
      }

    },
    "input": {
      ...
    }
  }
}

This is the process that occurs when you request the current input values and calculation results from a Widget:

  1. Invoke the getData() method on the Widget.
  2. The iframeUtil will use the iframeUtil.postMessage() method to send a 'wiwo.dido.getData' event to the Widget.
  3. The Widget receives the event and processes the data into the required JSON structure.
  4. The Widget will send the 'wiwo.dido.getDataResult' event back to the iframeUtil.
  5. The iframeUtil will invoke your callback, passing the Widget data to the function.

See DiDo Events.getDataResult for detail on the returned data.

Example: send data to Widget

Example: Setting data on the Widget.

The data payload you send should match the structure of the WidgetData type.

// `setData` example
var _wiwo = _wiwo || [];

// 1. Invoke the `setData` method on the iframeUtil:
_wiwo.push([
    'setData',
    'wiwo-bimade', 
    {
      "id": "wiwo-repayment-widget",
      "version": 1,

      // This is the data that will be loaded by the Widget:
      // This data is Widget-specific.
      "input": {
        "repaymentModel": {
          "propertyValue": 530000,
          "principal": 424000
        }
      }
    },
    function(e, result){
      // 2. This callback will be invoked when Widget returns the `wiwo.dido.setDataResult` event:
      if (result.success){
        console.log('Successfully loaded data into Widget ID=', e.frameId);
      } else {
        console.warn('Unable to set data on Widget ID=', e.frameId, ', reason=', result.message);
      }

    }
]);

To dynamically load new data into a Widget:

  1. Invoke the setData() method on the iframeUtil, passing the frameId and data you want to load.
  2. The iframeUtil will use the iframeUtil.postMessage() method to send a 'wiwo.dido.setData' event to the Widget along with the data payload.
  3. The Widget receives the event, validates the data payload and loads the new data.
  4. The Widget will send the 'wiwo.dido.setDataResult' event back to the iframeUtil.
  5. The iframeUtil will invoke your callback, passing the Widget data to the function.

The setData() method expects a WidgetData object passed as the payload parameter.

See DiDo Events.setDataResult detail on the data types expected by the Widget.

To load data at Widget startup see Loading values from URL.

Events and Properties

Host events

// Example: send 'wiwo.dido.getData' and 'wiwo.dido.setData' events to a Widget
var _wiwo = _wiwo || [];
_wiwo.push(['postMessage', 'wiwo-bimade', 'wiwo.dido.getData']);
_wiwo.push(['postMessage', 'wiwo-bimade', 'wiwo.dido.setData', {...}]);

For more information see: method calls

// Example: send 'wiwo.dido.getData' and 'wiwo.dido.setData' events to a Widget
// Equivalent to above example but uses synchronous ready function:
var _wiwo = _wiwo || [];
_wiwo.push([function(iframeUtil){
  iframeUtil.postMessage('wiwo-bimade', 'wiwo.dido.getData');
  iframeUtil.postMessage('wiwo-bimade', 'wiwo.dido.setData', {...});
}]);

For more information see: ready functions

The following events may be sent from the host page to the Widget:

Event name Description Response event from Widget
wiwo.dido.getData Request data from the specified widget wiwo.dido.getDataResult
wiwo.dido.setData Request to set your data payload on the specified widget wiwo.dido.setDataResult

See iframeUtil API for detail on how to add event listeners and send messages to the Widget.

Widget events

var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.dido.getDataResult', function(e, result){
  // Handle the event here.
}]);

_wiwo.push(['on', 'wiwo.dido.setDataResult', function(e, result){
  // Handle the event here.
}]);

_wiwo.push(['on', 'pageTrack', function(e, data){
  // Handle the event here.
}]);

_wiwo.push(['on', 'eventTrack', function(e, data){
  // Handle the event here.
}]);

The following events may be raised by the Widget and handled on the host page:

Event name Description
wiwo.dido.getDataResult Indicates success of failure of preceeding ‘wiwo.dido.getData’ event. Returns Widget data if successful.
wiwo.dido.setDataResult Indicates success or failure of preceeding ‘wiwo.dido.setData’ event.
pageTrack Analytics event. The user has navigated to a new screen in the Widget.
eventTrack Analytics event. The user has interacted with the Widget.

See iframeUtil.on() for more detail on registering event listeners.

Event Properties

See iframeUtil.FrameEvent for the properties on the e parameter in event listeners.

Loading values from URL

Override defaults

Example:

  1. For this example the parent page URL is: https://wm.widgetworks.com.au/widget/bimade/live

  2. The parent page has a Widget with the iframe ID ‘wiwo-bimade’: e.g. <iframe id="wiwo-bimade" width="100%" height="100" src="" frameborder="0" data-wiwo-init="false"></iframe>

  3. The parent page must have a URL query parameter with a key that matches the iframe ID: https://wm.widgetworks.com.au/widget/bimade/live/?wiwo-bimade=…

  4. The value of the parameter is the URI-encoded JSON data for that Widget

  5. Combine the everything together to form the final URL:

e.g. This JSON string:

{"id":"wiwo-repayment-widget","version":0,"input":{"repaymentModel":{"principal":123456,"term":13,"interestRate":0.13,"repaymentType":"IO_ARR","repaymentFrequency":"fortnight","productGroup":"fixed","product":"wiwoFixed3Y"},"savingsModel":{"savingsEnabled":false,"extraRepayment":0,"offset":0,"lumpSum":0,"lumpSumYear":3}}}

Is URI-encoded as:

%7B%22id%22%3A%22wiwo-repayment-widget%22%2C%22version%22%3A0%2C%22input%22%3A%7B%22repaymentModel%22%3A%7B%22principal%22%3A123456%2C%22term%22%3A13%2C%22interestRate%22%3A0.13%2C%22repaymentType%22%3A%22IO_ARR%22%2C%22repaymentFrequency%22%3A%22fortnight%22%2C%22productGroup%22%3A%22fixed%22%2C%22product%22%3A%22wiwoFixed3Y%22%7D%2C%22savingsModel%22%3A%7B%22savingsEnabled%22%3Afalse%2C%22extraRepayment%22%3A0%2C%22offset%22%3A0%2C%22lumpSum%22%3A0%2C%22lumpSumYear%22%3A3%7D%7D%7D

The Widgets can load default values from the parent page query parameters.

The data is passed into the Widget via a URL query parameter that matches the ID of the Widget’s iframe.

For example, the data from the query parameter '?wiwo-bimade=...' will be passed to the Widget loaded into the iframe with the ID 'wiwo-bimade'.

The parameter should be the same JSON payload that passed with the 'wiwo.dido.setDataResult' event (see the send data to Widget example section above). However, the JSON payload must be URI-encoded when passed as a URL parameter.

To set values after page load see the ‘wiwo.dido.setData’ event and ‘wiwo.dido.setData’ example.

Example

Combine the everything together to form the final URL:

<a href="https://wm.widgetworks.com.au/widget/bimade/live/?wiwo-bimade=%7B%22id%22%3A%22wiwo-repayment-widget%22%2C%22version%22%3A0%2C%22input%22%3A%7B%22repaymentModel%22%3A%7B%22principal%22%3A123456%2C%22term%22%3A13%2C%22interestRate%22%3A0.13%2C%22repaymentType%22%3A%22IO_ARR%22%2C%22repaymentFrequency%22%3A%22fortnight%22%2C%22productGroup%22%3A%22fixed%22%2C%22product%22%3A%22wiwoFixed3Y%22%7D%2C%22savingsModel%22%3A%7B%22savingsEnabled%22%3Afalse%2C%22extraRepayment%22%3A0%2C%22offset%22%3A0%2C%22lumpSum%22%3A0%2C%22lumpSumYear%22%3A3%7D%7D%7D" target="_blank">Load Repayment Widget with custom data...</a>

Try it out:

Load Repayment Widget with custom data (look for a loan value of $123 456)

URI-encoding data

The data variable matches the structure of the WidgetData type

var frameId = 'wiwo-bimade';    // The ID of the Widget.
var data = {                    // The data to set on the Widget.
    id: '',
    version: 1,
    input: {
        repaymentModel: {
            principal: 123456
        }
    }
};

// Convert the data to a JSON string and encode it with `encodeURIComponent`:
var encodedData = encodeURIComponent(JSON.stringify(data));

// Combine the encoded data with the frameId:
var widgetParam = frameId + '=' + encodedData;

// `widgetParam` now has the value:
// wiwo-bimade=%7B%22id%22%3A%22wiwo-repayment-widget%22%2C%22v...

The value of widgetParam can now be used to pass data to the Widget via the URL.

This is a simple example showing the most common method of encoding the Widget data to pass on the URL:

Error Handling

The structure of the result object:

interface DidoResult {
    success: boolean,
    message: string,
    data: object
}

‘wiwo.dido.getDataResult’ detail:

var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.dido.getDataResult', function(event, result){
    if (result.success){
        result.message  // Extra information about the result (can be empty).
        result.data;    // Holds the Widget's input and result data.
    } else {
        result.message  // Error message.
        result.data;    // `data` will be null.
    }
}]);

‘wiwo.dido.setDataResult’ detail:

var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.dido.setDataResult', function(event, result){
    if (result.success){
        result.message  // Holds information about 'setData' request (can be empty).
        result.data;    // Will be null.
    } else {
        result.message  // Holds information about the error.
        result.data;    // Will be null.
    }
}]);

Widgets do their best to keep in a consistent state and ensure they don’t show complex or code related errors to users. We design them to accept a wide range of inputs, but to ensure accuracy they are conservative in their approach to error handling - they will reject data on error and provide you a result object detailing what went wrong.

Data issues

Widgets pre-process all input data and perform type conversion and internal lookups before calculating or displaying the data you give them. If lookups are invalid or outdated (eg. when you try to look up an outdated product) the widget will log errors and return the error information in the result object.

Most of the time you will still get a calculation value back from 'wiwo.dido.getDataResult', but it will use internal defaults for fields with errors.

Missing required data

Required values that are not supplied will be logged to console and in the result object.

Invalid datatypes

Simply rejected

Outdated/invalid lookup references (i.e. Product names)

You control all product information and settings from your Widget Manager account so you must ensure you keep any external references to product keys up to date.

If you try to set data with references to a product which doesn’t exist the Widget may default to the first applicable in the list or reject your set data (the behaviour is Widget-specific).

iframeUtil API Reference

Summary

The asynchronous API is accessed via the global _wiwo object:

var _wiwo = _wiwo || [];
_wiwo.push(paramList);

Use the “ready” callback to get a reference to the iframeUtil object to call synchronous methods:

var _wiwo = _wiwo || [];
_wiwo.push([function(iframeUtil){
    // Call synchronous methods on `iframeUtil`:
    console.log("Widets on page: ", iframeUtil.getIframes());
}]);

The iframeUtil is used to facilitate communication between the host page and Widgets loaded on that page.

The iframeUtil proivdes an asynchronous API for interacting with the Widgets (based on the Google Analytics asynchronous syntax). This API is exposed via the global _wiwo object.

The _wiwo object acts as a queue that collects API calls until the iframeUtil has been loaded and is ready to execute them. To add a call to the queue use the _wiwo.push method, passing the method name and parameters for that method:

The paramList is an array containing the method name and parameters of the method on the iframeUtil you want to invoke.

The first element of paramList is the name of the method you want to invoke. The remaining elements are the arguments that will be passed to that method.

Syntax

_wiwo.push(paramList)

Parameter Type Description
paramList array An array containing information about the command to run once the iframeUtil is initialised.

Description

Once the iframeUtil has been initialised on the page any queued commands will invoked in the order they were pushed onto the _wiwo queue.

Any commands registered after the iframeUtil has been initialised will be invoked immediately.

Ready functions

Register a “ready” callback:

var _wiwo = _wiwo || [];
_wiwo.push([function(iframeUtil){
  // Work with the initialised `iframeUtil` instance.
}]);

It is possible to push function objects onto the _wiwo queue. The functions will be invoked in order once the iframeUtil has been initialised on the page.

This is useful for calling synchronous methods on the iframeUtil once it has been initialised on the page.

Syntax

_wiwo.push([callback])

Parameter Type Description
callback function A function that will be invoked once the iframeUtil is initalised. The callback function will be passed the iframeUtil instance as the first parameter.

Examples

// List the Widget iframes that have been loaded onto the page.
var _wiwo = _wiwo || [];
_wiwo.push([function(iframeUtil){
    var frameList = iframeUtil.getIframes();
    console.log('frameList=', frameList);
}]);

Method calls

Queue a method call

Queue up a series of method calls using the asynchronous API:

// This event listener will be registered once the `iframeUtil` is initialised.
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.data.getDataResult', function(e, data){
  console.log('getDataResult: data=', data);
}]);

// Register these origins with the `iframeUtil`.
_wiwo.push(['addOrigins', [
    'http://www.example.com',
    'https://www.example.com'
]]);

Push a list containing the methodName and parameters for that method:

_wiwo.push([methodName[, param1[, param2[, ...]]]])

Parameter Type Description
methodName string The name of the method to invoke once iframeUtil is initialised.
paramN any The parameters to pass to the method.

The following methods are available on the iframeUtil:

init()

Manually initialise a Widget

<!-- NOTE: the `data-wiwo-init` attribute is set to "paused" to disable automatic initialisation -->
<script src="https://calcs.widgetworks.com.au/s/bimade/live.js"></script>
<iframe id="wiwo-bimade" width="100%" height="200" src="" frameborder="0" data-wiwo-init="paused"></iframe>
<script src="https://calcs.widgetworks.com.au/widget/widget-scout.min.js"></script>
var _wiwo = _wiwo || [];
_wiwo.push(['init', 'wiwo-bimade');

Summary

Use the init() method to manually initialise a Widget.

Use this method if you want to pass default startup data to a Widget.

By default Widgets are automatically initialised on a page.

If the Widget iframe has the data-wiwo-init attribute set to "false" then the Widget will be automatically initialised on page load.

Set the attribute to data-wiwo-init="paused" to disable automatic initialisation for that Widget and require manual initialisation.

Manual initialisation is triggered by invoking the init() method (see example to the right).

Setting default data

The init() method accepts an optional second parameter of data to set on the Widget during startup.

This is the recommended way of setting default data on a Widget during startup.

This parameter is an InitPayload object.

Pass default data to a Widget

var _wiwo = _wiwo || [];
_wiwo.push(['init', 'wiwo-bimade', {
    setData: {
        // ... startup data goes here ...
        // This is a WidgetData object - the same structure passed to the `setData()` method
        {
            "id": "wiwo-repayment-widget",
            "version": 1,

            // This is the data that will be loaded by the Widget:
            // This data is Widget-specific.
            "input": {
                "repaymentModel": {
                    // The Widget will show these values at startup
                    "propertyValue": 530000,
                    "principal": 424000
                    //...
                }
            }
        }
    }
});

Syntax

iframeUtil.init(frameId[, payload])

_wiwo.push(['setData', frameId[, payload])

Parameters

Property Type Description
frameId string The ID of the frame containing the Widget.
payload InitPayload (optional) An object with a setData property with the default data that should be shown in the Widget at startup.

getData()

Get data from a Widget

var _wiwo = _wiwo || [];
_wiwo.push(['getData', 'wiwo-bimade', function(e, result){
    if (result.success){
        // Do something with `result.data`
    } else {
        // Check error with `result.message`
    }
}]);

Summary

The getData() method lets you easily request data from a Widget.

Syntax

iframeUtil.getData(frameId, callbackFn)

_wiwo.push(['getData', frameId, callbackFn)

Parameters

Property Type Description
frameId string The ID of the frame containing the Widget.
callbackFn Function A function that will receive the Widget data. See DiDo Events.getDataResult for parameter types.

setData()

Send new data to a Widget

var _wiwo = _wiwo || [];
_wiwo.push([
    'setData',
    'wiwo-bimade', 
    {
      "id": "wiwo-repayment-widget",
      "version": 1,

      // This is the data that will be loaded by the Widget:
      // This data is Widget-specific.
      "input": {
        "repaymentModel": {
          "propertyValue": 530000,
          "principal": 424000
        }
      }
    },
    function(e, result){
      if (!result.success){
        // Check error with `result.message`
      }

    }
]);

Summary

The setData() method lets you easily load new data in a Widget.

Syntax

iframeUtil.setData(frameId, payload, callbackFn)

_wiwo.push(['setData', frameId, payload, callbackFn)

Parameters

Property Type Description
frameId string The ID of the frame containing the Widget.
payload WidgetData The data the Widget should load.
callbackFn Function A function that will receive the result of the setData call. See DiDo Events.setDataResult for parameter types.

setAndGetData()

Send new data to a Widget and immediately retrieve the result

var _wiwo = _wiwo || [];
_wiwo.push([
    'setAndGetData',
    'wiwo-bimade', 
    {
      "id": "wiwo-repayment-widget",
      "version": 1,

      // This is the data that will be loaded by the Widget:
      // This data is Widget-specific.
      "input": {
        "repaymentModel": {
          "propertyValue": 530000,
          "principal": 424000
        }
      }
    },
    function(e, result){
      if (result.success){
        // Access calculated results via `result.data`
        result.data
      } else {
        // Check error with `result.message`
      }

    }
]);

Summary

The setAndGetData() method lets you easily load new data in a Widget and immediately retrieve the calculated results.

Behind the scenes it runs setData() and then immediately getData() to get the calculated results.

If there is an error with the setData() call then the error is passed to the callback and getData() is not called.

Syntax

iframeUtil.setAndGetData(frameId, payload, callbackFn)

_wiwo.push(['setAndGetData', frameId, payload, callbackFn)

Parameters

Property Type Description
frameId string The ID of the frame containing the Widget.
payload WidgetData The data the Widget should load.
callbackFn Function A function that will receive the calculated results from a getData call. See DiDo Events.getDataResult for parameter types.

addOrigins()

Add the widget domain as an allowed origin:

var _wiwo = _wiwo || [];
_wiwo.push(["addOrigins", [
  "http://your-widget-domain",
  "https://your-widget-domain"
]]);
// Equivalent to above but using a RegExp
var _wiwo = _wiwo | [];
_wiwo.push(['addOrigins', [
    /https?:\/\/your-widget-domain/
]]);

Summary

The addOrigins() method allows additional domains to communicate with the host page.

The iframeUtil implements a whitelist of domains that are allowed to host Widgets and communicate with the host page. By default only Widgets loaded from the same domain as the host page or loaded from Widget Works Cloud Servers are allowed to send messages to the host page.

If the Widget is self-hosted by the client and served from a different domain to the hosting page then addOrigins() should be used to whitelist the client’s Widget domain.

Syntax

iframeUtil.addOrigins(origin1[, origin2[, ...]])

_wiwo.push(['addOrigins', origin1[, origin2[, ...]] ])

Parameters

Parameter Type Description
originN string | string[] | RegExp | RegExp[] String or RegExp representing Widget hosting domains that are allowed to communication with the host page. The origin values may be strings, RegExp or arrays of these types.

Note

If the browser’s JavaScript console shows the warning:
(iframeUtil) ERROR: Invalid event.origin="<your domain here>" with event="wiwoResize"

Then you should make sure the domain of the hosting page has been added as a valid origin:

on()

// Add an event listener for the `getDataResult` event:
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.dido.getDataResult', function(e, data, originalEvent){
    console.log('`getDataResult` event triggered by frame=', e.frameId);
    console.log('`getDataResult` received data=', data);
}]);

Check which Widget raised the event:

var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.dido.getDataResult', function(e, data){
    // Make sure this event came from the 'wiwo-bimade' iframe.
    if (e.frameId != 'wiwo-bimade'){
        // Ignore if not from 'wiwo-bimade'.
        return;
    }

    // ... handle the event ...
}]);

Summary

The on() method registers an event listener for events raised by any Widget loaded on the host page.

To determine which Widget instance raised the event check the e.frameId property.

Syntax

iframeUtil.on(eventName, function handler(e, data, originalEvent){...})

_wiwo.push(['on', eventName, function handler(e, data, originalEvent){...}])

Parameters

Parameter Type Description
eventName string Add the listener for this event.
handler function The function that will be invoked when the event is raised.

once()

// Add an event listener that will be deregistered after the callback is run.
var _wiwo = _wiwo || [];
_wiwo.push(['once', 'wiwo.dido.getDataResult', function(e, data, originalEvent){
    console.log('`getDataResult` event triggered by frame=', e.frameId);
    console.log('`getDataResult` received data=', data);
}]);

Summary

The once() method acts just like on() except the event listener will be deregistered after the event has fired.

This means the callback will only be invoked once for a given event.

Syntax

iframeUtil.once(eventName, function handler(e, data, originalEvent){...})

_wiwo.push(['once', eventName, function handler(e, data, originalEvent){...}])

Parameters and handler()

This method accepts the same parameters and handler signature as the on() method.

postMessage()

// Request data from the 'wiwo-bimade' Widget iframe.
// The data will be returned via a 'wiwo.dido.getDataResult' event from that iframe.
var _wiwo = _wiwo || [];
_wiwo.push(['postMessage', 'wiwo-bimade', 'wiwo.dido.getData']);
// Set new data on the 'wiwo-bimade' Widget.
// The success/failure result will be returned via a 'wiwo.dido.setDataResult' event.
var _wiwo = _wiwo || [];
_wiwo.push(['postMessage', 'wiwo-bimade', 'wiwo.dido.setData', {
    id: 'wiwo-repayment-widget',
    version: 0,
    input: {
        repaymentModel: {
            principle: 150000,
            rate: 0.065
        }
    }
}]);

Summary

The postMessage() method sends an event to a Widget loaded inside an iframe.

The Widget is identified by the targetFrame parameter.

If any result is expected from the event then it will be triggered asynchronously by the Widget and sent as a new event. e.g. The widget responds to the ‘wiwo.dido.getData’ event by raising a ‘wiwo.dido.getDataResult’ event.

Syntax

iframeUtil.postMessage(targetFrame, eventName[, data])

_wiwo.push(['postMessage', targetFrame, eventName[, data]])

Parameters

Parameter Type Description
targetFrame string | HTMLIFrameElement The ID of the frame or IFrame element that should receive this message.
eventName string The event to send to the iframe. e.g. ‘wiwo.dido.getData’
data object Optional. The data to send with the frame. This is event-specific.

getIframes()

// Call `getIframes()` in the iframeUtil ready function:
var _wiwo = _wiwo || [];
_wiwo.push([function(iframeUtil){
    var frameList = iframeUtil.getIframes();
    console.log('frameList=', frameList);
}]);

/*
frameList= [
    {
        frame: HTMLIFrameElement,
        frameId: 'wiwo-bimade'
    }
]
*/

Summary

Call getIframes() to retrieve a list of all Widget iframes currently registered with the iframeUtil.

This method is only available after the iframeUtil has been loaded and initialised on the page and should be invoked inside the iframeUtil ready function.

Syntax

// `getIframes()` result structure:
[
    {
        frame: HTMLIFrameElement,
        frameId: string
    },
    ...
]

iframeUtil.getIframes()

Description

The iframeUtil.getIframes() method returns an array of objects containing a reference to the Widget’s iframe element and the ID of the frame.

getIframeIds()

// Call `getIframeIds()` in the iframeUtil ready function:
var _wiwo = _wiwo || [];
_wiwo.push([function(iframeUtil){
    var frameIds = iframeUtil.getIframeIds();
    console.log('frameIds=', frameIds);
}]);

/*
frameIds= ["wiwo-bimade", ...]
*/

Summary

Call getIframeIds() to retrieve a list of all Widget iframe IDs currently registered with the iframeUtil.

This method is only available after the iframeUtil has been loaded and initialised on the page and should be invoked inside the iframeUtil ready function.

Syntax

iframeUtil.getIframeIds()

Description

The iframeUtil.getIframeIds() method returns a list of strings.

Each string is the ID of a registered Widget.

refresh()

// Reinitalise a Widget:
var _wiwo = _wiwo || [];
_wiwo.push(['refresh', 'wiwo-bimade']);
// Call `refresh()` to reinitialise a Widget:
var _wiwo = _wiwo || [];
_wiwo.push([function(iframeUtil){
    iframeUtil.refresh('wiwo-bimade');
}]);

Summary

Invoke refresh() to reinitialise a Widget on the current page.

This will reset and reload the Widget.

Syntax

iframeUtil.refresh(frameId)

_wiwo.push(['refresh', frameId)

scrollTo()

// Smooth-scroll to a location on-page:
var _wiwo = _wiwo || [];
_wiwo.push(['scrollTo', 100]);

// Scroll to the location in 100ms
_wiwo.push(['scrollTo', {
    to: 200,
    duration: 100
}]);
// Smooth-scroll an element or Widget into view:
var _wiwo = _wiwo || [];
_wiwo.push(['scrollTo', {
    scrollTarget: '#wiwo-bimade'
}]);

// Scroll element into view in 500ms:
_wiwo.push(['scrollTo', {
    scrollTarget: '#wiwo-bimade',
    duration: 500
}]);

Summary

Invoke scrollTo() to scroll the page to a position or element.

Syntax

iframeUtil.scrollTo(posOrOptions)

_wiwo.push(['scrollTo', posOrOptions)

Parameter Type Description
posOrOptions number or options If a number then scroll to that position. Where 0 is the top of the page and positive numbers are further down the page.

The options object has this structure:

Property Type Description
to number (optional if scrollTarget given) The position to scroll to
scrollTarget string (optional if to is given) The selector string of the element to scroll into view
duration number The duration, in milliseconds, of the smooth-scroll (default is 750)

NOTE: The scrollTarget property should be given as an element selector string (with leading hash: ‘#wiwo-bimade’) as it will be passed to document.querySelector()

scrollBy()

// Smooth-scroll a relative amount:
var _wiwo = _wiwo || [];
_wiwo.push(['scrollBy', 100]);
// Smooth-scroll a relative amount over 100ms:
var _wiwo = _wiwo || [];
_wiwo.push(['scrollBy', {
    to: 100,
    duration: 100
}]);

Summary

Invoke scrollBy() to scroll the page by a relative amount.

Syntax

iframeUtil.scrollBy(posOrOptions)

_wiwo.push(['scrollBy', posOrOptions)

Parameter Type Description
posOrOptions number or options If a number then scroll by that many pixels from the current location. Larger numbers will scroll further, negative numbers will scroll up the page.

The options object has this structure:

Property Type Description
to number The number of pixels to scroll by (positive is down the page, negative values scroll up the page)
duration number The duration, in milliseconds, of the smooth-scroll (default is 750)

Type: FrameEvent

// FrameEvent structure:
interface FrameEvent {
    "frame": HTMLIFrameElement, // The Element that raised the event.
    "frameId": string,          // The ID of the element that raised the event.
    "wiwoEvent": string,        // The name of the event.
    "payload": object           // Event-specific data.
}
// Example FrameEvent object:
{
    "frame": HTMLIFrameElement, // The Element that raised the event.
    "frameId": "wiwo-bimade",   // The ID of the element that raised the event.
    "wiwoEvent": "wiwo.dido.getDataResult", // The name of the event.
    "payload": {...}            // Event-specific data.
}
// Example usage:
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.dido.getDataResult', function(e, data){
    // `e` is a `FrameEvent` object.
    // `data` is a `DidoResult` object (event-specific).
}]);

Summary

The FrameEvent type is the first parameter returned to the on() event handler.

Properties

Property Type Description
frame HTMLIFrameElement Reference to iframe DOM element that raised the event.
frameId string The ID of the frame that raised the event.
wiwoEvent string The name of the event
payload object The data sent from the Widget along with this event. This data is event-specific.

DiDo Event Reference

The Data In/Data Out (DiDo) API.

Note: All of the events and sent to the Widget and any events received back are handled asynchronously. It is not possible to make a synchronous event/method call to the Widget.

Event: getData

// Post a message to request data from a Widget:
var _wiwo = _wiwo || [];
_wiwo.push(['postMessage', 'wiwo-bimade', 'wiwo.dido.getData']);

Summary

The 'wiwo.dido.getData' event is sent from the host page to a Widget.

The Widget will respond with a wiwo.dido.getDataResult event. See wiwo.dido.getDataResult for detail on the response event.

event vs method

This is the 'wiwo.dido.getData' event; there is also a getData() method.

Behind the scenes getData() method uses this event to implement its behaviour.

Syntax

iframeUtil.postMessage(frameId, 'wiwo.dido.getData');

_wiwo.push(['postMessage', frameId, 'wiwo.dido.getData']);

Parameter Type Description
frameId string The ID of the Widget that will receive the event.
‘wiwo.dido.getData’ string The eventName.

Widget responds with wiwo.dido.getDataResult event.

Event: getDataResult

// `wiwo.dido.getDataResult` listener:
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.dido.getDataResult', function(e, result){
  if (result.success){
    console.log('Received data from Widget ID=', e.frameId, ', data=', result.data);
  } else {
    console.warn('Unable to get data from Widget ID=', e.frameId, ', reason=', result.message);
  }
}]);

Summary

The 'wiwo.dido.getDataResult' event is sent from a Widget to the host page in response to a ‘wiwo.dido.getData’ request.

Listener

_wiwo.push(['on', 'wiwo.dido.getDataResult', function handler(e, result){...}])

Handler parameters

Parameter Type Description
e FrameEvent Information about the Widget that emitted the event.
result object DidoResult object. See DidoResult for detail.
// Example `DidoResult` success structure
{
    "success": true,
    "message": '',
    "data": {
        "id": "wiwo-repayment-widget",
        "version": 1,
        "input": {
            ... Widget-specific properties ...
        },
        "output": {
            ... Widget-specific properties ...
        }
    }
}

Note: The result.data object structure is Widget-specific.

Event: setData

Example ‘wiwo.dido.setData’ call:

// The Widget will respond with a 'wiwo.dido.setDataResult' event.
var _wiwo = _wiwo || [];
_wiwo.push(['postMessage', 'wiwo-bimade', 'wiwo.dido.setData', {
    "id": "wiwo-repayment-widget",
    "version": 1,
    "input": {
        "repaymentModel": {
            "propertyValue": 530000,
            "principal": 424000
        }
    }
}]);

Summary

Send 'wiwo.dido.setData' the event to a Widget to trigger it to load data.

The Widget will respond with a wiwo.dido.setDataResult event.

Using 'wiwo.dido.setData' you provide an object to the widget with all the of the standard input fields. Generally, any input field which is available on screen can be set via this API. Refer to the Widget-specific documentation for the input object model.

event vs method

This is the 'wiwo.dido.setData' event; there is also a setData() method.

Behind the scenes setData() method uses this event to implement its behaviour.

Syntax

iframeUtil.postMessage(frameId, 'wiwo.dido.setData', payload)

_wiwo.push(['postMessage', frameId, 'wiwo.dido.setData', payload])

Parameter Type Description
frameId string The ID of the Widget that will receive the event.
‘wiwo.dido.setData’ string The eventName.
payload object | WidgetData The data to be loaded by the Widget. This data is Widget-specific.

Event: setDataResult

// `wiwo.dido.setDataResult` listener:
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'wiwo.dido.setDataResult', function(e, result){
  if (result.success){
    console.log('Successfully loaded data into Widget ID=', e.frameId);
  } else {
    console.warn('Unable to set data on Widget ID=', e.frameId, ', reason=', result.message);
  }
}]);
Response event Result
wiwo.dido.setDataResult result object with result.data.input, the values you called setData with

Type: DidoResult

DidoResult type structure:

interface DidoResult {
    "success": boolean,
    "message": string,
    "data": object
}

Example DidoResult success structure:

{
    "success": true,
    "message": '',
    "data": {
        "id": "wiwo-repayment-widget",
        "version": 1,
        "input": {
            ... Widget-specific properties ...
        },
        "output": {
            ... Widget-specific properties ...
        }
    }
}

Example DidoResult failure structure:

{
    "success": false,
    "message": 'Widget has not been initialised yet.',
    "data": null
}

Summary

The DidoResult object is returned by the ‘wiwo.dido.getDataResult’ and ‘wiwo.dido.setDataResult’ event listeners.

It is used to indicate if the preceeding 'wiwo.dido.getData' or 'wiwo.dido.setData' event was successful and to return any data that may be associated with the event.

Properties

Property Type Description
success boolean Indicates if the ‘getData’ or ‘setData’ request was successful.
message string Will be an empty string if success is true. Otherwise holds the error message explaining why the request failed.
data object | WidgetData Widget-specific response data. Will be null if success is false.

Type: WidgetData

WidgetData type structure:

interface WidgetData {
    "id": string,
    "version": number,
    "input": object,
    "output": object
}

Example WidgetData structure:

{
    "id": "wiwo-repayment-widget",
    "version": 1,
    "input": {
        ... Widget-specific properties ...
    },
    "output": {
        ... Widget-specific properties ...
    }
}

Summary

The WidgetData object is used to describe the input and output data belonging to a Widget.

The WidgetData is returned as the result.data property (see DidoResult) with the wiwo.dido.getDataResult event.

A WidgetData object is passed to a Widget as the payload parameter with the wiwo.dido.setData event.

Properties

Property Type Description
id string Identifies the type of Widget that generated or should receive this data. Used by the Widget to verify the expected data structure.
version number An integer that indicates the version of this Widget data structure. The version number is determined by the Widget that generated the data object. When loading data this value is used to validate the expected data structure. If the version number is larger than the version expected by the Widget it will be rejected.
input object Optional. Widget-specific input data.
output object Optional. Widget-specific result data.

Note: Whilst the id and version properties are required, any other properties on WidgetData are Widget-specific. The previous table should be used as a general guide only - see Widget-specific documentation to see if the structure differs for that Widget.

Type: InitPayload

InitPayload type structure

interface InitPayload {
    "setData": WidgetData
}

Example InitPayload strucutre:

{
    "setData": {
        "id": "WidgetId" // e.g. "wiwo-repayment-widget",
        "version": 1,
        "input": {
            ... Widget-specific properties ...
        },
        "output": {
            ... Widget-specific properties ...
        }
    }
}

Summary

The InitPayload object is used to pass default data to a Widget during initialisation (see the init method).

If given a valid strucutre, the Widget will startup with the default values set.

Properties

Property Type Description
setData WidgetData (optional) Default data to set on the Widget during initialisation

Analytics Event Reference

The Widgets may emit tracking events that can be used to integrate with data analytics services.

See the examples for Adobe Marketing Cloud and Google Analytics.

Event: pageTrack

Example ‘pageTrack’ event listener:

var _wiwo = _wiwo || [];
_wiwo.push(['on', 'pageTrack', function(e, path){
    console.log('User viewing path: ', path);
}]);

Summary

The 'pageTrack' event is emitted by the Widget as the user navigates through the Widget.

The event listener parameters contain information about the Widget that raised the event and the URL path fragment that represents the application state that the user is viewing.

Listener

_wiwo.push(['on', 'pageTrack', function handler(e, path){...}])

Handler Parameters

Parameter Type Description
e FrameEvent Information about the Widget that emitted the event.
path string The URL path fragment that represents the application state that the user is viewing. This value always includes a leading slash ‘/’.

Event: eventTrack

Example ‘eventTrack’ event listener:

var _wiwo = _wiwo || [];
_wiwo.push(['on', 'eventTrack', function(e, properties){
    console.log('User interaction: category="%s", action="%s", label="%s", value=%s',
        properties.category,
        properties.action,
        properties.label,
        properties.value
    );
}]);

Summary

The 'eventTrack' event is emitted by the Widget when the user interacts with the Widget.

It represents the user performing some action inside the Widget - e.g. clicking a button, showing a tooltip, etc.

The first time the user interacts with the Widget a special 'eventTrack' is raised with the category property set to ‘initial’.

Listener

_wiwo.push(['on', 'eventTrack', function handler(e, properties){...}])

Handler Parameters

Parameter Type Description
e FrameEvent Information about the Widget that emitted the event.
properties EventTrackProperties The tracking properties associated with this event.

Type: EventTrackProperties

interface EventTrackProperties {
    category: string,
    action: string,
    label: string,
    value: number
}
Property Type Description
category string

The type of item that triggered the event.

Examples:

  • ‘initial’ - the user’s first interaction with the Widget on the page.
  • ‘control’ - the user interacted with a control.
  • ‘interaction’ - general interaction with the Widget, but not associated with an input control.
action string

The type of interaction that triggered the event.

For controls associated with another input (e.g. a slider associated with a text input field) this will contain the action followed by the control type, separated by a ‘|’ character.

Examples:

  • ‘click’ - an element was clicked or tapped.
  • ‘change’ - the value of a control was changed.
  • ‘change|slider’ - the value of the control was changed by a slider.
label string

The identifier of the item that triggered the event.

For list selection controls (select menu, radiobuttons) this will be the identifier followed by the new selection value, separated by a ‘:’ character.

The actual values of the `label` property will vary depending on the Widget being tracked.

Examples:

  • ‘current.voluntaryContribution’ - This event relates to the ‘current.voluntaryContribution’ control
  • ‘adjusted.voluntaryContribution’ - This event relates to the ‘adjusted.voluntaryContribution’ control
  • ‘repaymentModel.product:wiwoFixed5Y’ - This event relates to the ‘repaymentModel.product’ control and the new value is ‘wiwoFixed5Y’.
value number

Optional.

If there is a numeric value associated with the event then this property will be present.

Examples:

  • undefined - This event does not have an associated numeric value.
  • null - This event does not have an associated numeric value.
  • 29000 - The value associated with this event is 29000.
  • 0.0775 - The value associated with this event is 0.0775.

Adobe Marketing Cloud Integration

Example page view tracking (navigation event) in Adobe Marketing Cloud.

var _wiwo = _wiwo || [];
_wiwo.push(['on', 'pageTrack', function(e, path){
    /*
    // Set additional tracking properties here as determined
    // by your tracking requirements.

    s.prop1 = 'tools:calculator:repayment';
    */

    s.t();
}]);

Example link/interaction tracking in Adobe Marketing Cloud.

var _wiwo = _wiwo || [];
// An example of how 
_wiwo.push(['on', 'pageTrack', function(e, properties){
    /*
    // Set additional tracking properties here as determined
    // by your tracking requirements.

    s.prop1 = 'tools:calculator:repayment';
    s.prop2 = s.eVar1 = properties.category;
    s.events = 'event1';
    */

    s.tl(true, 'o', properties.label);
}]);

Integration with Adobe Marketing Cloud (formerly Omniture/SiteCatalyst) is supported through the 'pageTrack' and 'eventTrack' events emitted by the Widgets.

See the Adobe Marketing Cloud documentation for more information on available tracking options.

See EventTrackProperties for the properties available to the 'eventTrack' event.

Google Analytics Integration

Example analytics.js tracking:

Google Analytics tracking is supported through the 'pageTrack' and 'eventTrack' events emitted by the Widgets.

These can be mapped to the pageview and event commands.

// With `analytics.js`
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'pageTrack', function(e, path){
    ga('send', 'pageview', path);
}]);
// With `analytics.js`
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'eventTrack', function(e, properties){
    // Pass `properties.value` if it exists, otherwise set `value` to `undefined`.
    var value = properties.value == null ? void 0 : properties.value;

    // Set any additional tracking properties as required by your analytics requirements.

    ga('send', 'event', properties.category, properties.action, properties.label, value);
}]);

See the Universal Analytics documentation:


Legacy ga.js tracking:

// With legacy `ga.js`
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'pageTrack', function(e, path){
    _gaq.push(['_trackPageview', path]);
}]);
// With legacy `ga.js`
var _wiwo = _wiwo || [];
_wiwo.push(['on', 'eventTrack', function(e, properties){
    // Pass `properties.value` if it exists, otherwise set `value` to `undefined`.
    var value = properties.value == null ? void 0 : properties.value;

    // Set any additional tracking properties as required by your analytics requirements.

    _gaq.push(['_trackEvent', properties.category, properties.action, properties.label, value]);
}]);

The the legacy ga.js Google Analytics library will map to: