Unable to Set iFrame 'src' Dynamically from System Variable
09:00 Mar 06, 2025
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
1 comments
11:22 Mar 13, 2025
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