(Quick Reference)

6 Event Handling - Reference Documentation

Authors: groovyquan

Version: 0.5.1

6 Event Handling

6.1 Event Listening

Declare an Event Handler in gsp

An event handler can be declared in a gsp page by specifying an event attribute(An event attribute is an attribute starting with on). For example,

<z:button label="hi" onClick='alert("Hello")'/>
where the content of the event handler is the code snippet in Groovy. The event handler will be interpreted at the run time.

Important Builtin Variables

  • self - the component receiving the event. In the previous example, it is the button itself.
  • event - the event being received. In the previous example, it is an instance of MouseEvent.

Listen by Use of an Event Listener

An event listener is a class implementing EventListener. For example,

class MyListener implements EventListener {
    void onEvent(Event event) {
        Messages.show("Hello")
    }
}

Then, you can register an event listener to the component that might receive the event by use of Component.addEventListener(String, EventListener). For example,

button.addEventListener("onClick", new MyListener())

This is a typical approach to handle events. However, it is a bit tedious to register event listeners one-by-one if there are a lot of listeners. Rather, it is suggested to use the following method:

button.addEventListener("onClick"){Event event->
    Messages.show("Hello")
}

Composer and Event Listener Autowiring

With Auto-wired Component, you generally don't need to register event listeners manually. Rather, they could be registered automatically by use of the auto-wiring feature of a composer. For example

class MyComposer{
    void onClick_hi() {
        Messsagebox.show("Hello")
    }
    void onClick_bye() {
        Messsagebox.show("Bye")
    }
}

As shown above, the method to listen an event shall be named by starting with the event name, separating with _, and ending with the component's ID. The composer will search all matched methods and register the event listener automatically. Then, in the gsp page, you can specify the apply attribute to associate the composer with a component.

<z:window apply="MyComposer">
    <z:textbox/>
    <z:button id="hi"/>
    <z:button id="bye"/>
</z:window>

If the listener needs to access the event, just declare it as the argument:

void onClick_hi(MouseEvent event) {
  Messsagebox.show("Hello, " + event.getName())
}
Though not limited, a composer is usually associated with an ID space (such as Window) to handle events and component within the give ID space. You could associate any component that properly represents a scope of your application to manage. See more Auto-wired Component

Declare a Event Handler in zkui's Builder

see Event listening

6.2 Client-side Event Listening

ZK allows applications to handle events at both the server and client side. Handling events at the server side, as described in the previous sections, are more common, since the listeners can access the backend services directly. However, handling event at the client side improves the responsiveness. For example, it is better to be done with a client-side listener if you want to open the drop-down list when a comobox gains focus. A good rule of thumb is to use server-side listeners first since it is easier, and then improve the responsiveness of the critical part, if any, with the client-side listener.

Declare a Client-side Listener in gsp

Declaring a client-side listener in a gsp is similar to declaring a server-side listener, except
  • Use the client_ Prefix
  • It is JavaScript
  • Use this to reference to the target widget (while the event is referenced with event)
  • Use this.$f() to reference fellow widgets (Widget.$f())

For example,

<z:combobox client_onFocus="this.open()"/>

The Relationship between Client and Server-side Event Listener

It is allowed to register both the client and server-side event listeners. They will be both invoked. Of course, the client-side listener is called first, and then the server-side listener. For example,
<z:div>
  <z:combobox client_onFocus="this.open()" onFocus="self.parent.appendChild(new Label('focus'))"/>
</z:div>
If you want to stop the event propagation such that the server won't receive the event, you could invoke Event.stop(Map). For example, the server-side listener won't be invoked in the following example:
<z:div>
  <z:combobox client_onFocus="this.open(); event.stop();" onFocus="self.parent.appendChild(new Label('focus'))"/>
</z:div>

Declare a Client-side Listener in Groovy

The other way to declare a client-side listener at the server is Component.setWidgetListener(String, String). For example,
combobox.setWidgetListener("onFocus", "this.open()")
Notice that it is Groovy and running at the server.

Register a Client-side Listener in Client-Side JavaScript

Listening an event at the client could be done by calling Widget.listen(Map, int). For example,
<z:window>
    <z:bandbox id="bb"/>
    <z:script defer="true">
        this.$f().bb.listen({onFocus: function () {this.open();}});
    </z:script>
</z:window>
where
  • defer="true" is required such that the JavaScript code will be evaluated after all widgets are created successfully. Otherwise, it is not able to retreive the bandbox (bb).
  • script is a widget (unlike zscript), so this references to the script widget, rather than the parent.
  • Widget.$f(String) is equivalent to Component.getFellow(String), except it is a JavaScript method (accessible at the client).

Declare a Client-side Listener in zkui's Builder

see Client-side event listening