3.5.8Custom HTML dialogs

You can get the framework to display a completely custom dialog consisting of your own HTML. This mechanism is very flexible, because you can do bi-directional communication between your widget/script and the dialog while it is open, but it is complicated. It involves you having to assemble a string containing HTML and Javascript inside your code (unless you use a web page hosted externally). In a widget, but not a script or UDIX, it may be simpler to have the widget act as its own dialog.

You create an HTML dialog using Framework.CreateHtmlDialog(). This has some fundamental ground rules:

You can send messages from your widget/script/UDIX to the dialog.

The dialog can send messages to your widget/script/UDIX.

The dialog has no access to the framework. You can send messages to the dialog containing framework data, and the dialog can send you messages asking your widget/script/UDIX to carry out framework actions. But the dialog itself cannot access the framework.

The dialog cannot close itself. It needs to send a message to your widget/script/UDIX, and your widget/script/UDIX then uses Framework.DestroyDialog() to close the dialog.

As an example, take the following widget/script/UDIX code which builds a string containing an HTML document, including a <script> block. This will the HTML of our dialog:

var html = "<html><head>";

html += "<script>";

html += "function SendUpdateToParent(txt) {window.parent.postMessage(txt, '*');};"

html += "window.addEventListener('message', function(event) {";

html += "document.getElementById('lblEquity').innerText = event.data;";

html += "});"

html += "</script>";

html += "</head><body>";

html += "<p>Equity: <span id='lblEquity'>...</span></p>"

html += "<p><button onclick='SendUpdateToParent(\"close-me\");'>Close</button></p>";

html += "</body></html>";

Various things are happening here:

The <script> in the HTML defines a SendUpdateToParent() function. This sends messages from the dialog to your widget/script/UDIX, using the standard browser window.parent.postMessage().

There is a button in the page which uses SendUpdateToParent() to send the message "close-me" to your widget/script/UDIX.

The Javascript in the HTML sets up a listener on window.message. This receives updates from your widget/script/UDIX. In this basic example, the handler simply dumps the content of a message into the <span id="lblEquity"> in the page. In a more sophisticated example you might send a message to the HTML by building some JSON and doing JSON.stringify() on it, and the dialog might parse it with JSON.parse(event.data) and then inspect the contents.

You can then create such a dialog as follows:

Framework.CreateHtmlDialog({

title: "My dialog",

html: html

}, function(Msg) {

if (Msg.result) {

// Dialog has been closed/cancelled. Remove the timer which we set up earlier.

clearInterval(Framework.$myTimer);

} else if (Msg.update) {

// Some kind of message from the dialog, via window.parent.postMessage()

if (Msg.update == "close-me") {

// Dialog is asking to be closed

Framework.DestroyDialog(Msg.widgetId);

} else {

// Some other message

}

} else {

// If not a result and not an update, then this is the initial message

// giving us the dialog's ID (in Msg.widgetId).

// As a simple example, we will send the dialog the current account equity

// once per second.

setInterval(function() {

Framework.$myTimer = Framework.SendHtmlDialogUpdate(Msg.widgetId, Framework.Account.equity);

}, 1000);

}

});

Again, a number of things are happening in this widget/script/UDIX code:

The asynchronous callback handler from CreateHtmlDialog() can receive a number of types of message.

If the Msg parameter contains a result, then the dialog has been closed/cancelled.

If the Msg contains an update, then it is a message from the dialog Javascript, issued using window.parent.postMessage() as illustrated above. The example code inspects the text of the message from the dialog. If the dialog is saying "close-me", then the code closes the dialog using DestroyDialog().

If the Msg contains neither an update nor a result, then it is the initial creation message about the dialog. What the code does in this example is to set up a timer which, every second, sends the dialog the current value of account equity using Framework. SendHtmlDialogUpdate(). The dialog receives this in its window.message handler, and puts the value into the <span id="lblEquity"> as described above.

All this is obviously not a very realistic example in itself. But exactly the same principles used here can be extended to create very feature-rich dialogs, all ultimately based on the same message-exchange demonstrated above.

Finally, in addition to the title and html properties used above, there are further settings which you can supply when creating the dialog:

Property

Description

url

If you supply a url, that remote address is loaded into the dialog (instead of an HTML string). Allows you to host the content for a dialog on an external server rather than building it inside your widget/script/UDIX. Like all other resources, such a page must be hosted at an https:// address.

noTitle

If noTitle:true is set then the dialog is not given a title bar. Your HTML/url content takes up the whole dialog window.

noStandardCss

By default the framework will insert its own CSS into your HTML (not applicable if you use a url), in order to make the styling consistent with the rest of MyTrader. You can prevent this using noStandardCss:true.

buttons

You can optionally give the dialog standard buttons, in a footer, in exactly the same way as for dialogs such as Ask(). These buttons will close your dialog in the usual way, sending back a Msg.result containing the value of the clicked button.