ZK Elements

From Documentation

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


Helper component that's not UI. It helps to save variable, write java code in ZUML, and others.

Element Name
Description
zk Aggregate other components
zscript Write java code in ZUML
attribute] Make the page more readable
variables Store variable in namespace scope
custom-attributes Store variables in different scopes

Overview

ZK elements are used to control ZUML pages other than creating components.

The zk Element

 <zk>...</zk>

It is a special element used to aggregate other components. Unlike a real component (say, hbox or div), it is not part of the component tree being created. In other words, it doesn't represent any component. For example,

 <window>
     <zk>
         <textbox/>
         <textbox/>
     </zk>
 </window>

is equivalent to

 <window>
     <textbox/>
     <textbox/>
 </window>

Then, what is it used for?

Multiple Root Elements in a Page

Due to XML's syntax limitation, we can only specify one document root. Thus, if you have multiple root components, you must use zk as the document root to group these root components.[1]

 <?page title="Multiple Root"?>
 <zk>
     <window title="First">
     ...
     </window>
     <window title="Second">
     ...
     </window>
 </zk>

Iteration Over Versatile Components

The zk element, like components, supports the forEach attribute. Thus, you could use it to generate different type of components depending on the conditions. In the following example, we assume mycols is a collection of objects that have member, isUseText(). For each object in mycols, a textbox will be created if isUseText() returns true. useText is auto transformed to isUseText() by EL expression evaluation.

 <window>
     <zk forEach="${mycols}">
         <textbox if="${each.useText}"/>
     </zk>
 </window>

For more information about forEach, if, please refer to section The ZK Attributes.

Notes

  1. A component without any parent is called a root component

The zscript Element

Write java code in ZUML

<zscript>Scripting codes</zscript>
<zscript src="uri"/>

It defines a piece of the scripting codes, say the Java codes, that will be interpreted when the page is evaluated. The language of the scripting codes is, by default, Java.

The zscript element has two formats as shown above. The first format is used to embed the scripting codes directly in the page. The second format is used to reference an external file that contains the scripting codes.

You can also embed zscript in event handler in ZUML. In the following example,

 <button onClick="alert(&quot;Hi&quot;)"/>

alert("quot;Hi"quot;)is also a piece of zscript code.

Attribute Name
Description
src [Optional][Default: none]

Specifies the URI of the file containing the scripting codes. If specified, the scripting codes will be loaded as if they are embedded directly.


deferred [Optional][Default: false]

Whether to defer the evaluation of this element until the first non-deferred zscript codes of the same language need to be evaluated. Refer to the How to Defer the Evaluation section below.

How to Defer the Evaluation

ZK loads the interpreter before it is going to evaluate the first zscript codes. For example, the Java interpreter is loaded when the user clicks the button in the following example.

 <button onClick="alert(&quot;Hi&quot;)"/>

On the other hand, the interpreter is loaded when loading the following ZUML page, since the zscript element needs to be evaluated when loading the page.

 <window>
     <zscript>
     void add() {
     }
     </zscript>
     <button onClick="add()"/>
 </window>

If you prefer to defer the loading of the interpreter, you can specify the deferred option with true. Then, the interpreter won't be loaded, until the user clicks the button.

 <window>
     <zscript deferred="true">
     void add() {
     }
     </zscript>
     <button onClick="add()"/>
 </window>

Note: The evaluation of EL expressions specified in the if, unless and src attributes are also deferred.

Note: If the component is detached from the page by the time the interpreter is loaded, the zscript codes are ignored. For example, if the window in the previous example no longer belongs to the page, the deferred zscript won't be interpreted.

The attribute Element

Make the page more readable

It defines a XML attribute of the enclosing element. The content of the element is the attribute value, while the name attribute specifies the attribute name. It is useful if the value of an attribute is sophisticated, or the attribute is conditional. With proper use, it makes the page more readable.

For example:

<button label="Say Hello" onClick="alert(&quot;Hello World!&quot;)"/>

is equivalent to

<button label="Say Hello">
     <attribute name="onClick">alert("Hello World!");</attribute>    
</button>

In the following example, title of the window depends on ${new}.

 <window>
     <attribute name="title" if="${new}">New is True</attribute>
 </window>

Native Content

In addition, you can specify a XML fragment as the value of the attribute. The XML fragment is so-called the native content.

 <html>
     <attribute name="content">
         <ol>
             <li forEach="${values}">${each}</li>
         </ol>
     </attribute>
 </html>

where ol and li are part of the native content. They are not ZK components. They will be eventually converted to a String instance and assigned to the specified attribute. If values has three elements, the above example is equivalent to the following:

 <html>
     <attribute name="content">
         <ol>
             <li>${values[0]}</li>
             <li>${values[1]}</li>
             <li>${values[2]}</li>
         </ol>
     </attribute>
 </html>
Attribute Name
Description
name [Required]

Specifies the attribute name.

trim [Optional][Default: false]

Specifies whether to omit the leading and trailing white-spaces of the attribute value.


The custom-attributes element

The custom-attributes element is used to defines a set of custom attributes. Custom attributes are objects associated with a particular scope. Acceptable scopes include component, ID space, page, desktop, session and application.

As depicted below, custom-attributes is convenient to assign custom attributes without programming.

 <window>
     <custom-attributes main.rich="simple" very-simple="intuitive"/>
 </window>

