Simphony HTML5 Custom Page Control API Reference Guide

Oracle® MICROS Simphony
Simphony HTML5 Custom Page Control API Reference Guide
Release 19.7
June 2024

Copyright © 2024, Oracle and/or its affiliates.

Introduction

  • The HTML5 Custom Page Control feature allows you to place custom UI elements on a page in the Page Design module beyond the functionality of loose XAML.
  • The HTML5 Custom Page Control feature is available in the EMC Page Design module, under the Other menu. Similar to the Custom Content Loader, which allows page designers the ability to select loose XAML to be the content of a custom page control, the HTML5 Custom Page Control is placed onto a page, and an extensibility application will provide the dynamic HTML content to the control.
  • The HTML5 Custom Page Control feature is only available under OPS; neither Kiosk nor STS will be making use of HTML5 Custom Page Controls.
  • For OPS, the HTML5 Custom Page Control feature is supported on Win32, Linux and Android clients.
  • The HTML5 Custom Page Control displays the extensibility application’s HTML content in an embedded browser control if Windows, or an iFrame in Linux/Android.

Operation

Custom Page Controls allow an extensibility developer to place user-defined HTML5 controls on a POS page.

The general life cycle of a Custom Page Control is:

  1. extensibility application registers the Custom Page Control with the POS. This involves specifying the page HTML5 source for the POS to load into the browser control on the page.
  2. When a page is first displayed, a custom HTML page control will make a request to the POS for its HTML5 content.
  3. The page control can now enact request/response operations to its owning extensibility application.
  4. The page control can send asynchronous messages to its extensibility application
  5. The extensibility application can send asynchronous messages to the page control.

General notes on page controls:

  • Page control HTML runs inside a browser control, and not in the POS ServiceHost.exe application address space.
  • A Custom Page Control does not have access to the full OpsContext, Datastore, or any of the data available to extensibility applications. It can request any required data from its owning extensibility application.
  • An extensibility application can register as many distinct Custom Page Control sources as possible. The Custom Page Control types are differentiated by a “key” field. For example, the sign in page control’s key may be “GeneralEmplMessages” and a transaction page control’s key may be “SpecialsOfTheDay”. The key field allows the extensibility application to specify many sources for the Custom Page Control content.
  • Due to POS pages being refreshed, all Custom Page Control must expect to handle being recycled (destroyed, recreated). This can occur for a variety of reasons; the page control is responsible for managing its own state.
  • The Custom Page Control API is not the JavaScript Extensibility API. The page control has its own limited API that has little in common with the JS API.

Minimum Content required

