Introduction

HTML5 specification introduces new History API:

  • history object can use pushState() to push given data onto the session history and change the URL to a given one, if provided.
  • When history changes, browser will fire an onpopstate event to window.onpopstate.

History management with HTML5 History API in ZK introduces how developers can use this API in ZK with JavaScript code. In this article, I will go through how you can use this API using Java code. This is done by introducing a ZK add-on “ZKPushState”, a Java wrapper that allow developers to handle this feature in pure Java code which makes managing history more in a more ‘ZK’ way and simplifies the difficulty of encoding/decoding state.

How to Use?

The only thing you must do before start digging into the code is to download ZKPS.jar and put it in classpath so you can call PushState.push(Map, String, String) in Java and set onPopupState attribute on root element in ZUL.

Follow the example in the next section will make this more clear.

Example

Following Ashish’s example in History management with HTML5 History API in ZK which contains three textboxes and (filter)buttons. You could input some text in the textbox to search for the content you want and upon clicking the filter button, listbox will display filtered data based on the text entered in the textbox.

I will re-write his example using ZKPushState and MVVM, the ZUL code of the buttons would be as follows:

<button label="Filter" width="50px"
onClick='@command("filter", f1=filter1.value, f2=filter2.value, f3=filter3.value)' />

In the View Model, the command method writes:

@Command
@NotifyChange("*")
public void filter(@BindingParam("f1") String f1, @BindingParam("f2") String f2, @BindingParam("f3") String f3){
  doFilter(f1, f2, f3);
  Map<String, String> map = new HashMap<String, String>();
  map.put("f1", f1);
  map.put("f2", f2);
  map.put("f3", f3);
  PushState.push(map, "Search results", "?q="+f1+f2+f3);
}

The function of doFilter is to rebuild the model of listbox. At the end of filter(), I invoke PushState.push() which will execute history.pushState() on client side automatically. At this point in time, the URL will change and end users can go back to its previous state by clicking back on the browser and going back to the previous page.

This is what happens: after a few searches, browser will keep some states to bind with the give URL. When end users click the browser’s “back” button, ZKPushState will fire a PopupStateEvent, therefore, I need to add onPopupState on the ZUL root element like the following:

<window onPopupState='@command("popupState", event=event)'>

In the view model, the command method writes:

@Command
@NotifyChange("*")
public void popupState(@BindingParam("event") PopupStateEvent event){
  Map<String, ?> state = event.getState();
  doFilter(
    state.get("f1").toString(),
    state.get("f2").toString(),
    state.get("f3").toString()
  );
}

We can retrieve the state by event.getState() which will return a Map<String, ?> instance. To do this, we call doFilter with arguments returned by PopupStateEvent, listbox will thus show the same data as before (before the user exited this page previously).

You can download the complete source code for this example and ZKPushState from its github repository here.
Any feedback is welcome 🙂

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.

4 Responses to “ZKPushState: A ZK Addon to Handle HTML5 History API in Pure Java”

  1. ashiqmbs says:

    I download this source code and get a good output.

  2. LT Bangladesh Web Design says:

    code is now much cleaner and can easily define own data-handler

  3. hasan says:

    I can not resolve my problem.I used this code

  4. Bill says:

    What’s your problem?

Leave a Reply