Widget Developers Tutorial
Overview
Widgets in Orchestra are based on the open source Apache Wookie widget engine (albeit a highly customised port of wookie). The Wookie engine provides support for widgets conforming to the W3C Widget specification.
Documentation on Wookie and the widget specification can be found on the Internet. All widgets conforming to the W3C spec that run on Wookie will also run on Orchestra.
Anatomy of a Widget
As a minimum a widget consists of the following files:
| File | Description |
|---|---|
config.xml | Base specification of the widget |
index.html | Start page of the widget, should include required JavaScript and CSS resources and declare a <body/> element |
i18n/attribute_<lang>.properties | The i18n folder should contain properties files providing translations for <q:attribute> name and description values. These translations are shown in the properties pane in the Surface Editor. |
The files and folders making up a widget are packaged as a zip archive with a .wgt extension.
The name of the archive must match the id and name of the widget as configured in the config.xml file. For example, if the widget has an id of http://qmatic.com/widgets/myWidget and a name of myWidget then the archive must be named myWidget.wgt. If the archive name does not match, widgets will not be updated correctly when publishing.
Config.xml
The config.xml file resides in the root folder of the widget and provides the required properties that specify the basic configuration of the widget.
The non-namespaced elements are defined by the W3C specification.
Example:
<widget xmlns="http://www.w3.org/ns/widgets"
xmlns:q="http://qmatic.com"
id="http://qmatic.com/widgets/myWidget"
version="0.1"
width="200"
height="320">
<name>myWidget</name>
<name xml:lang="en">my cool widget</name>
<description>My first attempt at creating a widget</description>
<author>Qmatic</author>
<license>Copyright (c) Qmatic</license>
<!-- Tell wookie to include resources from orchestra-widget feature.
This feature allows us to get events from Orchestra and communicate
with other widgets and receive q:attribute data -->
<!-- This feature must be first in the list of features -->
<feature name="http://qmatic.com/features/orchestra-widget" required="true"/>
<!-- Tell wookie to include resources from orchestra-connector feature.
This feature allows us to call widget connector API methods only
available to widgets -->
<feature name="http://qmatic.com/features/orchestra-connector" required="true"/>
<content src="index.html"/>
<icon src="images/myWidgetIcon.jpg"/>
<access origin="*"/>
<q:standalone>false</q:standalone>
</widget>
The <widget/> element has a number of attributes:
| Attribute | Description |
|---|---|
id | Unique id for the widget |
version | Increment the version number every time the widget code is updated otherwise it will be ignored when uploaded if the version number is the same or lower than current uploaded version |
width | Width of the widget in pixels (note that in the surface editor the size of the widget can be changed) |
height | Height of the widget in pixels (note that in the surface editor the size of the widget can be changed) |
The <feature/> elements represent features installed in the wookie engine. Features represent external dependencies in a widget in the way of JavaScript libraries. Instead of having to manually manage these dependencies in each widget, using features will dynamically include the latest JavaScript resources in the widget at runtime.
Qmatic provides two features in wookie by default: orchestra-widget, touchprinter-widget, and orchestra-connector. See the later section on Features for an explanation on how to use these.
The <q:standalone/> element identifies whether we want the widget to be integrated with Orchestra or fully standalone (defaults to true if omitted). Setting this element to false enables the use of attributes in the surface editor and communication with Orchestra including widget-to-widget communication within the host page.
Widget Attributes
Optionally a widget can specify any number of <q:attribute/> elements that will be used to present attributes in the surface editor properties pane.
Example:
<q:attribute type="string" key="text.above.ticket" name="text.above.ticket"
description="text.above.ticket.description" defaultValue="Go to counter"/>
<q:attribute type="integer" key="top.margin" name="top.margin"
description="top.margin.description" defaultValue="20"/>
<q:attribute type="color" key="ticket.background.color" name="ticket.background.color"
description="ticket.background.color.description" defaultValue="#E5EDFF"/>
<q:attribute type="font" key="ticket.number.font" name="ticket.number.font"
description="ticket.number.font.description" defaultValue="Helvetica;46px;normal;normal"/>
<q:attribute type="boolean" key="show.direction" name="show.direction"
description="show.direction.description" defaultValue="false"/>
<q:attribute type="image" key="arrow.left.image" name="arrow.left.image"
description="arrow.left.image.description"/>
Each <q:attribute/> element has a number of attributes:
| Attribute | Description |
|---|---|
type | Used to determine the type of control presented in the surface editor for setting the attribute value |
key | Unique identifier |
name | Maps to a translatable resource in i18n/attributes_<lang>.properties |
description | Maps to a translatable resource in i18n/attributes_<lang>.properties |
defaultValue (optional) | Default value |
validation (optional) | Regular expression which defines allowed values |
validationMessage (optional) | Maps to a translatable resource in i18n/attributes_<lang>.properties |
Supported q:attribute types:
| Value | Surface Editor Control |
|---|---|
number | Text input. Use in combination with a validation regular expression to limit to only numeric input. |
string | Text input |
color | Color picker |
font | Font picker allowing selection of font, size, style, and weight. The value is stored in a semicolon delimited string format, e.g. Arial;12pt;Italic;bold |
boolean | Drop-down with Yes / No selection |
service | Drop-down list of all Services configured for the operations profile associated with the surface |
queue | Drop-down list of all queues configured for the operations profile associated with the surface |
image | Image picker |
audio | Audio file picker |
enumlist | Drop-down with the pre-defined enum values specified inside the <q:enum/> element |
Enum attributes support a nested <q:enum/> element to provide a configurable list of selectable items:
<q:attribute type="enumlist" key="weekday" name="weekday" description="weekday.desc">
<q:enum name="monday" value="0"/>
<q:enum name="tuesday" value="1"/>
</q:attribute>
Features
Qmatic provides 3 features within Wookie that provide most of the plumbing necessary for a widget to integrate with Orchestra.
orchestra-widget
<feature name="http://qmatic.com/features/orchestra-widget" required="true"/>
With this feature enabled in the config.xml the widget only needs to implement two JavaScript callbacks:
qmatic.webwidget.client.setOnLoaded(<callback>)qmatic.webwidget.client.setOnLoadError(<callback>)
In Qmatic standard widgets these are typically defined in a JavaScript file called controller.js and are called from the widget host page (typically index.html) when the document has loaded.
Example index.html:
<!DOCTYPE html>
<html>
<head>
<title>Customer Call Ding Widget</title>
<meta http-equiv="pragma" content="no-cache"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="css/ding.css" />
<script src="scripts/jquery-1.5.1.min.js"></script>
<script src="scripts/controller.js"></script>
<script type="text/javascript">
// The following function will be called when page has been loaded
$(function() {
// hook up widget client event
qmatic.webwidget.client.setOnLoaded(controller.onLoaded);
qmatic.webwidget.client.setOnLoadError(controller.onLoadError);
});
</script>
</head>
<body style="overflow: hidden;display:hidden;">
<div id="content"></div>
</body>
</html>
Example controller.js:
var controller = (function($) {
// Public contents of controller
return {
/**
* Called when widget client has finished loading.
* This is where you initialise your widget
*/
onLoaded : function(configuration) {
var attr = configuration.attributes;
for(i in attr) {
switch(attr[i].key) {
case 'image.url':
// Add an image showing the image at the supplied URL.
$('#content').html('<img id="newImage" src="' + attr[i].value + '"/>');
break;
}
}
// Subscribe to customer called
qmatic.webwidget.client.subscribe(
qmatic.webwidget.topic.CUSTOMER_CALLED,
onCustomerCallEvent
);
},
onLoadError : function(message) {
$('body').append('<p>Widget load error: ' + message + '</p>');
}
};
})(jQuery);
The onLoadError callback takes a string with the error message if something fails when communicating with Orchestra. Use this to gracefully handle exceptions in widgets.
The onLoaded callback takes a configuration object that contains the attribute values as configured in the surface editor.
Configuration object properties:
| Property | Description |
|---|---|
width | Actual width of the widget in pixels |
height | Actual height of the widget in pixels |
protocol | The protocol (HTTP or HTTPS) of the host page URL |
host | Hostname / IP address of the host page URL |
port | Port number of the host page URL |
image_resource_path | The location where Orchestra provides image content |
attributes | An associative array of all <q:attribute/> elements defined in config.xml with the values as configured in the surface editor |
Widget Client Methods:
| Method | Description |
|---|---|
getUnitId() | Returns the unitId the surface app is running on |
getBranchId() | Returns the current branch id the surface app is running in |
getConfiguration() | Returns the configuration object |
getLocale() | Returns the locale setting of the host page |
getDisplayType() | Returns the display type for widgets running on graphical display unit types |
getCurrentHostPage() | Returns the name of the current page being displayed on the host page |
log(severity, message) | Write a log message to the Orchestra log file. Severity: DEBUG, INFO, WARN, ERROR, FATAL |
subscribe(topic, onData, scope, onComplete, subscriberData) | Subscribe to a topic to receive published data |
unsubscribe(subscriptionId, onCompleted, scope) | Unsubscribe from a topic |
publish(topic, data) | Publish data to subscribers of a specified topic |
setOnLoaded(callback) | Sets the callback function invoked when the widget is loaded |
setOnLoadError(callback) | Sets the callback function invoked if the widget could not establish connection with Orchestra |
setOnCleanUp(callback) | Sets the callback function invoked when the widget is unloaded |
switchHostPage(pageName, isStayOnPage) | Switch the page displayed on the host page |
putDataIntoAppCache(key, value) | Put data into a global application cache |
getDataFromAppCache(key) | Retrieve data from the cache |
clearCache() | Clear all data from the cache |
touchprinter-widget
The touchprinter-widget feature provides the same methods as the orchestra-widget. This feature has special optimisations to handle specific browser behaviours in Qmatic TP series touch printers and should be used instead of the orchestra-widget feature in those situations.
connector-client
A feature in R5.2, the connector-client feature gives widgets access to underlying functionality from the Orchestra connector interfaces.
The qmatic.webwidget.connector object exposes methods for:
- Getting branches, queues, services, and service points
- Creating and managing visits
- Working with appointments and customers
- Managing global and branch variables
Events
Intra-widget communication in a surface application can be performed by using the methods on the widget-client feature to publish and subscribe to topics using your own custom topic names.