Unable to Set iFrame 'src' Dynamically from System Variable

Hi Creatio Community,
 

I’m trying to set the src of an iFrame dynamically using a system variable (SysSettings). While I can successfully retrieve the URL, I’m unable to bind it to the src property of usr.FrameComponent.

My Approach

I fetch the system setting using SysSettingsService.getByCode() inside crt.HandleViewModelResumeRequest:

 

handlers: /**SCHEMA_HANDLERS*/[
{
                request: "crt.HandleViewModelResumeRequest",
                handler: async (request, next) => {
                    await next?.handle(request);
 
                    try {
                        /* Ensure SysSettingsService is correctly initialized */
                        const sysSettingsService = new common.SysSettingsService();
                        var defaultSrc = await sysSettingsService.getByCode("SmartenIFrameSrc");
                        console.log("Src URL:", defaultSrc.value);
                      /* Set the fetched value into the ViewModel */
                        request.$context.SmartenIFrameSrc.value = defaultSrc;
                    } catch (error) {
                        console.error("Error retrieving SysSettings:", error);
                    }
 
                    return next?.handle(request);
                },
            },
] /**SCHEMA_HANDLERS*/

 

Then, I try binding it in the UI:

 

viewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
...,
            {
        "operation": "insert",
        "name": "UsrSmartenIFrameSrc",
        "values": {
            /* The property that handles the text contained in the element. Bound to the "SmartenIFrameSrc" attribute. */
          "type": "crt.Label",
            "caption": "$SmartenIFrameSrc",
        },
    },
    {
				"operation": "insert",
				"name": "Label_mmxxxre",
				"values": {
					"layoutConfig": {
						"column": 1,
						"row": 1,
						"colSpan": 1,
						"rowSpan": 18
					},
					"type": "usr.FrameComponent",
					"src": "$SmartenIFrameSrc" ,
                  // "src": "$defaultSrc" ,
 
				},
				"parentName": "GridContainer_Sales",
				"propertyName": "items",
				"index": 0
			},
			...
    ]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/,
 
viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[
    ...
           {
                "operation": "merge",
                "path": ["attributes"],
                "values": {
                    "SmartenIFrameSrc": { "value": "" }  // Initialize with an empty value
                }
            },
            ...
            ]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/,

 

Issue

  • The URL logs correctly in the console.
  • But the FrameComponent does not update the src dynamically.

What I Tried

  • Checking if SmartenIFrameSrc updates in the ViewModel (it does).
  • Using different binding methods like $context.SmartenIFrameSrc.
  • Setting a default static URL (which works, proving the issue is with dynamic binding).

Has anyone faced this issue before? How can I properly bind a system setting value to the src property of usr.FrameComponent?
 

Thanks in advance!

 

 

Like 0

Like

1 comments

I implemented this case on my side and it's working well. Here is the sample of the code that works for me:
 

handlers: /**SCHEMA_HANDLERS*/[
            {
                request: "crt.HandleViewModelResumeRequest",
                handler: async (request, next) => {
                    await next?.handle(request);
                    const sysSettingsService = new sdk.SysSettingsService();
                    const defaultSrc = await sysSettingsService.getByCode('SmartenIFrameSrc');
                    request.$context.SmartenIFrameSrc = defaultSrc.value;
        }
    }
        ]/**SCHEMA_HANDLERS*/

 

 

viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[
...
            {
                "operation": "merge",
                "path": ["attributes"],
                "values": {
                    "SmartenIFrameSrc": { "value": "" }
                }
            }
        ]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/


 

viewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
...
            {
                "operation": "insert",
                "name": "FrameComponent",
                "values": {
                    "type": "usr.FrameComponent",
                    "src": "$SmartenIFrameSrc",
                    "caption": "#ResourceString(Label_xifuwmy_caption)#",
                    "labelType": "headline-1",
                    "labelThickness": "default",
                    "labelEllipsis": false,
                    "labelColor": "auto",
                    "labelBackgroundColor": "transparent",
                    "labelTextAlign": "start"
                },
                "parentName": "GeneralInfoTab",
                "propertyName": "items",
                "index": 5
            }
        ]/**SCHEMA_VIEW_CONFIG_DIFF*/



The implementation of IFrame component:
 

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) {
            console.log('IFrame scr: ' + 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;
});
Show all comments