It is equivalent to

 <window>
     <zscript>
         self.setAttribute("main.rich", "simple");
         self.setAttribute("very-simple", "intuitive");
     </zscript>
 </window>

Moreover, you could specify what scope to assign the custom attributes to.

 <window id="main" title="Welcome">
     <custom-attributes scope="desktop" shared="${main.title}"/>
 </window>

It is equivalent to

 <window id="main">
     <zscript>
         desktop.setAttribute("shared", main.title);
     </zscript>
 </window>

Retrieve attributes directly in EL and zscript

Since ZK 5.0, the custom attribute can be accessed directly if its name is a valid Java name. For example,

<window>
  <custom-attributes less="is more"/>
  ${less}
  <zscript>
  if ("is more".equals(less)) { //true
  }
  </zscript>
</window>

ZK will look up the value of a custom attribute from the nearest component, to its parent, to its ancestor, to its page, to its desktop, to the session, and to the application, until found.

Retrieve attributes in EL via built-in variables

A custom attribute can be retrieved from one of the following built-in variables, componentScope, spaceScope, pageScope, desktopScope, sessionScope, and applicationScope. They are all maps representing different scopes.

${pageScope.something}

Notice that EL expression is evaluated against the component being created. Sometime it is subtle to notice. For example, ${componentScope.simple} is evaluated to null, in the following codes. Why? It is a shortcut of <label value="${componentScope.simple}"/>. In other words, the component, self, is the label rather than the window, when the EL is evaluated.

 <window>
     <custom-attributes simple="intuitive"/>
     ${componentScope.simple}
 </window>

is equivalent to

 <window>
     <custom-attributes simple="intuitive"/>
     <label value="${componentScope.simple}"/><!-- self is label not window -->
 </window>

Tip: Don't confuse <attribute> with <custom-attributes>. They are irrelevant. The attribute element is a way to assign value to a predefined XML attribute of the enclosing element, while the custom-attributes element is used to assign new custom attributes to particular scopes.

Specify a list or a map of values with the composite Attribute

If you want to specify a list of values, you can specify the composite attribute with list as follows.

 <custom-attributes simple="apple, orange" composite="list"/>

Then, it is converted to a list with two elements. The first element is "apple" and the second "orange".

If you want to specify a map of values, you can specify the composite attribute with map as follows.

 <custom-attributes simple="juice=apple, flavor=orange" composite="map"/>

Then, it is converted to a map with two entries. The first entry is ("juice", "apple") and the second ("flavor", "orange").

Specify null

In the following example, var is an empty string.

 <custom-attributes var=""/>

To define a variable with the null value, use the following statement.

 <custom-attributes var="${null}"/>
Attribute Name
Description
scope [Optional][Default: component]

Specifies what scope to associate the custom attributes to.

composite [Optional][Default: none]

Specifies the format of the value. It could be none, list or map.

The variables element

[deprecated since 5.0] The concept of namespace (and variables) is deprecated and replaced with the custom attribute (#The custom-attributes element).

The variables element is used to define a set of variables in the namespace. It is equivalent to the setVariable method of Component.

A namespace is a unique scope that is associated with an ID space. The relation is one-to-one.
However, it is deprecated since ZK 5.0 (because of the redundancy with custom attributes).

As depicted below, variables is convenient to assign variables without programming.

In the following example, we set a variable named "rich", and its value is "simple", a variable named "simple" and its value is "intuitive".

 <window>
     <variables rich="simple" simple="intuitive"/>
 </window>

It is equivalent to

 <window>
     <zscript>
         self.setVariable("rich", "simple", false);
         self.setVariable("simple", "intuitive", false);
     </zscript>
 </window>

Of course, you can specify EL expressions for the values.

 <window id="win1">
     <window id="w" title="Test">
	 <variables title="${w.title}"/>
         1: ${title}
     </window>
     2: ${title}
 </window>

The result will show 1: Test 2: . Since title is invisible in win1. Because it is stored in namespace, and window is an id space, and therefore a namespace.

Like Component's setVariable, you can control whether to declare variables local to the current ID space as follows. If not specified, local="false" is assumed.

 <variables simple="rich" local="true"/>

Note: local is an attribute of variables, so it's not parsed as a variable name. By default, local is false. It means if parent namespace has same variable, its value will be changed too.

In the following example, you can change the value of local to see the difference.

<window>
	<variables title="def"/>
	<window title="Test">
		<variables title="abc" local="false" />	
		1: ${title}
	</window>
	2: ${title}
</window>

Specify a list or a map of values with the composite Attribute

If you want to specify a list of values, you can specify the composite attribute with list as follows.

 <variables simple="apple, orange" composite="list"/>

Then, it is converted to a list with two elements. The first element is "apple" and the second "orange".

If you want to specify a map of values, you can specify the composite attribute with map as follows.

 <variables simple="juice=apple, flavor=orange" composite="map"/>

Then, it is converted to a map with two entries. The first entry is ("juice", "apple") and the second ("flavor", "orange").

Specify null

In the following example, var is an empty string.

 <variables var=""/>

To define a variable with the null value, use the following statement.

 <variables var="${null}"/>

See Also

From ZK Forum

Quiz

  1. What's root component? How many root component can a page have?
  2. Where does setVariable store variable?
  3. Where does custom-attributes store variable?



Last Update : 2022/01/19

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