/// <summary> /// Defines the design time experience for the VKIframe. /// </summary> [FormDesignControlAttribute('VKIframeControl')] [FormDesignValidContainerControlAttribute(classstr(FormTabPageControl))] [FormDesignValidContainerControlAttribute(classstr(FormGroupControl))] public class VKIframeBuildControl extends FormBuildControl { str url; str title; public void new(FormContainer _container) { super(_container); } [FormDesignProperty('URL', 'Behavior')] public str url(str _value = '') { if (!prmisdefault(_value)) { url = _value; } return url; } [FormDesignProperty('Title', 'Behavior')] public str title(str _value = '') { if (!prmisdefault(_value)) { title = _value; } return title; } }
/// <summary> /// VKIframe control /// </summary> [FormControlAttribute('VKIframeControl', '/resources/html/VKIframeHTML.html', classStr(VKIframeBuildControl))] public class VKIframeControl extends FormTemplateControl { private FormProperty Url; private FormProperty Title; public void new(FormBuildControl _build, FormRun _formRun) { super(_build, _formRun); this.setTemplateId(classStr(VKIframeControl)); this.setResourceBundleName('/Resources/HTML/VKIframeHTML.html'); Url = properties.addProperty(methodStr(VKIframeControl, url), Types::String); Title = properties.addProperty(methodStr(VKIframeControl, title), Types::String); } [FormPropertyAttribute(FormPropertyKind::BindableValue, identifierStr(Url), true)] public str url(str _url = Url.parmValue()) { if (!prmIsDefault(_url)) { Url.parmValue(_url); } return Url.parmValue(); } [FormPropertyAttribute(FormPropertyKind::BindableValue, identifierStr(Title), true)] public str title(str _title = Title.parmValue()) { if (!prmIsDefault(_title)) { Title.parmValue(_title); } return Title.parmValue(); } /// <summary> /// Applies the build configurations to the run instance of the control. /// </summary> /// <remarks> /// ApplyBuild of the form part control should be called only in formRun::Init() method. /// </remarks> public void applyBuild() { super(); var build = this.build() as VKIframeBuildControl; if (build) { this.url(build.url()); this.title(build.title()); } } [FormCommandAttribute(identifierstr(UpdatePaymentStatus), true)] public void updatePaymentStatus(str serializedJson) { // this method will be also available on the form control level info('updatePaymentStatus: ' + serializedJson); } }updatePaymentStatus method will also be available at the form control level:
<script src="/resources/scripts/VKIframeJS.js"></script> <div id="VKIframeControl" class="iframeControl fill-width" style="overflow:hidden" data-dyn-bind="sizing: { width: $dyn.layout.Size.available, height: $dyn.layout.Size.available }"> <iframe class="iframeControl-frame" style="border:0px; width:100%; height:100%" sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox" data-dyn-bind="title: $data.Title"></iframe> </div>
(function () { 'use strict'; Globalize.addCultureInfo('en', { messages: { IFrame_iFrameTitle: "Payment", } }); $dyn.controls.VKIframeControl = function (data, element) { $dyn.ui.Control.apply(this, arguments); if (data.Url) { var self = this; $dyn.bulkObserve({ url: data.Url }, function (changes) { self.onPropChanged(changes.url); }, self.Updating, self); } }; $dyn.controls.VKIframeControl.prototype = $dyn.extendPrototype($dyn.ui.Control.prototype, { Url: undefined, Title: undefined, init: function () { $dyn.ui.Control.prototype.init.apply(this, arguments); if (this.Title === undefined) { this.Title($dyn.label('IFrame_iFrameTitle')); } if (window.addEventListener) { window.addEventListener("message", this.applyContext(this.onMessageReceive, this), false); } else if (window.attachEvent) { window.attachEvent("onmessage", this.applyContext(this.onMessageReceive, this), false); } }, onPropChanged: function (urlChanged) { var webHostIframe = this.getIFrameElement(); if (urlChanged && webHostIframe) { webHostIframe.setAttribute('src', this.Url()); } }, getIFrameElement: function () { var webHostIframe = undefined; var iframes = this.element.getElementsByTagName('iframe'); if (iframes && iframes.length) { webHostIframe = iframes[0]; //There is only one iframe in webHost control } return webHostIframe; }, applyContext: function (Func, Context) { return function () { return Func.apply(Context, arguments); } }, onMessageReceive: function (event, ui) { var data = event.data; if ($dyn.callFunction) { $dyn.callFunction(this.UpdatePaymentStatus, this, [data], function () { /* executes on success */ }); } } }); })();Resources:
<html> <body> <script> function clickMe() { console.log('iFrame: clickMe'); window.parent.postMessage({ 'code': 'transIdent', 'paymentStatus': 'Paid', 'amount': 10.56, 'description': 'SO-000405', 'currency': 'GBP' }, "*"); } </script> <a href="javascript: clickMe();">click me</a> </body> </html>
DaxOnline.org is free platform that allows you to quickly store and reuse snippets, notes, articles related to Dynamics AX.
Authors are allowed to set their own AdSense units and "buy me a coffee" link.
Join us.