Client Side Programming"
(14 intermediate revisions by 5 users not shown) | |||
Line 9: | Line 9: | ||
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 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 <ref>For ZK 3.6 and prior, please use [http:// | + | In order to execute application-specific code at the client, ZK introduces the concept of the Client Namespace <ref>For ZK 3.6 and prior, please use [http://docs.zkoss.org/wiki/Client_Side_Actions Client Side Actions] instead.</ref>. With the Client Namespace, developers are able to listen to any client-side event, override ZK methods and execute any custom client-side code. |
---- | ---- | ||
Line 79: | Line 79: | ||
In an event listener, you can access the widget by using <code>this</code> as shown above. In addition, you can access the event (an instance of <javadoc directory="jsdoc">zk.Event</javadoc>) by using <code>event</code>. | In an event listener, you can access the widget by using <code>this</code> as shown above. In addition, you can access the event (an instance of <javadoc directory="jsdoc">zk.Event</javadoc>) by using <code>event</code>. | ||
− | You can find more detail at [[ZK Client-side Reference] | + | You can find more detail at [[ZK Client-side Reference]]. |
===Override a Widget Method=== | ===Override a Widget Method=== | ||
Line 100: | Line 100: | ||
</source> | </source> | ||
− | You can find more detail at [[ZK Client-side Reference]] and [ | + | You can find more detail at [[ZK Client-side Reference]] and [[ZK_Client-side_Reference/General_Control|ZK Client-side Reference: General Control]]. |
EL expressions is allowed <ref>EL expressions are allowed since ZK 5.0.2</ref><ref> EL is evaluated when rendering a page. In other words, it is evaluated before sending the JavaScript code to the client for execution later.</ref> 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. | EL expressions is allowed <ref>EL expressions are allowed since ZK 5.0.2</ref><ref> EL is evaluated when rendering a page. In other words, it is evaluated before sending the JavaScript code to the client for execution later.</ref> 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. | ||
Line 117: | Line 117: | ||
<label id="labeltwo" value="label two"/> | <label id="labeltwo" value="label two"/> | ||
<script defer="true"> | <script defer="true"> | ||
− | old = zul.wgt.Label.prototype.setValue; | + | old = zul.wgt.Label.prototype.setValue; |
zul.wgt.Label.prototype.setValue = function (){ | zul.wgt.Label.prototype.setValue = function (){ | ||
arguments[0]="modified prototype"+arguments[0]; | arguments[0]="modified prototype"+arguments[0]; | ||
old.apply(this,arguments); | old.apply(this,arguments); | ||
− | } | + | } |
</script> | </script> | ||
− | <button label="change" onClick='labelone.setValue((new Date()).toString());labeltwo.setValue((new Date()).toString());'/> | + | <button label="change" onClick='labelone.setValue((new Date()).toString());labeltwo.setValue((new Date()).toString());'/> |
+ | </window> | ||
+ | </source> | ||
+ | |||
+ | [Since 5.0.2] | ||
+ | |||
+ | As of ZK 5.0.2, you can also use [http://www.zkoss.org/javadoc/latest/jsdoc/_global_/zk.html#override%28java.lang.Object,%20_global_.String,%20java.lang.Object%29 zk.override()] to override the method: | ||
+ | <source lang="xml"> | ||
+ | <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"> | ||
+ | zk.override(zul.wgt.Label.prototype, "setValue", function () { | ||
+ | arguments[0] = "modified prototype "+ arguments[0]; | ||
+ | this.$setValue.apply(this, arguments); | ||
+ | }); | ||
+ | </script> | ||
+ | <button label="change" onClick='labelone.setValue((new Date()).toString());labeltwo.setValue((new Date()).toString());'/> | ||
</window> | </window> | ||
</source> | </source> | ||
Line 183: | Line 200: | ||
[Since 5.0.3] | [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: < | + | 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: <code>http://www.zkoss.org/2005/zk/client/attribute</code>. For example, if you want to generate the <code>onload</code> attribute for the iframe component, then you can do as follows: |
<source lang="xml"> | <source lang="xml"> | ||
Line 215: | Line 232: | ||
</source> | </source> | ||
− | === ''Watch | + | <!-- wrong content commented by Jumper 04/10/2014 |
− | To implement a ZK widget, traditional DOM events are not enough. Therefore, ZK defines extra widget related events like <code>onHide</code>,<code>onFloatUp</code> and system-level events such as '''watch'''. ZK provide its mechanism to fire and listen to '''watch'''. | + | === ''Watch'': ZK Client Engine Event === |
+ | To implement a ZK widget, traditional DOM events are not enough. Therefore, ZK defines extra widget related events like <code>onHide</code>, <code>onShow</code>, <code>onFloatUp</code> and system-level events such as '''watch'''. ZK provide its mechanism to fire and listen to '''watch'''. | ||
<source lang="xml"> | <source lang="xml"> | ||
<window xmlns:w="http://www.zkoss.org/2005/zk/client"> | <window xmlns:w="http://www.zkoss.org/2005/zk/client"> | ||
<button label="show" onClick="b1.setVisible(true);" /> | <button label="show" onClick="b1.setVisible(true);" /> | ||
<button label="hide" onClick="b1.setVisible(false);" /> | <button label="hide" onClick="b1.setVisible(false);" /> | ||
− | + | <!-- | |
onShow is not called when first time rendering. | onShow is not called when first time rendering. | ||
It is called while setVisible="false", and then setVisible="true" | It is called while setVisible="false", and then setVisible="true" | ||
− | -- | + | --> |
<button label="if onShow" id="b1" | <button label="if onShow" id="b1" | ||
style="position:relative;zoom:1"> | style="position:relative;zoom:1"> | ||
<attribute w:name="onShow"> | <attribute w:name="onShow"> | ||
alert("listened to onShow"); | alert("listened to onShow"); | ||
− | |||
− | |||
− | |||
</attribute> | </attribute> | ||
</button> | </button> | ||
Line 237: | Line 252: | ||
</source> | </source> | ||
<references/> | <references/> | ||
+ | --> | ||
=== Use Third Party JavaScript Library === | === Use Third Party JavaScript Library === | ||
Line 250: | Line 266: | ||
<attribute w:name="bind_"> | <attribute w:name="bind_"> | ||
function () { | function () { | ||
− | this.$bind_(); | + | this.$bind_.apply(this,arguments); |
jq(this).bind('blur',function(event){alert('blurred by jquery')}); | jq(this).bind('blur',function(event){alert('blurred by jquery')}); | ||
} | } | ||
Line 299: | Line 315: | ||
#[[Small_Talks/2009/July/ZK_5.0_and_jQuery|ZK 5.0 and jQuery]] | #[[Small_Talks/2009/July/ZK_5.0_and_jQuery|ZK 5.0 and jQuery]] | ||
#[[Small_Talks/2009/July/ZK_5.0_and_jQuery_part_2|ZK 5.0 and jQuery part 2]] | #[[Small_Talks/2009/July/ZK_5.0_and_jQuery_part_2|ZK 5.0 and jQuery part 2]] | ||
− | |||
#<javadoc directory="jsdoc">_global_.jq</javadoc> -- jQuery selector for ZK widget. | #<javadoc directory="jsdoc">_global_.jq</javadoc> -- jQuery selector for ZK widget. | ||
#<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_(), $() | ||
− | + | #[[ZK Client-side Reference/Notifications/Client Activity Watches|Client Activity Watches]] -- onShow, onHide in ZK5 | |
− | #[[ZK Client-side Reference/ | ||
#[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 |
Latest revision as of 03:47, 11 November 2015
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 ZK Client-side Reference.
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 ZK Client-side Reference and ZK Client-side Reference: General Control.
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>
[Since 5.0.2]
As of ZK 5.0.2, you can also use zk.override() to override the method:
<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">
zk.override(zul.wgt.Label.prototype, "setValue", function () {
arguments[0] = "modified prototype "+ arguments[0];
this.$setValue.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: 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
}
});
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_.apply(this,arguments);
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
- 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 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. |