org-scn-design-studio-community / sdkpackage

SDK Package of SCN Design Studio Community
Apache License 2.0
32 stars 29 forks source link

How to prevent EmbeddedFrame from refreshing when event outside of the frame is fired #148

Closed ephraimrosenfeld closed 7 years ago

ephraimrosenfeld commented 7 years ago

When creating a simple Design Studio application with an EmbeddedFrame component I am noticing that if an event is fired in the parent application, outside of the EmbeddedFrame, it causes an asynchronous call to the server which in turn refreshed the EmbeddedFrame.

This behavior is disruptive as it causes the embedded content to refresh. Moreover, our intention is to use the EmbeddedFrame to create modular Design Studio applications that can be embedded inside of each other. However, this issue compromises the usability of the EmbeddedFrame component.

Please see the attached screenshot and the exported test Design Studio analysis .zip file for more reference. I have created a simple application (no data-sources) with three components: 1) a button, 2) a text-label, 3) an EmbeddedFrame. The button toggles the visibility of a text-field in its 'OnClick' event. However, when clicking on the button, the content of the EmbeddedFrame reloads.

We are using Design Studio 1.6 (SAP BusinessObjects Design Studio; 16.2.2; com.sap.ip.bi.zen.product.platform) and the latest SDK components ( SCN Community Free Extensions for Design Studio; 3.0.0.201610191048; org.scn.community.sdk.feature.main.feature.group; SCN Community Contributors)

Thank you in advance.

testembeddedframerefreshlabels

TestEmbeddedFrameRefresh-20161206095247.zip

MartinPankraz commented 7 years ago

Hi Ephraim,

I checked your issue and found a feasible implementation for it. Only drawback is that embedding the embedded frame into a pagebook for example still requires a reload of the component. I will upload the new version today to our preview branch. I will leave a note once you can test.

Kind regards Martin

MartinPankraz commented 7 years ago

Hi Ephraim,

The new version is online and can be updated via our preview update link on Design Studio as usual https://github.com/org-scn-design-studio-community/sdkinstall/blob/master/releases/preview/org.scn.community.sdk.package_preview.zip?raw=true

Leave a note if the update works for you.

Kind regards Martin

ephraimrosenfeld commented 7 years ago

Hello Martin,

I downloaded the .zip following this link (the attribute, 'raw=true', gave me a 404 error, so I removed it): https://github.com/org-scn-design-studio-community/sdkinstall/blob/master/releases/preview/org.scn.community.sdk.package_preview.zip

I found that the behavior of the EmbeddedFrame component was the same.

