Search code examples
javascriptjavazkzul

Connection between Java and Javascript through ZK framework


I have been facing an issue with the communication between java and javascript through zk framework in a iframe. In simple words, I want to save a string in the current session and access it (or even overwrite it) in javascript.

my java lines:

HttpSession session = (HttpSession)(Executions.getCurrent()).getDesktop().getSession().getNativeSession();
session.setAttribute("key","testing");

my zul lines:

<iframe id = "change_option" src="select_one_option.html" scrolling="no" width="700px" height="400px" > </iframe>

my javascript lines in the html file:

var session= /SESS\w*ID=([^;]+)/i.test(document.cookie) ? RegExp.$1 : false;  //finds the correct session id + desktop name?
session = session.substring(0, session.indexOf('.')); //removes desktop name and keeps just the session id in a string 

//another try
console.log("Saved: " + sessionStorage.getItem("key")); //returns "Saved: null" 

//another try 
var username = '<%= Session["key"] =%>'
console.log ( " Variable is : " + username) //returns  "<%= Session["key"] %"

Since the html file is big I thought it would be better to do it through iframe and not try to rewrite inside the zul file. Any suggestion is highly appreciated.


Solution

  • There are a few approaches you can consider depending on your full requirement.

    #1 The page located inside of the iframe and the outer page may communicate directly, using the window postMessage API: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

    This require a bit of setting up, but allows the page located in the iframe to post an event to the parent page. The event has a data field, which you can use to transfer data. The parent page can subscribe to such event, and read the event data.

    With this method, you don't actually need to write stuff to the session at server-side, since this communication happen fully at client-side. This is good if the server doesn't care about knowing the value.

    #2 saving the object in session from the inner page, using it from the outer page You are already setting the session attribute in the native session:

    HttpSession session = (HttpSession)(Executions.getCurrent()).getDesktop().getSession().getNativeSession();
    session.setAttribute("key","testing");
    

    Note that session attributes are Java-side only. They are not automatically returned to the client as cookies. You can add a cookie with the same value to your response, if you want to handle this by cookies: https://www.zkoss.org/wiki/ZK_Developer%27s_Reference/UI_Patterns/Communication/Inter-Application_Communication#Use_Cookie

    However, this is a bit overkill because ZK is a communication framework and you can already pass the value to the outer zul page in a number of ways.

    First, you can just execute arbitrary JS on the page using the Clients#evalJavascript method.

    https://www.zkoss.org/wiki/ZK_Developer's_Reference/UI_Patterns/Useful_Java_Utilities#evalJavaScript

    With that, you can just build a JS call containing your value retrieved at server side, and execute it in client. Should look like this:

    String myValue = ... //retrieve your server-side value;
    Clients.evalJavascript("myClientSideFunction('"+myValue+"')"); //executed in an execution of the zul page.
    

    But you can also use that value as a client-attribute, pass it as a component value, etc.

    There are a lot of arbitrary things you can do to pass that value back to the client, all with pros and cons. For example, if you want to put that value back into a textbox, you can simply use the textbox#setValue method. It really depends on what you are looking to achieve.