Event Forwarding"

From Documentation
m (replace tt with code (via JWB))
(33 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{ZKComponentReferencePageHeader}}
+
{{ZKDevelopersReferencePageHeader}}
 
= Overview =
 
= Overview =
  
For easy programming, ZK does not introduce any complex event flow. When an event is sent to a target component, only the event listeners registered for the target component will be called. It is the application's job to forward an event to another component if required (by the application).
+
For easy programming, ZK does not introduce any complex event flow. When an event is sent to a target component, only the event listeners registered for the target component will be called. It is the application's job to forward an event to another component if necessary.
  
For example, you might have a menu item and a button to trigger the same action, say, opening a dialog, and then it is more convenient to have a single listener to open the dialog, and register the listener to the main window rather than register to both the menu item and the button.
+
For example, you might have a menu item and a button to trigger the same action, say, opening a dialog, and then it is more convenient to have a single listener to open the dialog, and register the listener to the main window rather than register to both the menu item and button.
  
 
= Event Forwarding in Java =
 
= Event Forwarding in Java =
  
Forwarding an event is straightforward: just post or send the event again. However, there is a better way: composer. The composer can be the central place to handle the events. For example,
+
Forwarding an event is straightforward: just posting or sending the event again. However, there is a better way: [[ZK Developer's Reference/MVC/Controller/Composer|composer]]. The composer can be the central place to handle the events. For example, you could invoke <code>openDialog</code> in the event handler for the menu item and button as shown below:
  
 
<source lang="java">
 
<source lang="java">
public class FooComposer extends GenericForwardComposer {
+
public class FooComposer extends SelectorComposer {
   public void onClick$menuitem() {
+
   @Listen("onClick = menuitem#item1; onClick = button#btn")
    openDialog();
 
  }
 
  public void onClick$button() {
 
    openDialog();
 
  }
 
 
   private void openDialog() {
 
   private void openDialog() {
 
     //whatever you want
 
     //whatever you want
Line 24: Line 19:
 
</source>
 
</source>
  
= Event Forwarding in ZUL =
+
= Event Forwarding in ZUML =
  
Event forwarding can be done with the forward attribute in ZUL. For example,
+
Event forwarding can be done with [[ZUML Reference/ZUML/Attributes/forward|the forward attribute]] in ZUML. For example,
  
 
<source lang="xml">
 
<source lang="xml">
<window>
+
<window id="mywin">
 
<button label="Save" forward="onSave"/>
 
<button label="Save" forward="onSave"/>
 
<button label="Cancel" forward="onCancel"/>
 
<button label="Cancel" forward="onCancel"/>
Line 35: Line 30:
 
</source>
 
</source>
  
Then, <tt>window</tt> will receive the <tt>onSave</tt> event when the Save button is clicked.
+
Then, <code>window</code> will receive the <code>onSave</code> event when the Save button is clicked.
  
With this approach we could introduce an abstract layer between the event and the component. For example, <tt>window</tt> needs only to handle the <tt>onSave</tt> event without knowing which component causes it. Therefore, you could introduce another UI to trigger onSave without modifying the event listener. For example,
+
With this approach we could introduce an abstract layer between the event and the component. For example, <code>window</code> needs only to handle the <code>onSave</code> event without knowing which component causes it. Therefore, you could introduce another UI to trigger onSave without modifying the event listener. For example,
  
 
<source lang="xml">
 
<source lang="xml">
Line 43: Line 38:
 
</source>
 
</source>
  
Of course, you can use the composer and ZUL's forward together to have more maintainable code.
+
Of course, you can use the composer and ZUML's forward together to have more maintainable code.
 +
 
 +
<syntaxhighlight lang="java" line>
 +
public class BetterComposer
 +
extends org.zkoss.zk.ui.select.SelectorComposer {
 +
    @Listen("onSave = #mywin")
 +
    public void doSave(ForwardEvent event) { //signature if you care about event
 +
        ...
 +
    }
 +
    @Listen("onCancel = #mywin")
 +
    public void doCancel() { //signature if you don't care the event
 +
        ...
 +
</syntaxhighlight>
 +
 
 +
Notice that, as shown above, the event being forwarded is wrapped as an instance of <javadoc>org.zkoss.zk.ui.event.ForwardEvent</javadoc>. To retrieve the original event, you could invoke <javadoc method="getOrigin()">org.zkoss.zk.ui.event.ForwardEvent</javadoc>
 +
 
 +
== Using a component Path ==
 +
You can also use a component [http://books.zkoss.org/wiki/ZK_Developer's_Guide/ZK_in_Depth/Component_Path_and_Accesibility/Access_UI_Component Path] within your ZUML pages to specify a target component to which you would like to forward a specific event. This is especially useful if you want to forward events across different [http://books.zkoss.org/wiki/ZK_Developer's_Reference/UI_Composing/ID_Space IdSpace] such as forwarding event from a component in an included ZUML page to the main page component. For example
 +
 
 +
<source lang="xml" >
 +
<?page id="mainPage" ?>
 +
<window id="mainWindow" apply="BetterComposer">
 +
...
 +
    <include src="incDetails.zul" />
 +
...
 +
</window>
 +
</source>
 +
 
 +
Now in your included page use [http://books.zkoss.org/wiki/ZK_Developer's_Guide/ZK_in_Depth/Component_Path_and_Accesibility/Access_UI_Component  Path] while forwarding event to mainWindow <code>Window</code> component
 +
 
 +
<source lang="xml" >
 +
  <button forward="//mainPage/mainWindow.onSave" /> <!-- default forward event is onClick -->
 +
</source>
 +
 
 +
 
 +
== Forward with Parameters ==
 +
You can specify any application-specific data in the forward attribute by surrounding it with the parenthesis as shown below:
 +
 
 +
<source lang="xml" >
 +
<button forward="onCancel(abort)"/><!-- "abort" is passed -->
 +
<button forward="onPrint(${inf})"/><!-- the object returned by ${inf} is passed -->
 +
</source>
 +
 
 +
Then, you can retrieve the application-specific data by <javadoc method="getData()">org.zkoss.zk.ui.event.ForwardEvent</javadoc>.
 +
 
 +
'''Notice''' : When using <i>forward</i> attribute in the ZUML(.zul) with ZK MVC controller, you have to get the original event by using '''getOrigin()''', then you can access the data by '''getData()''' <br />
 +
*Example : ZUL
 +
<source lang="xml" >
 +
<tabbox id="ctrl" apply="composer1">
 +
  <tabs>
 +
    <tab id="tb1" label="News" forward="ctrl.onSelectTab(0)"></tab>
 +
    <tab id="tb2" label="News Images" forward="ctrl.onSelectTab(1)"></tab>
 +
  </tabs>
 +
</tabbox>
 +
</source>
 +
*Example Composer (composer1)
 +
<source lang="java" >
 +
@Listen("onSelectTab = #ctrl")
 +
public void doChangeTab(ForwardEvent e) {
 +
    MouseEvent me = (MouseEvent) e.getOrigin();
 +
    System.out.println(me.getData());
 +
}
 +
</source>
 +
 
 +
== Foward Multiple Events ==
 +
If you want to forward several events at once, you can specify them in the forward attribute by separating them with the comma '''<code>,</code>'''. For example,
 +
 
 +
<source lang="xml" >
 +
<textbox forward="onChanging=onUpdating, onChange=some.onUpdate"/>
 +
</source>
  
Notice that the event being forwarded is wrapped as an instance of <javadoc>org.zkoss.zk.ui.event.ForwardEvent</javadoc>. To retrieve the original event, you could invoke <javadoc method="getOrigin()">org.zkoss.zk.ui.event.ForwardEvent</javadoc>
+
In addition, the target component and the event data can be specified in EL expressions, while the event names cannot.
  
 
=Version History=
 
=Version History=
  
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-
Line 57: Line 121:
 
|}
 
|}
  
{{ZKComponentReferencePageFooter}}
+
{{ZKDevelopersReferencePageFooter}}

Revision as of 15:01, 12 January 2022



Overview

For easy programming, ZK does not introduce any complex event flow. When an event is sent to a target component, only the event listeners registered for the target component will be called. It is the application's job to forward an event to another component if necessary.

For example, you might have a menu item and a button to trigger the same action, say, opening a dialog, and then it is more convenient to have a single listener to open the dialog, and register the listener to the main window rather than register to both the menu item and button.

Event Forwarding in Java

Forwarding an event is straightforward: just posting or sending the event again. However, there is a better way: composer. The composer can be the central place to handle the events. For example, you could invoke openDialog in the event handler for the menu item and button as shown below:

public class FooComposer extends SelectorComposer {
   @Listen("onClick = menuitem#item1; onClick = button#btn")
   private void openDialog() {
     //whatever you want
   }
}

Event Forwarding in ZUML

Event forwarding can be done with the forward attribute in ZUML. For example,

<window id="mywin">
	<button label="Save" forward="onSave"/>
	<button label="Cancel" forward="onCancel"/>
</window>

Then, window will receive the onSave event when the Save button is clicked.

With this approach we could introduce an abstract layer between the event and the component. For example, window needs only to handle the onSave event without knowing which component causes it. Therefore, you could introduce another UI to trigger onSave without modifying the event listener. For example,

	<menuitem label="Save" forward="onSave"/>

Of course, you can use the composer and ZUML's forward together to have more maintainable code.

1 public class BetterComposer
2 extends org.zkoss.zk.ui.select.SelectorComposer {
3     @Listen("onSave = #mywin")
4     public void doSave(ForwardEvent event) { //signature if you care about event
5         ...
6     }
7     @Listen("onCancel = #mywin")
8     public void doCancel() { //signature if you don't care the event
9         ...

Notice that, as shown above, the event being forwarded is wrapped as an instance of ForwardEvent. To retrieve the original event, you could invoke ForwardEvent.getOrigin()

Using a component Path

You can also use a component Path within your ZUML pages to specify a target component to which you would like to forward a specific event. This is especially useful if you want to forward events across different IdSpace such as forwarding event from a component in an included ZUML page to the main page component. For example

<?page id="mainPage" ?>
<window id="mainWindow" apply="BetterComposer">
...
    <include src="incDetails.zul" />
...
</window>

Now in your included page use Path while forwarding event to mainWindow Window component

   <button forward="//mainPage/mainWindow.onSave" /> <!-- default forward event is onClick -->


Forward with Parameters

You can specify any application-specific data in the forward attribute by surrounding it with the parenthesis as shown below:

 <button forward="onCancel(abort)"/><!-- "abort" is passed -->
 <button forward="onPrint(${inf})"/><!-- the object returned by ${inf} is passed -->

Then, you can retrieve the application-specific data by ForwardEvent.getData().

Notice : When using forward attribute in the ZUML(.zul) with ZK MVC controller, you have to get the original event by using getOrigin(), then you can access the data by getData()

  • Example : ZUL
<tabbox id="ctrl" apply="composer1">
  <tabs>
     <tab id="tb1" label="News" forward="ctrl.onSelectTab(0)"></tab>
     <tab id="tb2" label="News Images" forward="ctrl.onSelectTab(1)"></tab>
  </tabs>
</tabbox>
  • Example Composer (composer1)
	@Listen("onSelectTab = #ctrl")
	public void doChangeTab(ForwardEvent e) { 
	    MouseEvent me = (MouseEvent) e.getOrigin();
	    System.out.println(me.getData());
	}

Foward Multiple Events

If you want to forward several events at once, you can specify them in the forward attribute by separating them with the comma ,. For example,

 <textbox forward="onChanging=onUpdating, onChange=some.onUpdate"/>

In addition, the target component and the event data can be specified in EL expressions, while the event names cannot.

Version History

Version Date Content
     



Last Update : 2022/01/12

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.