Is this the right place to obtain the sdk components? It shows that the last commit to the Preview branch (https://github.com/org-scn-design-studio-community/sdkinstall/tree/master/releases/preview) was two months ago (Oct. 19). I believe I have downloaded the same version of the sdk components in which I originally observed the issue of the EmbeddedFrame component reloading.

Please advise.

Thank you,

Ephraim

MartinPankraz commented 7 years ago

Hi Ephraim,

You cannot download from my link. You need to paste that into the install text field on Design Studio directly.

Kind regards Martin

ephraimrosenfeld commented 7 years ago

Hello Martin:

I was able to get the latest changes by pasting the following URL in: http://org-scn-design-studio-community.github.io/sdkinstall/releases/preview I was able to verify this by the version of the SDK component (the version of the SDK component contains today's time-stamp, December, 15th).

This change fixed the issue in the original example I provided, where the EmbeddedFrame uses a static URL of a webpage. However, when I use a dynamic URL for the EmbeddedFrame, the frame becomes invisible as a result of an event outside of the frame.

I have attached a .zip file containing an .lcmbiar file (no data-source is necessary): OutstandingIssueWEmbeddedFrame.zip. The .lcmbiar contains the following three applications:

The outstanding issue I am noticing is that, when clicking on the toggle-visibility button in the outer-application, which should not affect the EmbeddedFrame or its URL, the frame becomes invisible until the 'Update' button is pressed again: testembeddedframebuttonmakesframeinvisible

I have tested this behavior in Chrome and IE and it occurs in both environments.

As mentioned originally, our ideal goal is to have a hierarchy of DS applications that will allow us to reuse content in a modular fashion. We would want to dynamically reset the URL of the EmbeddedFrame based upon some event, but only when that event fires.

Regards,

MartinPankraz commented 7 years ago

Hi Ephraim,

Did you upload the new SDK extension to your BO server too? The behavior you describe works during my local tests. Please don't provide bo packaged projects, only Design Studio exports.

Be aware that calling the scripting method setUrl will automatically trigger a load on the iframe.

Does that help?

Kind regards Martin

ephraimrosenfeld commented 7 years ago

Hello Martin:

Attached are the exported Design Studio applications:

These are the versions of the applications we are using:

To reiterate, what I've found is that, when using the EmbeddedFrame component to embed a static URL, the component works as desired; however, in my "TestOuterApplication" application I found that when clicking on a button to update the visibility of a component other than the EmbeddedFrame, the frame becomes invisible - and it is only after reloading its URL that it becomes visible again.

Again, thank you for your time and efforts,

Ephraim

MartinPankraz commented 7 years ago

Hi Ephraim,

I checked the behavior. The problem is with the Design Studio Scripting method setVisible. It causes a lifecycle restart of all SDK components of a Design Studio dashboard. There a certain application hooks in a SDK component (init, beforeUpdate, afterUpdate, componentDeleted) which can be coded against. In your example the init meethod is triggered again although you just clicked a button. In addition to that the html element gets invalidated so actually a rerun of the cycle is necessary to see the SDK component again.

I am not sure if this is a bug in the Design Studio SDK framework. @entmike & @KarolKalisz any idea?

A possible workaround for you would be to avoid the method setVisible and use css classes for example with visibility:hidden or visibility:visible. I tested that successfully with your example dashboard.

But please note that calling setUrl or triggerUpdate will always reload the iframe. You cannot alter parts of it once loaded. That is the nature of the iframe.

Let me know what you think.

Kind regards Martin

entmike commented 7 years ago

Martin,

You are correct that the visibility property will destroy and recreate a component upon state change. I had a similar issue with a different component where I wished that when the component was hidden, that it not be destroyed. I ended up creating a separate SDK property called 'Show' or something similar, and basically when 'Show' was true (by default) it applied a CSS rule something like display: block to the component, and when 'Show' was false, it applied display: none, which is basically what you are suggesting as well.

Since the default 'Visible' property is not controllable via SDK, the best we could do is offer a a separate 'Show', 'Hidden', or 'Whatever' alternate property to make the CSS toggling a bit easier, however as an immediate workaround, this should be doable already by setting CSS Style classes as you have suggested.

ephraimrosenfeld commented 7 years ago

Hello Martin & Mike:

Thank you for the detailed explanation.

In addition to setVisible(), are there other methods that could cause a life-cycle restart of the SDK components?

Not to bother you, but do you anticipate a fix for this issue in a new patch or release-version?

Best Regards,

Ephraim

MartinPankraz commented 7 years ago

Hi Ephraim,

Since we are not working for SAP it is not up to us to fix this. Feel free to open an idea in SAP's idea place or report an SAP incident if you feel that this is a problem worth checking.

Thanks for your input @entmike

Kind regards Martin

entmike commented 7 years ago

Anything that causes a redraw of the IFRAME tag will reset the state of the IFRAME document. This includes but would not be limited to, changing the Visibility Property, but also any possible containers that the IFRAME may be a child of, such as a Panel container that causes state changes to its child components, such as in the event of the Panel container's Visibility being changed. Related, yet possibly surprising, is that even the Tab Panel component will do this say component destroy/recreation behavior simply by clicking from Tab 1 to Tab 2. So imagine an IFRAME being in Tab 1, you navigate in the IFRAME, then click Tab 2, and come back to Tab 1, that will cause an IFRAME redraw, I'm afraid.

I've toyed with the prospect of even "stashing" the IFRAME outside of the SDK Component DOM container so that the IFRAME is preserved, however while this is possible to preserve the "life" of the IFRAME, unfortunately any time an IFRAME is moved in the browser DOM to a new parent element, it ALSO loses its state, which defeats the whole point.

Moreover, I've never liked the IFRAME components myself for these reliability reasons, even though I've created some of them myself (like the Modal Popover one, for example.) I think it's an OK use for brief "in-application help" use cases that make use of an IFRAME for quick reference documentation/help, but I'd never rely on it for keeping track of page interactions, navigations, or web application embedding, it's just inviting usability issues such as these we are discussing, which is why I've avoided jumping into all these IFRAME discussions for the most part :)

I do wish you luck though! I think your best partial resolution for this visibility matter would be to apply CSS and one of us might get around to giving you a convenience property in the future but it's not going to do anything CSS couldn't do for you now.