Embedding an IFRAME on a Creatio Freedom UI Page

In a previous article I outlined how to embed an IFRAME on a Classic Creatio page. This article will outline how to do this for a Freedom UI page. We’ll accomplish this by creating a simple Freedom UI component, and then adding the component to the page. We’ll be able to use a static URL for the IFRAME source or bind the source to a property on the page. The end result will be as follows:

Creating a Simple Freedom UI IFRAME Component

Our first step is to create a simple Freedom UI component that will create the IFRAME. To create this, add a Module and paste in the following code:

// jshint esversion: 11
define("UsrFrameComponent", ["@creatio-devkit/common"], function (sdk) {
	class UsrFrameComponent extends HTMLElement {
		constructor() {
			super();
			this._dom = this.attachShadow({mode: 'open'});
		}
		
		get src() {
			return this._frameConfig.src;
		}
		
		set src(value) {
			this.frameConfig = {src: value};
		}
		
		get frameConfig() {
			return this._frameConfig;
		}

		set frameConfig(value) {
			this._frameConfig = value;
			
			this._frameConfig.src = this.frameConfig.src || "about:blank";
			this._frameConfig.height = this.frameConfig.height || "100%";
			this._frameConfig.width = this.frameConfig.width || "100%";
			
			this._frameConfig.style += "height:" + this.frameConfig.height + ";width:" + this.frameConfig.width + ";";
			if (!this.frameConfig.border) {
				this._frameConfig.style += "border:none;";
			}
			
			if (!this._frameConfig.sandbox) {
				this._frameConfig.sandbox = "allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox";
			}
			
			this._loadFrame();
		}
		
		_loadFrame() {
			let frame = '<iframe src="' + this._frameConfig.src + '" style="' + this._frameConfig.style + '" sandbox="' + this._frameConfig.sandbox + '" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade">';
			this._dom.innerHTML = frame;
		}
	}
	
	customElements.define("usr-frame-component", UsrFrameComponent);
	sdk.registerViewElement({
        type: "usr.FrameComponent",
        selector: "usr-frame-component",
		inputs: {
			frameConfig: {},
			src: {}
		}
	});
	
	return UsrFrameComponent;
});

This component will take a src URL and create an IFRAME with 100% width and height (there’s other options, I’ll discuss those later). The component is called usr.FrameComponent, which is what we’ll use to add it to the page.

Adding the IFRAME Component to the Page

The next step is to add the IFRAME component to the page. To do this, we need to add a reference to the module we created in the top of the page code.

define("UsrMyPage_FormPage", /**SCHEMA_DEPS*/["UsrFrameComponent"]/**SCHEMA_DEPS*/, function/**SCHEMA_ARGS*/()/**SCHEMA_ARGS*/ 

Now, we need to add the element to the page. If you’d like you can drag a label where you want to put the IFRAME and then edit the source code to modify it from a label to a usr.FrameComponent. The element in the page code, with the changes so it is a IFRAME, would look like this:

{
	"operation": "insert",
	"name": "FrameComponent",
	"values": {
		"layoutConfig": {
			"column": 1,
			"row": 1,
			"colSpan": 1,
			"rowSpan": 20
		},
		"type": "usr.FrameComponent",
		"src": "https://customerfx.com"
	},
	"parentName": "GridContainer_xvfw2eb",
	"propertyName": "items",
	"index": 0
}

The important part here are the following:

  • type = “usr.FrameComponent”
  • src = some URL

Additionally, I’ve set it to span 20 rows. As I mentioned, the component will fill 100% height and 100% width of the container it is in, so this will allow for a better height of the frame. At this point, that is all that is needed and the result is the image at the beginning of this article.

Binding the URL of the IFRAME to a Value

Instead of using a static URL for the IFRAME, we can also bind it to a value. For example, if we have a Website field on the page, we could display that website in the frame. To do this, we’d simply bind the src to the columns attribute in the viewModelConfigDiff (using a $ to indicate we’re binding to that attribute), like this:

{
	"operation": "insert",
	"name": "FrameComponent",
	"values": {
		"layoutConfig": {
			"column": 1,
			"row": 1,
			"colSpan": 1,
			"rowSpan": 20
		},
		"type": "usr.FrameComponent",
		"src": "$PDS_UsrWebsite_4644qhj"
	},
	"parentName": "GridContainer_xvfw2eb",
	"propertyName": "items",
	"index": 0
}

The result would be the following:

Just keep in mind that for this scenario the change event fires for each keystroke so you’ll see some flicker as the user types the URL. Or we could create our own attribute an form a URL to the lat/long of an address on Google maps:

We can also have multiple IFRAMEs on the same page:

A nice part is that once we’ve added it to the viewModelConfigDiff we can drag it around and resize it in the designer as well:

Other Options

I mentioned there’s a few other options for the component in this article. Rather than include a src property, you can use a frameConfig property and include the properties listed below:

{
	"operation": "insert",
	"name": "FrameComponent",
	"values": {
		"layoutConfig": {
			"column": 1,
			"row": 1,
			"colSpan": 1,
			"rowSpan": 20
		},
		"type": "usr.FrameComponent",
		"frameConfig": {
			"src": "https://customerfx.com",
			"style": "border: 1px solid red;",
  			"height": "200px",
			"width": "300px",
			"border": true,
			"sandbox": "allow-popups allow-popups-to-escape-sandbox"
		}
	},
	"parentName": "GridContainer_xvfw2eb",
	"propertyName": "items",
	"index": 0
}

Keep in mind, not all website allow themselves to be embedded in an IFRAME. Many websites have a HTTP header for X-Frame-Options, which is a header used to indicate if a browser should be allowed to embed a webpage. If set to “sameorigin” it means the website only allows embedding in a frame on its own website. ¬†Something to keep in mind with embedding websites in an IFRAME.

Want content like this delivered to your inbox? Sign up for our newsletter!
ABOUT THE AUTHOR

Ryan Farley

Ryan Farley is the Director of Development for Customer FX and creator of slxdeveloper.com. He's been blogging regularly about SalesLogix, now Infor CRM, since 2001 and believes in sharing with the community. His new passion for CRM is Creatio, formerly bpm'online. He loves C#, Javascript, web development, open source, and Linux. He also loves his hobby as an amateur filmmaker.

Submit a Comment

Your email address will not be published. Required fields are marked *