Widget Works Widget API
Overview
The Widget is made up of four components that work together to embed the tool on your webpage.
- Host page - your webpage that will host the Widget.
- Widget - the Widget and all of its associated assets - loaded into an iframe on the host page.
- Helper library - The iframeUtil library loaded on the host page that allow communication between the host page and Widget.
- 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:
- an event result object : failure/success, and details of any errors
- a data object : actual data from the widget, calculation results, etc. Refer to your Widget specific documentation for the data properties.
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:
- Invoke the getData() method on the Widget.
- The iframeUtil will use the iframeUtil.postMessage() method to send a
'wiwo.dido.getData'
event to the Widget. - The Widget receives the event and processes the data into the required JSON structure.
- The Widget will send the
'wiwo.dido.getDataResult'
event back to the iframeUtil. - 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:
- Invoke the setData() method on the iframeUtil, passing the frameId and data you want to load.
- The iframeUtil will use the iframeUtil.postMessage() method to send a
'wiwo.dido.setData'
event to the Widget along with the data payload. - The Widget receives the event, validates the data payload and loads the new data.
- The Widget will send the
'wiwo.dido.setDataResult'
event back to the iframeUtil. - 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:
For this example the parent page URL is: https://wm.widgetworks.com.au/widget/bimade/live
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>
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=…
The value of the parameter is the URI-encoded JSON data for that Widget
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.
The array may queue a “ready” function:
_wiwo.push([function(iframeUtil){...}]);
or a method call:
_wiwo.push(['methodName', param1, param2, ...]);
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.
If you’ve previously used the ‘wiwo.dido.getData’ and ‘wiwo.dido.getDataResult’ events then you can easily migrate to using the getData() method instead.
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.
If you’ve previously used the ‘wiwo.dido.setData’ and ‘wiwo.dido.setDataResult’ events then you can easily migrate to using the setData() method instead.
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. |
- Include the Widget identifier. In this case it’s ‘wiwo-repayment-widget’
- Include the
version
number of the data structure.
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:
|
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:
|
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:
|
value | number |
Optional. If there is a numeric value associated with the event then this property will be present. Examples:
|
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: