ZK Attributes"

From Documentation
m (correct highlight (via JWB))
 
(3 intermediate revisions by one other user not shown)
Line 9: Line 9:
 
! <center>Description</center>
 
! <center>Description</center>
 
|-
 
|-
| [http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_if_Attribute<tt>if</tt>]
+
| [http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_if_Attribute<code>if</code>]
 
| Conditional evaluation of an component
 
| Conditional evaluation of an component
 
|-
 
|-
| [http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_forEach_Attribute<tt>forEach</tt>, <tt>each</tt>]
+
| [http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_forEach_Attribute<code>forEach</code>, <code>each</code>]
 
| Iterative evaluate component against a collection
 
| Iterative evaluate component against a collection
 
|-
 
|-
| [http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_use.2C_apply_Attribute<tt>use</tt>, <tt>apply</tt>]
+
| [http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_use.2C_apply_Attribute<code>use</code>, <code>apply</code>]
  
| Write event handling code in pure java file. <tt>apply</tt> support MVC pattern better.
+
| Write event handling code in pure java file. <code>apply</code> support MVC pattern better.
 
|-
 
|-
| [http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_forward_Attribute<tt>forward</tt>]
+
| [http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_forward_Attribute<code>forward</code>]
  
 
| Let centralized controller handle events.
 
| Let centralized controller handle events.
Line 28: Line 28:
 
ZK attributes are used to '''control''' the associated element, other than initializing the data member.
 
ZK attributes are used to '''control''' the associated element, other than initializing the data member.
  
== The <tt>if</tt> Attribute ==
+
== The <code>if</code> Attribute ==
  
The evaluation of an element could be conditional. By specifying the <tt>if</tt> attribute, developers could control whether to evaluate the associated element.
+
The evaluation of an element could be conditional. By specifying the <code>if</code> attribute, developers could control whether to evaluate the associated element.
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 38: Line 38:
 
It specified the condition to evaluate the associated element. In other words, the associated element and all its child elements are ignored, if the condition is evaluated to false.
 
It specified the condition to evaluate the associated element. In other words, the associated element and all its child elements are ignored, if the condition is evaluated to false.
  
In the following example, the <tt>window</tt> component is created only if a is 1.  
+
In the following example, the <code>window</code> component is created only if a is 1.  
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 48: Line 48:
  
 
'''Note'''
 
'''Note'''
:There are other control attributes <tt>unless</tt>, <tt>switch</tt>, <tt>case</tt>, <tt>choose</tt>, <tt>when</tt> function like <tt>if</tt>. Please refer to Developer's Reference for more information.
+
:There are other control attributes <code>unless</code>, <code>switch</code>, <code>case</code>, <code>choose</code>, <code>when</code> function like <code>if</code>. Please refer to Developer's Reference for more information.
  
:Besides logical comparison, value of <tt>if</tt> also accepts string. But only string "true" will be accepted as true. Therefore, <tt><button if="abc"/></tt> won't be rendered, but <tt><button if="true"/></tt> will.
+
:Besides logical comparison, value of <code>if</code> also accepts string. But only string "true" will be accepted as true. Therefore, <code><button if="abc"/></code> won't be rendered, but <code><button if="true"/></code> will.
  
== The <tt>forEach</tt>, <tt>each</tt> Attribute ==
+
== The <code>forEach</code>, <code>each</code> Attribute ==
  
The evaluation of an element could be iterative. By specifying a collection of objects to the <tt>forEach</tt> Attribute, developers could control how many times of the associated element shall be evaluated.
+
The evaluation of an element could be iterative. By specifying a collection of objects to the <code>forEach</code> Attribute, developers could control how many times of the associated element shall be evaluated.
  
 
In the following example, the list item is created three times. Each of them has the label called "Good", "Better" and "Best", respectively.
 
In the following example, the list item is created three times. Each of them has the label called "Good", "Better" and "Best", respectively.
Line 75: Line 75:
  
 
Note that  
 
Note that  
#the order of <tt>label="${each}"</tt> and <tt>forEach="Good, Better, Best"</tt> inside <tt><listitem/></tt> doesn't matter, because they are both inside the scope of <tt>listitem</tt>.  
+
#the order of <code>label="${each}"</code> and <code>forEach="Good, Better, Best"</code> inside <code><listitem/></code> doesn't matter, because they are both inside the scope of <code>listitem</code>.  
#Since <tt>forEach</tt> is declared in <tt><listitem.../></tt>, <tt>listitem</tt> is rendered three times for "Good, Better, Best" has three elements.  
+
#Since <code>forEach</code> is declared in <code><listitem.../></code>, <code>listitem</code> is rendered three times for "Good, Better, Best" has three elements.  
#And inside each <tt><listitem/></tt>, <tt>${each}</tt> is assigned "Good", "Better", "Best" in sequence.
+
#And inside each <code><listitem/></code>, <code>${each}</code> is assigned "Good", "Better", "Best" in sequence.
  
=== The <tt>each</tt> Variable ===
+
=== The <code>each</code> Variable ===
  
During the evaluation, a variable called <tt>each</tt> is created and assigned with the item from the specified collection being iterated by <tt>forEach</tt>. In the above example, <tt>each</tt> is assigned with "Good" in the first iteration, then "Better" and finally "Best".  
+
During the evaluation, a variable called <code>each</code> is created and assigned with the item from the specified collection being iterated by <code>forEach</code>. In the above example, <code>each</code> is assigned with "Good" in the first iteration, then "Better" and finally "Best".  
  
=== The <tt>forEach</tt> Attribute ===
+
=== The <code>forEach</code> Attribute ===
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 90: Line 90:
 
</source>
 
</source>
 
   
 
   
The value assigned to <tt>forEach</tt> is usually a collection of objects, such that the associated element will be evaluated repeatedly against each object in the collection. It's scope is the same as the component it is declared inside. In the above example, the <tt>forEach</tt> can only be seen inside <tt>listitem</tt>'s scope. And only <tt>each</tt> inside the <tt>listitem</tt>'s scope will be assigned with the evaluating object in the collection.  
+
The value assigned to <code>forEach</code> is usually a collection of objects, such that the associated element will be evaluated repeatedly against each object in the collection. It's scope is the same as the component it is declared inside. In the above example, the <code>forEach</code> can only be seen inside <code>listitem</code>'s scope. And only <code>each</code> inside the <code>listitem</code>'s scope will be assigned with the evaluating object in the collection.  
  
The following is another example. You can assign a collection of object in <tt>zscript</tt>, and assign it to <tt>forEach</tt> with EL.
+
The following is another example. You can assign a collection of object in <code>zscript</code>, and assign it to <code>forEach</code> with EL.
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 106: Line 106:
 
</source>
 
</source>
  
[[How to Use each Variables in Event Listeners | Learn more, How to Use each Variables in Event Listeners]]
+
== The <code>use</code>, <code>apply</code> Attribute ==
 +
As demoed  in section [[ZK_Developer's_Guide/Advanced_ZK/MVC_in_ZK | Design pattern: MVC]]. You can use MVC pattern with ZK easily. It is suggested to use <code>apply</code> instead of <code>use</code>.
  
== The <tt>use</tt>, <tt>apply</tt> Attribute ==
+
=== The <code>use</code> Attribute ===
As demoed  in section [[ZK_Developer's_Guide/Advanced_ZK/MVC_in_ZK | Design pattern: MVC]]. You can use MVC pattern with ZK easily. It is suggested to use <tt>apply</tt> instead of <tt>use</tt>.
 
 
 
=== The <tt>use</tt> Attribute ===
 
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 118: Line 116:
 
</source>
 
</source>
 
   
 
   
Every ZK UI component has its mapping java class. <tt>use</tt> specifies a class to create a component instead of the default one. In the following example, <tt>MyWindow</tt> is used instead of the default class, <javadoc>org.zkoss.zul.Window</javadoc>.
+
Every ZK UI component has its mapping java class. <code>use</code> specifies a class to create a component instead of the default one. In the following example, <code>MyWindow</code> is used instead of the default class, <javadoc>org.zkoss.zul.Window</javadoc>.
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 124: Line 122:
 
</source>
 
</source>
  
If you want to customize your UI component, <tt>use</tt> is the suggested way.  
+
If you want to customize your UI component, <code>use</code> is the suggested way.  
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 141: Line 139:
 
</source>
 
</source>
  
You can customized your own class by extending from original class. In above example, <tt>MyWindow</tt> is extended from <tt>Window</tt>. You can write event handling code in extended class. Therefore you can customize your UI component in <tt>onCreate()</tt>.
+
You can customized your own class by extending from original class. In above example, <code>MyWindow</code> is extended from <code>Window</code>. You can write event handling code in extended class. Therefore you can customize your UI component in <code>onCreate()</code>.
  
=== The <tt>apply</tt> Attribute ===
+
=== The <code>apply</code> Attribute ===
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 152: Line 150:
 
</source>
 
</source>
  
This attribute is mainly for [http://en.wikipedia.org/wiki/Model-view-controller MVC] pattern. You can implement the <tt>controller</tt>, and then <tt>apply</tt> it.  
+
This attribute is mainly for [http://en.wikipedia.org/wiki/Model-view-controller MVC] pattern. You can implement the <code>controller</code>, and then <code>apply</code> it.  
  
It specifies a class, a collection of classes that are used to initialize the component. The class must implement the <javadoc type="interface">org.zkoss.zk.util.Composer</javadoc> interface. And then, you can do the initialization in the <tt>doAfterCompose</tt> method, since it is called after the component and all its children are instantiated. Developer can call <tt>addEventListener</tt> inside <tt>doAfterCompose</tt>. [[example code for addEventListener and apply | example code]]
+
It specifies a class, a collection of classes that are used to initialize the component. The class must implement the <javadoc type="interface">org.zkoss.zk.util.Composer</javadoc> interface. And then, you can do the initialization in the <code>doAfterCompose</code> method, since it is called after the component and all its children are instantiated. Developer can call <code>addEventListener</code> inside <code>doAfterCompose</code>.
  
 
For easier implementing, it has implemented auto-wire feature, which enable you use java code to access UI component with more intuitive syntax. As example in section [[ZK_Developer's_Guide/Advanced_ZK/MVC_in_ZK | Design pattern: MVC]] showed, you can forward event to controller, let controller handle it.
 
For easier implementing, it has implemented auto-wire feature, which enable you use java code to access UI component with more intuitive syntax. As example in section [[ZK_Developer's_Guide/Advanced_ZK/MVC_in_ZK | Design pattern: MVC]] showed, you can forward event to controller, let controller handle it.
  
For even easier implementing, <tt>forward</tt> can be omitted. In this smalltalk, [http://www.zkoss.org/smalltalks/mvc3/ ZK MVC Made Easy] demo ways to use <tt>apply</tt> to implement MVC pattern. It's '''highly recommended''' to read this smalltalk.
+
For even easier implementing, <code>forward</code> can be omitted. In this smalltalk, [http://www.zkoss.org/smalltalks/mvc3/ ZK MVC Made Easy] demo ways to use <code>apply</code> to implement MVC pattern. It's '''highly recommended''' to read this smalltalk.
  
In the following example, when <tt>button</tt> is clicked, its label will change from "test" to "event handled". Beware of naming pattern of <tt>button</tt>. It's <tt>btn_1</tt> both in zul file and java file. By giving the same name, it's '''auto-wired'''. Isn't it so intuitive?
+
In the following example, when <code>button</code> is clicked, its label will change from "test" to "event handled". Beware of naming pattern of <code>button</code>. It's <code>btn_1</code> both in zul file and java file. By giving the same name, it's '''auto-wired'''. Isn't it so intuitive?
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 185: Line 183:
 
</source>
 
</source>
  
=== The difference between <tt>use</tt> and <tt>apply</tt> ===
+
=== The difference between <code>use</code> and <code>apply</code> ===
You can write event handling code in java file through attribute <tt>use</tt> or <tt>apply</tt>. What's the difference between <tt>use</tt> and <tt>apply</tt>? It's a design pattern MVC issue. <tt>use</tt> will entangle View with Control, since you write the event handling codes in class that extends from UI component. Therefore, for MVC approach, <tt>apply</tt> is suggested. More than that, you can assign a java <tt>Object</tt> of <tt>composer</tt> to <tt>apply</tt>, but <tt>use</tt> can't. There are more article about MVC in ZK. Please goto ZK's [[Small_Talks]] and search "MVC". [http://www.zkoss.org/forum/index.zul#path%3DlistComment%3BdiscussionId%3D6253%3BcategoryId%3D14%3B A Forum Thread] that discuss the difference between <tt>use</tt> and <tt>apply</tt> thoroughly.
+
You can write event handling code in java file through attribute <code>use</code> or <code>apply</code>. What's the difference between <code>use</code> and <code>apply</code>? It's a design pattern MVC issue. <code>use</code> will entangle View with Control, since you write the event handling codes in class that extends from UI component. Therefore, for MVC approach, <code>apply</code> is suggested. More than that, you can assign a java <code>Object</code> of <code>composer</code> to <code>apply</code>, but <code>use</code> can't. There are more article about MVC in ZK. Please goto ZK's [[Small_Talks]] and search "MVC". [http://www.zkoss.org/forum/index.zul#path%3DlistComment%3BdiscussionId%3D6253%3BcategoryId%3D14%3B A Forum Thread] that discuss the difference between <code>use</code> and <code>apply</code> thoroughly.
  
== The <tt>forward</tt> Attribute ==
+
== The <code>forward</code> Attribute ==
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 196: Line 194:
 
</source>
 
</source>
 
   
 
   
where <tt>''target_event_expr''</tt> is an event expressions which will be described later.
+
where <code>''target_event_expr''</code> is an event expressions which will be described later.
  
The second format assumes the original event is <tt>onClick</tt>. In other words, the following are the same. They both rename the <tt>onClick</tt> event to <tt>onOK</tt> and forward to the space owner
+
The second format assumes the original event is <code>onClick</code>. In other words, the following are the same. They both rename the <code>onClick</code> event to <code>onOK</code> and forward to the space owner
 
<source lang="xml">
 
<source lang="xml">
 
<button forward="onOK"/>
 
<button forward="onOK"/>
Line 223: Line 221:
 
It is used to forward an event, that is targeting a particular component, to another component and to another event name. It is called the forward condition.
 
It is used to forward an event, that is targeting a particular component, to another component and to another event name. It is called the forward condition.
  
For example, you can forward the <tt>onClick</tt> event targeting a button to the window as follows:
+
For example, you can forward the <code>onClick</code> event targeting a button to the window as follows:
  
 
<source lang="java" >
 
<source lang="java" >
Line 232: Line 230:
 
</source>
 
</source>
 
   
 
   
Then, you can handle the submission in the <tt>MyWindow</tt> class as follows:
+
Then, you can handle the submission in the <code>MyWindow</code> class as follows:
  
 
<source lang="java" >
 
<source lang="java" >
Line 242: Line 240:
 
</source>
 
</source>
 
   
 
   
The original event is optional. If it is omitted, <tt>onClick</tt> is assumed. Similarly, the target ID is also optional. If omitted, the space owner is assumed. Thus, the above codes can be simplified to the following:
+
The original event is optional. If it is omitted, <code>onClick</code> is assumed. Similarly, the target ID is also optional. If omitted, the space owner is assumed. Thus, the above codes can be simplified to the following:
  
 
<source lang="java" >
 
<source lang="java" >
Line 258: Line 256:
 
   
 
   
 
=== The Forward Event ===
 
=== The Forward Event ===
Event that is forwarded, will be wrapped and transformed to Forward Event (<javadoc>org.zkoss.zk.ui.event.ForwardEvent</javadoc>), not the type of original event anymore. If you want to get event data, you can retrieve the original event by use of the <tt>getOrigin</tt> method. An event may be forwarded multiple times, therefore you may have to use <tt>getOrigin</tt> in a while loop, till you get the origin event.[[example code for forward event | a example of getOrigin]]
+
Event that is forwarded, will be wrapped and transformed to Forward Event (<javadoc>org.zkoss.zk.ui.event.ForwardEvent</javadoc>), not the type of original event anymore. If you want to get event data, you can retrieve the original event by use of the <code>getOrigin</code> method. An event may be forwarded multiple times, therefore you may have to use <code>getOrigin</code> in a while loop, till you get the origin event.
  
 
=== Pass Information to the Forward Event ===
 
=== Pass Information to the Forward Event ===
 
  forward="''orginalEvent''=''targetId1/targetId2.targetEvent(eventData)''"
 
  forward="''orginalEvent''=''targetId1/targetId2.targetEvent(eventData)''"
  
You can pass the application-specific information to the forward event by surrounding it with parenthesis and appending it to the forward condition as shown above. The information can be retrieved by use of the <tt>getData</tt> method of the <tt>ForwardEvent</tt> class.
+
You can pass the application-specific information to the forward event by surrounding it with parenthesis and appending it to the forward condition as shown above. The information can be retrieved by use of the <code>getData</code> method of the <code>ForwardEvent</code> class.
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 269: Line 267:
 
</source>
 
</source>
 
   
 
   
The <tt>getData</tt> method will return <tt>"abort"</tt>.
+
The <code>getData</code> method will return <code>"abort"</code>.
  
 
Of course, you can specify EL expressions to pass whatever type of data you want.
 
Of course, you can specify EL expressions to pass whatever type of data you want.
  
In the following example, a <tt>Date</tt> object will be the data in the event. You can set breakpoint in Eclipse to observe the content of <tt>evt</tt>
+
In the following example, a <code>Date</code> object will be the data in the event. You can set breakpoint in Eclipse to observe the content of <code>evt</code>
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 298: Line 296:
 
</source>
 
</source>
  
'''Note''' <tt>forward="onSayHello(${now})"</tt> is not <tt>zscript</tt>, and it accept EL. On the other hand, value of <tt>onXXX</tt> is <tt>zscript</tt>.
+
'''Note''' <code>forward="onSayHello(${now})"</code> is not <code>zscript</code>, and it accept EL. On the other hand, value of <code>onXXX</code> is <code>zscript</code>.
 
=== EL Expressions in the Forward Condition ===
 
=== EL Expressions in the Forward Condition ===
 
  forward="''originalEvent''=''${el-targetPath}.targetEvent(${el-eventData})''"
 
  forward="''originalEvent''=''${el-targetPath}.targetEvent(${el-eventData})''"
Line 311: Line 309:
  
 
=== If you prefer pure java solution ===
 
=== If you prefer pure java solution ===
<tt>addForward</tt> is the api you need. Please refer to the [http://www.zkoss.org/javadoc/3.5.1/zk/org/zkoss/zk/ui/AbstractComponent.html java doc].
+
<code>addForward</code> is the api you need. Please refer to the [http://www.zkoss.org/javadoc/3.5.1/zk/org/zkoss/zk/ui/AbstractComponent.html java doc].
  
 
== See Also ==
 
== See Also ==
Line 325: Line 323:
  
 
== Quiz ==
 
== Quiz ==
1.We can append parameter in url by appending <tt>?variableName=variableValue</tt> behind usual url. For example, the following url:
+
1.We can append parameter in url by appending <code>?variableName=variableValue</code> behind usual url. For example, the following url:
 
http://10.1.3.103:8080/zksTest/helloworld.zul?good=yes
 
http://10.1.3.103:8080/zksTest/helloworld.zul?good=yes
And <tt>${param.good=="yes"}</tt> will be evaluated as true.
+
And <code>${param.good=="yes"}</code> will be evaluated as true.
  
Use <tt>if</tt> to write a zul that will layout 1 to 3 buttons depends on user input parameter.
+
Use <code>if</code> to write a zul that will layout 1 to 3 buttons depends on user input parameter.
  
  
2.Generate 100 <tt>button</tt>s by <tt>each</tt> and <tt>forEach</tt>
+
2.Generate 100 <code>button</code>s by <code>each</code> and <code>forEach</code>
  
 
3.Implement MyWindow.java, such that
 
3.Implement MyWindow.java, such that
Line 351: Line 349:
 
</source>
 
</source>
  
5. Complete MyWindow.java, when <tt>button</tt> Submit or Cancel is clicked, a different text will append to the <tt>window</tt>.
+
5. Complete MyWindow.java, when <code>button</code> Submit or Cancel is clicked, a different text will append to the <code>window</code>.
 
<source lang="xml" >
 
<source lang="xml" >
 
  <window use="MyWindow">     
 
  <window use="MyWindow">     

Latest revision as of 10:37, 19 January 2022

Stop.png This documentation is for an older version of ZK. For the latest one, please click here.


Act on component, such like conditional evaluation, iteration, load on demand.

Attribute Name
Description
if Conditional evaluation of an component
forEach, each Iterative evaluate component against a collection
use, apply Write event handling code in pure java file. apply support MVC pattern better.
forward Let centralized controller handle events.


Overview

ZK attributes are used to control the associated element, other than initializing the data member.

The if Attribute

The evaluation of an element could be conditional. By specifying the if attribute, developers could control whether to evaluate the associated element.

 if="${an-EL-expr}"

It specified the condition to evaluate the associated element. In other words, the associated element and all its child elements are ignored, if the condition is evaluated to false.

In the following example, the window component is created only if a is 1.

<window if="${a==1}">
     ...
</window>


Note

There are other control attributes unless, switch, case, choose, when function like if. Please refer to Developer's Reference for more information.
Besides logical comparison, value of if also accepts string. But only string "true" will be accepted as true. Therefore, <button if="abc"/> won't be rendered, but <button if="true"/> will.

The forEach, each Attribute

The evaluation of an element could be iterative. By specifying a collection of objects to the forEach Attribute, developers could control how many times of the associated element shall be evaluated.

In the following example, the list item is created three times. Each of them has the label called "Good", "Better" and "Best", respectively.

 <listbox>
   <listitem label="${each}" forEach="Good, Better, Best"/>
 </listbox>

Therefore, above example is expanded to:

 <listbox>
   <listitem label="Good"/>
   <listitem label="Better"/>
   <listitem label="Best"/>
 </listbox>

Note that

  1. the order of label="${each}" and forEach="Good, Better, Best" inside <listitem/> doesn't matter, because they are both inside the scope of listitem.
  2. Since forEach is declared in <listitem.../>, listitem is rendered three times for "Good, Better, Best" has three elements.
  3. And inside each <listitem/>, ${each} is assigned "Good", "Better", "Best" in sequence.

The each Variable

During the evaluation, a variable called each is created and assigned with the item from the specified collection being iterated by forEach. In the above example, each is assigned with "Good" in the first iteration, then "Better" and finally "Best".

The forEach Attribute

 forEach="${an-EL-expr}"
 forEach="${an-EL-expr},a-value"

The value assigned to forEach is usually a collection of objects, such that the associated element will be evaluated repeatedly against each object in the collection. It's scope is the same as the component it is declared inside. In the above example, the forEach can only be seen inside listitem's scope. And only each inside the listitem's scope will be assigned with the evaluating object in the collection.

The following is another example. You can assign a collection of object in zscript, and assign it to forEach with EL.

<window>
	<zscript><![CDATA[	
		grades = new String[] {"Good", "Better", "Best"};
	]]>
	</zscript>
	<listbox>
		<listitem label="${each}" forEach="${grades}" />
	</listbox>
</window>

The use, apply Attribute

As demoed in section Design pattern: MVC. You can use MVC pattern with ZK easily. It is suggested to use apply instead of use.

The use Attribute

 use="a-class-name"
 use="${EL_returns_a_class_or_a_class_name}"

Every ZK UI component has its mapping java class. use specifies a class to create a component instead of the default one. In the following example, MyWindow is used instead of the default class, Window.

 <window use="MyWindow"/>

If you want to customize your UI component, use is the suggested way.

<window use="MyWindow"/>

And MyWindow.java

import org.zkoss.zul.Window;

public class MyWindow extends Window {
	public void onCreate(){
		this.setTitle("my window");
	}
}

You can customized your own class by extending from original class. In above example, MyWindow is extended from Window. You can write event handling code in extended class. Therefore you can customize your UI component in onCreate().

The apply Attribute

 apply="a-class-name"
 apply="class1, class2,..."
 apply="${EL_returns_a_class_or_a_collection_of_classes}"
 apply="${EL_returns_an_instance_or_a_collection_of_Composer_instances}"

This attribute is mainly for MVC pattern. You can implement the controller, and then apply it.

It specifies a class, a collection of classes that are used to initialize the component. The class must implement the Composer interface. And then, you can do the initialization in the doAfterCompose method, since it is called after the component and all its children are instantiated. Developer can call addEventListener inside doAfterCompose.

For easier implementing, it has implemented auto-wire feature, which enable you use java code to access UI component with more intuitive syntax. As example in section Design pattern: MVC showed, you can forward event to controller, let controller handle it.

For even easier implementing, forward can be omitted. In this smalltalk, ZK MVC Made Easy demo ways to use apply to implement MVC pattern. It's highly recommended to read this smalltalk.

In the following example, when button is clicked, its label will change from "test" to "event handled". Beware of naming pattern of button. It's btn_1 both in zul file and java file. By giving the same name, it's auto-wired. Isn't it so intuitive?

<window apply="MyController">
	<button id="btn_1" label="test"/>
</window>

And MyController.java

import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;

//Must extend from GenericForwardComposer to omit forward.
public class MyController extends GenericForwardComposer {
	private Button btn_1;

    //onClick event from btn_1 component
    public void onClick$btn_1(Event event) { 
    	btn_1.setLabel("event handled");
    }
}

The difference between use and apply

You can write event handling code in java file through attribute use or apply. What's the difference between use and apply? It's a design pattern MVC issue. use will entangle View with Control, since you write the event handling codes in class that extends from UI component. Therefore, for MVC approach, apply is suggested. More than that, you can assign a java Object of composer to apply, but use can't. There are more article about MVC in ZK. Please goto ZK's Small_Talks and search "MVC". A Forum Thread that discuss the difference between use and apply thoroughly.

The forward Attribute

 forward="oringal_event=target_event_expr"
 forward="target_event_expr"
 forward="oringal_event=" (since 5.0.0)

where target_event_expr is an event expressions which will be described later.

The second format assumes the original event is onClick. In other words, the following are the same. They both rename the onClick event to onOK and forward to the space owner

<button forward="onOK"/>
<button forward="onClick=onOK"/>

The third format assumes the name of the forward event is the same as the original one. For example, the following is the same.

<button forward="onClick="/>
<button forward="onClick=onClick"/>

Event Expression

An event expression is used to identify an event that is targeting a particular component. It can be one of the following formats:

 event-name
 target-id.event-name
 id1/id2/id3.event-name
 ${el-expr}.event-name

It is used to forward an event, that is targeting a particular component, to another component and to another event name. It is called the forward condition.

For example, you can forward the onClick event targeting a button to the window as follows:

 <window id="w" use="MyWindow">
     ...
     <button label="Submit" forward="onClick=w.onOK"/>
 </window>

Then, you can handle the submission in the MyWindow class as follows:

 public class MyWindow extends Window {
     public void onOK() {
         //handle the submission
     }
 }

The original event is optional. If it is omitted, onClick is assumed. Similarly, the target ID is also optional. If omitted, the space owner is assumed. Thus, the above codes can be simplified to the following:

 <window id="w" use="MyWindow">
     ...
     <button lable="Submit" forward="onOK"/>
 </window>

If you want to forward several events, you can specify these conditions in the forward attribute by separating them with the comma (,):

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

The Forward Event

Event that is forwarded, will be wrapped and transformed to Forward Event (ForwardEvent), not the type of original event anymore. If you want to get event data, you can retrieve the original event by use of the getOrigin method. An event may be forwarded multiple times, therefore you may have to use getOrigin in a while loop, till you get the origin event.

Pass Information to the Forward Event

forward="orginalEvent=targetId1/targetId2.targetEvent(eventData)"

You can pass the application-specific information to the forward event by surrounding it with parenthesis and appending it to the forward condition as shown above. The information can be retrieved by use of the getData method of the ForwardEvent class.

 <button forward="onCancel(abort)"/>

The getData method will return "abort".

Of course, you can specify EL expressions to pass whatever type of data you want.

In the following example, a Date object will be the data in the event. You can set breakpoint in Eclipse to observe the content of evt

 <window id="win" title="ZK app 6" apply="MyComposer">
 	<zscript><![CDATA[  
		Date now = new Date();
 	]]> 	
 	</zscript>
 	<button label="Say Hello" forward="onSayHello(${now})" />
 </window>

And MyComposer.java

import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericComposer;
import org.zkoss.zul.Label;

public class MyComposer extends GenericComposer {
	public void onSayHello(Event evt) {
		evt.getTarget().appendChild(new Label("Hello"));
	}
}

Note forward="onSayHello(${now})" is not zscript, and it accept EL. On the other hand, value of onXXX is zscript.

EL Expressions in the Forward Condition

forward="originalEvent=${el-targetPath}.targetEvent(${el-eventData})"

You can use EL expressions when specifying the target ID/path and the application-specific information (a.k.a., the event data).

 <button forward='${mainWnd}.onOK(${c:getProperty("status")})'/>

However, you can not use EL expressions to specify the event names.

If you prefer pure java solution

addForward is the api you need. Please refer to the java doc.

See Also

From ZK Forum:

Difference between use="" and apply=""

passing params to the controller class

Accessing EJB from Window controller

"Extend Window" --- problem

Quiz

1.We can append parameter in url by appending ?variableName=variableValue behind usual url. For example, the following url: http://10.1.3.103:8080/zksTest/helloworld.zul?good=yes And ${param.good=="yes"} will be evaluated as true.

Use if to write a zul that will layout 1 to 3 buttons depends on user input parameter.


2.Generate 100 buttons by each and forEach

3.Implement MyWindow.java, such that

<window title="Hello" border="normal" width="200px" height="200px"/>

can be write to

<window use="MyWindow"/>


4. Implement MyController.java, such that each the button is clicked, a new button is appended to the window.

<window apply="MyController">
	<button id="btn_1" label="test"/>
</window>

5. Complete MyWindow.java, when button Submit or Cancel is clicked, a different text will append to the window.

 <window use="MyWindow">     
     <button label="Submit" forward="onOK(yes)"/>
     <button label="Cancel" forward="onOK(no)"/>
 </window>

And MyWindow.java

public class MyWindow extends Window{
	public void onOK(Event evt){
		String input = (String)evt.getData();
		if(input.equals("yes")){
		}
	}
}



Last Update : 2022/01/19

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