Question
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
FrameComponentdoes not update the src dynamically.
What I Tried
- Checking if
SmartenIFrameSrcupdates 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