Extension Application (JS / C# / SIM)

The Extension Application will register the Page Control with the POS Client. Any interaction between the Extension Application and the Page Control is optional and not required if the Page Control handles any logic on its own.

Page Control HTML5

The actual HTML5 that will be rendered and shown. HTML5 should be understood as any combination of HTML, CSS and JavaScript that is required.

It is suggested to pay attention to create responsive layout(s). Neither the POS client resolution can be foreseen nor the dimension of the page control on the actual page.

There are many ways to supply Page Control HTML5. The extensibility application can read it from Content, Extension Application Content, the Extensibility Package, or as an embedded resource in a C# extension application. Which source is chosen is up to the extensibility developer.

For Application Content it needs to be ensured that both Page Control HTML5 and JS/C#/SIM reside within the same Ext.App.

API

API Objects

Page controls utilize one or more of the following API objects:

C#/JS/SIM code

Micros.PosCore.Extensibility.UserInterface namespace
Object Description
Resource specification objects
PageControlInPlaceResourceParameters html content is supplied in the object
PageControlLocalDirectoryResourceParameters content resides on disk
PageControlPackageDirectoryResourceParameters content resides in package
PageControlWebDirectoryResourceParameters web directory zip byte[] array content is supplied in the parameters object
PageControlExtAppContentResourceParameters web directory zip byte[] array content exists in Extension Application Content
PageControlContentResourceParameters content web directory zip byte[] array content exists in Content
Async message to one or more page controls
PageControlAsyncMessageParameters
Micros.PosCore.Extensibility.Ops namespace
Object Description
OpsPageControlEventArgs synchronous request/response event args
OpsPageControlAsyncEventArgs asynchronous event args

Page control JavaScript API objects

Object Description
SimphonyPOSAPI root level API object
SimphonyPOSAPI_ExtensibilityEventParameters Used with synchronous messages from HTML5 Custom Page Control to the extension application
SimphonyPOSAPI_ExtensibilityMethodParameters Used with synchronous method call from HTML5 Custom Page Control into the extension application
SimphonyPOSAPI_OpsCommand Used with postOpsCommand() or postOpsCommandMacro()
SimphonyPOSAPI_AsyncMessageType Used with asynchronous messages from HTML5 Custom Page Control to the extension application
SimphonyPOSAPI_ReadyMessage Object type when msg.Type is SimphonyPOSAPI_AsyncMessageType.Ready
SimphonyPOSAPI_ExtAppAsyncMessage Object type when msg.Type is SimphonyPOSAPI_AsyncMessageType.ExtApp
SimphonyPOSAPI_OpsContextChangeMessage Object type when msg.Type is SimphonyPOSAPI_AsyncMessageType.OpsContextPropertyChanged

Asynchronous message object inheritance

class __SimphonyPOSAPI_BaseAsyncMessage
{
    // indicates the type of object for this message
    Type;
}

// object type when msg.Type == SimphonyPOSAPI_AsyncMessageType.Ready
class SimphonyPOSAPI_ReadyMessage extends __SimphonyPOSAPI_BaseAsyncMessage
{
}

// object type when msg.Type == SimphonyPOSAPI_AsyncMessageType.ExtApp
class SimphonyPOSAPI_ExtAppAsyncMessage extends __SimphonyPOSAPI_BaseAsyncMessage
{
    // data from the extensibility application
    Data;
}

// object type when msg.Type == SimphonyPOSAPI_AsyncMessageType.OpsContextPropertyChanged 
class SimphonyPOSAPI_OpsContextChangeMessage extends __SimphonyPOSAPI_BaseAsyncMessage
{
    // list of names of OpsContext values that have changed, such as "TransEmployeeID"
    Names = [];
}

Extension Application API

Initialize Page Control

Method / Property Description
RegisterPageControlResource(string extAppName,
string key, object resourceObj)
Registers a Page Control Resource so that OPS will be able to render it.
  • Method exposed in OpsContext.
  • Full Namespace Micros.Ops.Extensibility.OpsContext
  • Parameter extAppName : the name of the calling extension application.
  • Parameter key needs to be used when a Custom Page Control is placed on any POS page. Key only has meaning for the extension application and will accompany any page control request.
  • Parameter resourceObj : must derive from Micros.PosCore.Extensibility.UserInterface.PageControlResourceParameters
PageControlResourceParameters
(base abstract class)
  • namespace Micros.PosCore.Extensibility.UserInterface
  • this class by itself not can it be instantiated
  • bool ReloadControls : reload any existing controls already register with this key, default ‘true’
  • string StartResource : starting page name, default “index.html”
PageControlInPlaceResourceParameters
  • namespace Micros.PosCore.Extensibility.UserInterface
  • derives from PageControlResourceParameters, i.e. includes all properties of the base class
  • string HTML : html contents
PageControlLocalDirectoryResourceParameters
  • namespace Micros.PosCore.Extensibility.UserInterface
  • derives from PageControlResourceParameters, i.e. includes all properties of the base class
  • string DirectoryName : the path of the html content on local disk
PageControlPackageDirectoryResourceParameters
  • namespace Micros.PosCore.Extensibility.UserInterface/li>
  • derives from PageControlResourceParameters, i.e. includes all properties of the base class
  • string DirectoryName : the path of the html content on local disk
PageControlWebDirectoryResourceParameters
  • namespace Micros.PosCore.Extensibility.UserInterface
  • derives from PageControlResourceParameters, i.e. includes all properties of the base class
  • byte[] WebDirectoryZip : byte array containing zip html directory contents
  • string ZipPassword : optional password for zip file
PageControlExtAppContentResourceParameters
  • namespace Micros.PosCore.Extensibility.UserInterface
  • derives from PageControlResourceParameters, i.e. includes all properties of the base class
  • string ContentName : ext app content zoneable key containing the byte array zip html directory contents
  • string ZipPassword : optional password for zip file
PageControlContentResourceParameters
  • namespace Micros.PosCore.Extensibility.UserInterface
  • derives from PageControlResourceParameters, i.e. includes all properties of the base class
  • string ContentName : content zoneable key containing the byte array zip html directory contents
  • string ZipPassword : optional password for zip file

Messages

Extension App to Page Control
Method / Property Description
SendAsyncPageControlMessage(parms) Sends an asynchronous message to the page control
  • namespace Micros.Ops.Extensibility.OpsContext
  • parms is of type PageControlAsyncMessageParameters()
PageControlAsyncMessageParameters
  • Used as parameter with SendAsyncPageControlMessage()
  • namespace Micros.PosCore.Extensibility.UserInterface
  • string ExtAppName : ext app name associated with page control
  • string Key : target page control, if null then all page controls for that ext app will receive the message
  • string ID : target page control ID, if null then all page controls for that ext app will receive the message
  • string Command : meaningful to page control
  • string Data : meaningful to page control
Events
Method / Property Description
OpsPageControlAsyncEvent Triggered by any asynchronous message that is received from a Page Control. A OpsPageControlAsyncEventArgs is passed in.
OpsPageControlAsyncEventArgs
  • string Key : key of source page control
  • string ID : ID of source page control
  • string Message : generated by page control
  • string Data : generated by page control
OpsPageControlEvent Triggered when page control sends message to ext application. A OpsPageControlEventArgs is passed in.
OpsPageControlEventArgs
  • string Key : key of source page control
  • string ID : ID of source page control
  • string Command : generated by page control
  • string Argument : generated by page control
  • string Response : generated by extension application, returned to page control
Page Control to Extension App via POSPageControlAPI.js
Method / Property Description
setAsyncMessageCallback(callback) Sets the callback function that handles asynchronous messages from the Ext.App
log(level, text) level is of type SimphonyPOSAPI_LogLevel, see below
postShowError(text) causes the text to be shown as error in OPS
postShowMessage(text) causes the text to be shown as message in OPS
postOpsCommand(opsCmd) opsCmd is of type SimphonyPOSAPI_OpsCommand, see below
postOpsCommandMacro(opsCmdMacro) opsCmdMacro is a list of SimphonyPOSAPI_OpsCommand, see below
postMessageToExtApp(message, data) both message and data are string
runExtensibilityEvent(parms, callback) parms is of type SimphonyPOSAPI_ExtensibilityEventParameters()
runExtensibilityMethod(parms, callback) parms is of type SimphonyPOSAPI_ExtensibilityMethodParameters()
SimphonyPOSAPI_LogLevel
    NONE: -99,
    LOG_ALWAYS_ERROR: -3,
    LOG_ALWAYS_WARN: -2,
    LOG_ALWAYS_INFO: -1,
    LOG_ALWAYS_DEBUG: 0,
    LOG_ALWAYS: 0,
    LIGHT_FLOW: 1,
    GENERAL_FLOW: 2,
    DETAIL_FLOW: 3,
    BUFFER_DUMPS: 4,
    ULTIMATE_DEBUG: 5,
SimphonyPOSAPI_OpsCommand
{
  Command;
  Number;
  Index;
  Text;
  Arguments;
  NextPage;
  NextPanel;
}

Diagrams

Single extension application, single page control Single extension application, single page control

Multiple extension application, each with its own page control Multiple extension application, each with its own page control

One extensibility application, multiple page controls One extensibility application, multiple page controls

EMC Configuration

A HTML5 custom page control requires valid HTML5 to be present, i.e. as Application Content or as Content. This can be either a plain string or a Web-Directory (zipped).

A HTML5 custom page control also requires an Ext.App that will initialize it. The Ext.App will read the HTML content (see previous point) and will determine the resource key (string) to be used in the EMC page configuration. The resource key can be any value.

A HTML5 custom page control can be added to any page using the option “Custom Html Page Control” in the “Other…” menu:

EMC Other menu

In the properties of the HTML5 custom page control the Ext.App Name as well as the resource key (string) need to be specified. The argument value is optional.

EMC Custom Html Page Control properties

Feature FAQ

I have an index.html file; how do I make it appear in a Custom HTML Page Control?

The first step is to register the Custom HTML Page Control via the OpsContext.RegisterPageControlResource() method. The arguments are straightforward:

  • string extAppName : the name of the extension application
  • string key : an identifier for that Custom HTML Page Control. This must match what is programmed on the page.
  • object resourceObj : the source for the html content.

There are 6 different ways to specify the html source.

  • PageControlInPlaceResourceParameters : The html content is a simple html string. This should be used if your entire Custom HTML Page Control can be contained within a single index.html.
  • PageControlLocalDirectoryResourceParameters : The html content is in a web directory on the local disk. This is usually used during development but generally not for production machines.
  • PageControlPackageDirectoryResourceParameters : The html content is in a web directory in the ext app package. If you are using packages then this is the simplest and preferred way for complex html content.
  • PageControlWebDirectoryResourceParameters : The zipped web app is read from an external source as a byte array. This is useful for debugging.
  • PageControlExtAppContentResourceParameters : The zipped web app is in extension application content. If you are not using packages then this is the simplest and preferred way for complex html content.
  • PageControlContentResourceParameters : The zipped web app is in content.
let resourceParms = null;
 
// both page controls' source is in the package itself
resourceParms = new _pos.Micros.PosCore.Extensibility.UserInterface.PageControlPackageDirectoryResourceParameters();
resourceParms.DirectoryName = "pagectl/app1";
_api.Environment.Context.RegisterPageControlResource(_api.Runtime.ApplicationName, "app1", resourceParms);
 
resourceParms = new _pos.Micros.PosCore.Extensibility.UserInterface.PageControlPackageDirectoryResourceParameters();
resourceParms.DirectoryName = "pagectl/app2";
_api.Environment.Context.RegisterPageControlResource(_api.Runtime.ApplicationName, "app2", resourceParms);

How does my Custom HTML Page Control html application access an API to do something useful?

Similar to Custom HTML Dialogs, Custom HTML Page Control are provided a global API object: SimphonyPOSAPI. This can be inserted into the global namespace using the <script> tag,

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script src="Simphony/POSPageControlAPI.js" type="text/javascript"></script>
 
    <SCRIPT LANGUAGE='JavaScript'>
        console.log(SimphonyPOSAPI.key);
    </SCRIPT>

Can I use the Custom HTML Page Control API right away in my HTML application?

No. You must wait for the Ready message to begin using API functions.

You Custom HTML Page Control should subscribe to message callback facility in the API. By registering your callback you will receive notification of various events.

// register callback
var _api = SimphonyPOSAPI;

_api.setAsyncMessageCallback(asyncMessageCallback);
 
function asyncMessageCallback(msg)
{
    switch (msg.Type)
    {
        case SimphonyPOSAPI_AsyncMessageType.Ready:
                // api can be accessed
                break;
    }
}

How do I send a message from the Custom HTML Page Control to my extension application?

There are two types of messages that can be sent:

  1. synchronous: request is sent and a response is expected from the extension application. This can be done either as an extensibility event or an extension method.
  2. asynchronous: message sent to the extension application with no response expected.

Synchronous example

The following code exists in the Custom HTML Page Control source.

var _api = SimphonyPOSAPI;

// extension application receives message in event
function runExtensibilityEvent(command, argument, callback)
{
    let parms = new SimphonyPOSAPI_ExtensibilityEventParameters();
    parms.command = command;
    parms.argument = argument;
    return _api.runExtensibilityEvent(parms, (parmsOut) => processResponse(parmsOut, callback));
}
 
// extension application method is called directly
function runExtensibilityMethod(method, argument, callback)
{
    let parms = new SimphonyPOSAPI_ExtensibilityMethodParameters();
    parms.method = method;
    parms.argument = argument;
    return _api.runExtensibilityMethod(parms, (parmsOut) => processResponse(parmsOut, callback));
}
 
function processResponse(parmsOut, callback)
{
    if (parmsOut.isSuccess())
        callback(parmsOut.response);
    else if (parmsOut.isError())
        alert('Error: ' + parmsOut.response);
    else if (parmsOut.isTimeout())
        alert('Timeout');
}

The following code exists in the extension application.

var _api = SimphonyExtensibilityAPI;

_api.Eventing.SubscribeToEvent('OpsPageControlEvent', OnOpsPageControlEvent);
 
// responds to page control _api.runExtensibilityEvent() method
function OnOpsPageControlEvent(sender, args)
{
    args.Response = "extensibility event myresponse";
}
 
// responds to page control _api.runExtensibilityMethod() method
globalThis.mymethod = function (args)
{
    args.Response = 'extensibility method response';
}

Asynchronous example

The following code exists in the Custom HTML Page Control source.

var _api = SimphonyPOSAPI;

let line = `async message from page control; ${new Date()}`;
_api.postMessageToExtApp('mycommand', line);

The following code exists in the extension application.

var _api = SimphonyExtensibilityAPI;
_api.Eventing.SubscribeToEvent('OpsPageControlAsyncEvent', OnOpsPageControlAsyncEvent);
 
function OnOpsPageControlAsyncEvent(sender, args)
{
    let line = `OpsPageControlAsyncEvent: args sent in: ${args.ToString()}`;
    console.log(line);
}

How do I send a message from the extension application to the Custom HTML Page Control?

The extension application can send an asynchronous message to the Custom HTML Page Control via OpsContext.

The following code exists in the extension application.

var _api = SimphonyExtensibilityAPI;
var _poscore = _api.Common.LoadPosCore();

function sendToPageControl()
{
    let parms = new _poscore.Micros.PosCore.Extensibility.UserInterface.PageControlAsyncMessageParameters();
    parms.ExtAppName = _api.Runtime.ApplicationName;
    parms.Key = "app1";
    parms.ID = null; // if null, all page controls with the specified key receive the message
    parms.Data = "data";
    _api.Environment.Context.SendAsyncPageControlMessage(parms);
}

The following code exists in the Custom HTML Page Control source.

var _api = SimphonyPOSAPI;

function onload() {
    SimphonyPOSAPI.setAsyncMessageCallback(asyncMessageCallback);
}

function asyncMessageCallback(msg) {
    switch (msg.Type) {
        case SimphonyPOSAPI_AsyncMessageType.Ready:
            // API is ready
            // msg is of type SimphonyPOSAPI_ReadyMessage
            break;
        case SimphonyPOSAPI_AsyncMessageType.OpsContextPropertyChanged:
            // a OpsContext property changed 
            // msg is of type SimphonyPOSAPI_OpsContextChangeMessage
            // you might want to check msg.Names[] array
            break;                
        case SimphonyPOSAPI_AsyncMessageType.ExtApp:
            // async message received from extension application
            // msg is of type SimphonyPOSAPI_ExtAppAsyncMessage
            // you might want to check msg.Data
            break;
    }
}

What state/transaction data is available via the API?

This is perhaps the key question concerning the design of your page control. Communications and rendering is rather straightforward. State management can be difficult. Points to remember:

  1. OPS state information available in the API are OpsContext atomic data properties. For example WorkstationNumber is available as it is an int. Any complex properties (check detail, check summary, open checks, open tables) are not available. The OpsContext state data is kept up to date and can be used to make local decisions such as “employee signed in” and “check total”. Accessing the workstation number property can be accomplished with SimphonyPOSAPI.OpsContext.WorkstationNumber. Changes in OpsContext can be detected in the Custom HTML Page Control async message callback.
  2. Due to OPS page architecture, every Custom HTML Page Control on the page has to be aware that it can be recycled at any time. This means that any persistent state data must be cached in the extension application code (JS/SIM/C#) and reconstructed when the Custom HTML Page Control is reinitialized.
  3. Custom HTML Page Control controls needing check information should send it asynchronously to the page control(s).

Why don’t I see the full JavaScript API available in the Page Control API?

Designing an API is difficult. There is a balance of providing functionality to the consumer versus the cost of building out and maintaining a complicated API.

Technically the Custom HTML Page Control API only needs methods for communicating with the extension application. All other functionality (e.g. logging) could be implemented by the ext app and not be part of the API.

There were some very common functions that were added to the Custom HTML Page Control API. It was decided to put them into the API, rather than every extensibility developer implementing them in each of their Custom HTML Page Control applications:

  1. logging to egateway log
  2. show an error on the POS
  3. show a message on the POS
  4. post an OpsCommand to the POS
  5. post an OpsCommand macro to the POS

The following functionality was deemed too complicated to implement in a general way for all extensibility applications:

  • OpsContext: check header and detail
  • OpsContext: open checks
  • OpsContext: open tables
  • Extensibility events (OpsSignInEvent, OpsMenuItemPreviewEvent)

For each of these, each extensibility writer can determine which subset of this functionality is required for their Custom HTML Page Control, and implement a customized solution.

One may be tempted to serialize all of OpsContext, check detail, or extensibility events to JSON and send them to the page control. These .Net objects are not serializable as-is. The extensibility application should create a Dictionary<> with the required elements from these objects and serialize the dictionary to JSON.