Client Side Programming"
m (→See Also) |
|||
Line 303: | Line 303: | ||
#<javadoc directory="jsdoc">zk.Widget</javadoc> -- See the usage of $f(), $n(), bind_(), $() | #<javadoc directory="jsdoc">zk.Widget</javadoc> -- See the usage of $f(), $n(), bind_(), $() | ||
#[[Client Side Actions]] -- Deprecated since ZK5 | #[[Client Side Actions]] -- Deprecated since ZK5 | ||
− | #[[Client Watches]] -- onShow, onHide in ZK5 | + | #[[ZK Developer's Reference/Client-side Control/Client Activity Watches|Client Activity Watches]] -- onShow, onHide in ZK5 |
#[http://www.zkoss.org/javadoc/latest/jsdoc/ JavaScript API] -- Documentation for ZK JavaScript API. | #[http://www.zkoss.org/javadoc/latest/jsdoc/ JavaScript API] -- Documentation for ZK JavaScript API. | ||
#[http://www.zkoss.org/forum/listComment/12420 Customizing Error Box] -- from Forum | #[http://www.zkoss.org/forum/listComment/12420 Customizing Error Box] -- from Forum |
Revision as of 02:17, 1 December 2010
Peter Kuo, Engineer, Potix Corporation
April 20, 2010
ZK 5.0 and above
Introduction
In ZK 5 we continue to focus on our strong Server-side approach which boosts your productivity but now provides developers the option to control the client side programming. We have dubbed this blending of technology, Server+client Fusion.
In order to execute application-specific code at the client, ZK introduces the concept of the Client Namespace [1]. With the Client Namespace, developers are able to listen to any client-side event, override ZK methods and execute any custom client-side code.
- ↑ For ZK 3.6 and prior, please use Client Side Actions instead.
Before writing JavaScript in a ZUL file
Define ZK Client Namespace
In order to write client-side code, you are required to specify the XML namespace which is named http://www.zkoss.org/2005/zk/client. In the following example, you can see the onClick event is handled by client side JavaScript.
<button label="client" xmlns:w="http://www.zkoss.org/2005/zk/client" w:onClick="alert('clicked')"/>
How to Get Widget Reference in JavaScript
When the client event is invoked, you can reference the widget using this. In the below example this refers to the label.
<window xmlns:w="http://www.zkoss.org/2005/zk/client">
<label value="change me by click" w:onClick="this.setValue('clicked');"/>
</window>
widget can retrieve other widgets using the function $f. This works in a similar manner as getFellow.
In additions, you can use jQuery to select a DOM element of a widget[1]. For example jq("@window")
will select DOM elements of all window widget. And, jq("$win1")
will select DOM elements of all widgets whose ID is win1
. (see jq).
<window xmlns:w="http://www.zkoss.org/2005/zk/client">
<vbox>
<label id="labelone" value="click to change"
w:onClick="this.setValue('changed by click label');" />
<button label="button"
w:onClick="this.$f('labelone').setValue('changed by button');" />
<html><![CDATA[
<a href="javascript:;" onclick="zk.Widget.$(jq('$labelone')[0]).setValue('changed with jq');">not widget</a>
]]></html>
</vbox>
</window>
zk.Widget.$
is a utility to return particular zk widget by given id of dom element. (see Widget).
- ↑ Since ZK 5.0.2
Execute JavaScript After All Widgets Are Loaded
Set defer
attribute of script
to "true", if you want to access widgets. It means deferring the execution of the script codes until the widget is instantiated and mounted. Note that script
here is a zk component, not an HTML tag. Similarly, defer
here is not in the same context as HTML . More detail at Script.
<script defer="true">
..........
</script>
Things you can do
Define a Client-side Listener of ZK Widget event
For example, handle onClick
event of a label
component's corresponding widget at the client side.
<window xmlns:w="http://www.zkoss.org/2005/zk/client">
<label value="change me by click" w:onClick="this.setValue('clicked');"/>
</window>
In an event listener, you can access the widget by using this
as shown above. In addition, you can access the event (an instance of Event) by using event
.
You can find more detail at ZK5: Client Computing with ZUML
Override a Widget Method
For example, override the setValue
implementation of a label
widget.
<window xmlns:w="http://www.zkoss.org/2005/zk/client">
<label>
<attribute w:name="setValue">
function (value) {
this.$setValue(value); //call the original method
if (this.desktop) {
this._flag = !this._flag;
this.setStyle('background:'+(this._flag ? 'red':'green'));
}
}
</attribute>
</label>
</window>
You can find more detail at ZK5: Client Computing with ZUML.
EL expressions is allowed [1][2] to simplify the passing of data from server to client. For example, you could pass a Java bean's property to the client as shown below.
w:setValue='function (value) { this.$setValue(value + "${foo.description}")}';
Override a Default Widget Method
In previous section, we showed how to override method of a particular widget we declared. But how to override the default widget method for all such widgets? We can modify it by overwriting the widget's prototype
implementation. The following is a sample to modify the default setValue
of label
<window xmlns:w="http://www.zkoss.org/2005/zk/client">
<label id="labelone" value="label one"/>
<label id="labeltwo" value="label two"/>
<script defer="true">
old = zul.wgt.Label.prototype.setValue;
zul.wgt.Label.prototype.setValue = function (){
arguments[0]="modified prototype"+arguments[0];
old.apply(this,arguments);
}
</script>
<button label="change" onClick='labelone.setValue((new Date()).toString());labeltwo.setValue((new Date()).toString());'/>
</window>
Override a Default Widget Method for Whole Application
In additions to specifying the JavaScript code or file in each page, you can configure ZK to load one or more particular JavaScript files.
First, you have to modify zk.xml
to specify a so-called lang-addon XML file. For example,
<zk>
......
<language-config>
<addon-uri>/WEB-INF/mylabel-lang-addon.xml</addon-uri>
</language-config>
......
</zk>
Then, you can specify the JavaScript files to load with each ZK page in this XML file as follows.
<?xml version="1.0" encoding="UTF-8"?>
<language-addon>
<language-name>xul/html</language-name>
<javascript src="/mylabel.js" charset="UTF-8"/>
</language-addon>
The content of the JavaScript file, of course, could be anything you want. For example, if you want to customize the behavior of Label, the JavaScript file could be as follows:
zk.afterLoad("zul.wgt",function(){
old = zul.wgt.Label.prototype.setValue;
zul.wgt.Label.prototype.setValue = function (){
arguments[0]="lang-addon "+arguments[0];
old.apply(this,arguments);
}
});
Notice that it is important to use zk.afterLoad(String, Function) to specify the customization code, since ZK JavaScript packages are loaded only when required. In other words, the customization code has to wait until the package is loaded. In this example, we have to wait for the zul.wgt package being loaded to execute the customization code.
Define a New Widget Method
For example, in ZK 5.0 and Server+Client Fusion, we defined an update
function for listbox
<zk xmlns:w="http://www.zkoss.org/2005/zk/client">
....
<listbox id="list" rows="10" width="300px">
<attribute w:name="update"><![CDATA[
....
]]></attribute>
</listbox>
Define a DOM Attribute
[Since 5.0.3]
Sometimes we need to specify a DOM attribute that is not generated by a ZK widget. It can be done by use the client-attribute namespace: <cdoe>http://www.zkoss.org/2005/zk/client/attribute". For example, if you want to generate the onload attribute for the iframe component, then you can do as follows:
<iframe src="http://www.google.com" width="100%" height="300px"
xmlns:wa="http://www.zkoss.org/2005/zk/client/attribute"
wa:onload="alert(window.location.href)"/>
The generate DOM element will then have an attribute called onload
.
Specify a Different Widget Class
You could specify your own implementation instead of the default widget class (at the client) as follows.
<zk xmlns:w="http://www.zkoss.org/2005/zk/client">
...
<button w:use="foo.MyButton"/>
</zk>
where foo.MyButton
is a widget you implement. For example,
zk.$package("foo").MyButton = zk.$extends(zul.wgt.Button, {
setLabel: function (label) {
this.$supers("setLabel", arguments);
//do whatever you want
}
});
Watch': ZK Client Engine Event
To implement a ZK widget, traditional DOM events are not enough. Therefore, ZK defines extra widget related events like onHide
,onFloatUp
and system-level events such as watch. ZK provide its mechanism to fire and listen to watch.
<window xmlns:w="http://www.zkoss.org/2005/zk/client">
<button label="show" onClick="b1.setVisible(true);" />
<button label="hide" onClick="b1.setVisible(false);" />
<!--
onShow is not called when first time rendering.
It is called while setVisible="false", and then setVisible="true"
-->
<button label="if onShow" id="b1"
style="position:relative;zoom:1">
<attribute w:name="onShow">
alert("listened to onShow");
</attribute>
<attribute w:name="bind_">
function () { this.$bind_(); zWatch.listen({onShow: this});}
</attribute>
</button>
</window>
Use Third Party JavaScript Library
ZK 5.0 and jQuery part 2 demonstrates how to utilize jQuery UI Tools for low-level interaction, animation and more.
Listen to DOM event
For more sophisticated control, you can listen to DOM events. The following example demonstrates two different ways to handle the onblur
event.
<window title="listen dom event" border="normal"
xmlns:w="http://www.zkoss.org/2005/zk/client">
<textbox value="onBlur to alert" w:onBlur="alert('onBlur by zk')" />
<textbox value="onblur to alert">
<attribute w:name="bind_">
function () {
this.$bind_();
jq(this).bind('blur',function(event){alert('blurred by jquery')});
}
</attribute>
</textbox>
</window>
Animation
Please visit ZK Live Demo and search for "animations". The following is a simplified example.
<zk xmlns:w="http://www.zkoss.org/2005/zk/client">
<button label="slideDown"
w:onClick="jq(this.$f('t')).hide().slideDown()" />
<div id="t">
<button label="target" />
</div>
</zk>
- Since 5.0.2, there is an alternative way to look for a fellow:
this.$f().fellowId
Communicate to Server
zAu is an utility to communicate with the server. In other words, it handles AU requests and responses. The following example sends a customized onUser
event to the server.
<window>
<html onUser='l.value ="onUser "+org.zkoss.lang.Objects.toString(event.data)'><![CDATA[
<a href="javascript:;" onclick="zAu.send(new zk.Event(zk.Widget.$(this), 'onUser',[1,2]));">onUser with [1, 2]</a>
]]></html>
<label id="l"/>
</window>
Summary
The ability to do client side programming allows developers to easily access and control ZK widgets. ZK retains its server-centric philosophy for productivity but enhances the controllability at client side with this capability; making it just as customizable as any client centric framework. The possibilities are limiteless.
Download
I've created a project named zk-sample host on google code. The related sample code can be found on its repository.
See Also
- ZK5: Client Computing with ZUML
- ZK 5.0 and Server+Client Fusion
- ZK 5.0 and jQuery
- ZK 5.0 and jQuery part 2
- jq -- jQuery selector for ZK widget.
- Widget -- See the usage of $f(), $n(), bind_(), $()
- Client Side Actions -- Deprecated since ZK5
- Client Activity Watches -- onShow, onHide in ZK5
- JavaScript API -- Documentation for ZK JavaScript API.
- Customizing Error Box -- from Forum
- How to position image after label text on each tab of tabbox? -- from Forum, modify domContent_ is a good way to customize a little bit.
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |