Question

I have an appliction with a modal called loginModal which contains an iframe

<window id="loginModal" title="Login" border="normal" position="center,top" closable="true" width="500px" height="350px" >
    <iframe src="/usermenu.zul"  id="iframeLogin" scrolling="false" width="100%" height="100%"/>
</window>

The iframe calls a page usermenu. In certain cases the usermenu may redirect to a verification page whose contents are larger than the modal. I would like to find a way that when doing the redirect I can resize the modal to make it bigger automatically.

Please note that the getParent returns null and doesn't return the modal object to me.

I tried to send a message to the loginModal when reaching the verification page. The message is received but I cannot resize the modal through javascript.

In the verification page

<script type="text/javascript">
window.parent.postMessage('verification','*');
</script>

In the loginModal

<script type="text/javascript">
window.addEventListener('message', receiveMessage, false);

function receiveMessage(evt) {

    if (evt.data == 'verification') {
        loginModal.height = 500;
    }
}
</script>

I have tried a few variations to set the height but none of them works. I know that the message is reaching the loginModal because I can send an alert. Any help would be appreciated. Thank you

Was it helpful?

Solution 2

What ZK does is that it loads your loginModal page in one desktop and your iframeLogin page in another desktop. The notion of a desktop is further clarified here.

Thus, loginModal is not the parent browser window of iframeLogin. This is why getParent returns null when you invoke it on your iframe.

As stated in ZK Component Reference, one may not access components attached to other desktops. In other words, the information exchange between loginModal and iframeLogin is disabled.

It seems that you have one of two options:

  1. Do without an iframe and use include instead.
  2. Use an iframe but define an Event Queue under the group scope. Make this event queue visible to both loginModal and iframeLogin, and use it to exchange information between the two desktops you have.

EDIT 1

Please ensure that:

  1. the client-side namespace is incorporated by inserting xmlns:w="http://www.zkoss.org/2005/zk/client" into your window tag.
  2. your JS code is evaluated after creating all the widgets by inserting defer="true" into your script tag.

In your second JS snippet, this references the script widget itself. Your window and script co-exist in the same ID space. In other words, your window and script are fellows.

Therefore, to reference your window from your script, please use any of the following:

this.$f('loginModal').setHeight("500px");
this.$f().loginModal.setHeight("500px");
zk.Widget.$(jq('$loginModal')[0]).setHeight("500px");

Instead of:

loginModal.height = 500;

EDIT 2

To further exemplify, the following JS script would double the initial height of loginModal:

<window id="loginModal" title="Login" border="normal" width="500px" height="350px" xmlns:w="http://www.zkoss.org/2005/zk/client">
    <script defer="true">
        this.$f('loginModal').setHeight("700px");
    </script>
</window>

OTHER TIPS

You don't need the iframe as you mention in the comment of Sari awnser. Just add a Composer to your modal window

<window id="loginModal" ...  apply="mypkg.MyComposer">

and "fake" the redirect logic here.

class MyComposer extends SelectorComposer {

@Wire
Window loginModal;

public void doAfterCompose(Component comp){
    super.doAfterCompose(comp);
    if(checkConditionForVerificationPage){
      Executions.createComponents("/verification.zul", loginModal, null);
    } else {
      Executions.createComponents("/usermenu.zul", loginModal, null);
    }
}
}

My experience showed me, that it is better to avoid real redirects in zk.
Not very surprising, cos zk is ajax :)
And if you want to remove the verification page and add the usermenu after verification call

Events.sendEvent("onVerify", loginModal, mydata);

in a Composer of the verification page after success and add to the composer above

@Listen("onVerify = #loginModal")
  public void handelVerification(Event e) {
  loginModal.removeChild(loginModal.query("#idOfTopComponentFromVerificationPage"));
  Executions.createComponents("/usermenu.zul", loginModal, null);
}

And of course you can set the height and width of the loginModal

loginModal.setWidth("100px");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top