Widget Customization"
(Created page with '{{ZKDevelopersReferencePageHeader}} =Version History= {{LastUpdated}} {| border='1px' | width="100%" ! Version !! Date !! Content |- | | | |} {{ZKDeveloper…') |
|||
Line 1: | Line 1: | ||
{{ZKDevelopersReferencePageHeader}} | {{ZKDevelopersReferencePageHeader}} | ||
+ | |||
+ | =Override Widget's Default Behavior= | ||
+ | |||
+ | There are many ways to override the default behavior of widgets and even ZK Client Engine. JavaScript is a dynamic language and you could override almost any method you want. | ||
+ | |||
+ | ==Override a Widget Method== | ||
+ | |||
+ | For example, suppose we want to change the CSS style of a label when its value is changed, then we might have the code as follows. | ||
+ | |||
+ | <source lang="xml"> | ||
+ | <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> | ||
+ | </source> | ||
+ | |||
+ | where | ||
+ | |||
+ | * We specify [[ZUML Reference/ZUML/Namespaces/Client|client namespace]] to the <code>setValue</code> attribute to indicate it is the method to override | ||
+ | * The content of the attribute is a complete function definition of the method, including <code>function ()</code> | ||
+ | * You can access the widget by <code>this</code> in the function | ||
+ | * You can access the original method by <code>this.$xxx</code>, where xxx is the method name being overridden. If the method doesn't exist, it is null. | ||
+ | * To retrieve another widget, use <code>this.$f('anotherWidgetId')</code> or other methods as described in the previous section | ||
+ | * You can specify EL expressions<ref>EL expressions are allowed since ZK 5.0.2</ref> in the content of the attribute, such as | ||
+ | |||
+ | <source lang="javascript"> | ||
+ | w:setValue='function (value) { this.$setValue(value + "${whatever}")}'; | ||
+ | </source> | ||
+ | |||
+ | Notice EL expressions are evaluated at the server before sent back to the client. Thus, you could any Java class or variables in EL expressions. | ||
+ | |||
+ | <blockquote> | ||
+ | ---- | ||
+ | <references/> | ||
+ | </blockquote> | ||
+ | |||
+ | ==Override a Default Widget Method== | ||
+ | |||
+ | In previous section, we showed how to override method of a particular widget we declared. However, it only affects the behavior of a particular instance. If you want to modify the behavior of all instances of a widget class, you have to override the method in <code>prototype</code><ref>For more information about JavaScript's prototype, please refer to [http://www.packtpub.com/article/using-prototype-property-in-javascript Using Prototype Property in JavaScript] and [http://www.w3schools.com/jsref/jsref_prototype_math.asp JavaScript prototype Property]</ref>. | ||
+ | |||
+ | For example, | ||
+ | |||
+ | <source lang="xml" high="5"> | ||
+ | <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"> | ||
+ | var oldSV = zul.wgt.Label.prototype.setValue; | ||
+ | zul.wgt.Label.prototype.setValue = function (){ | ||
+ | arguments[0]="modified prototype"+arguments[0]; | ||
+ | oldSV.apply(this, arguments); | ||
+ | } | ||
+ | </script> | ||
+ | <button label="change" onClick="labelone.setValue((new Date()).toString()); | ||
+ | labeltwo.setValue((new Date()).toString());"/> | ||
+ | </window> | ||
+ | </source> | ||
+ | |||
+ | where we assign a new method to <code>zul.wgt.Label.prototype.setValue</code>. Since it is <code>prototype</code>, the setValue method of all instances are modified. | ||
+ | |||
+ | <blockquote> | ||
+ | ---- | ||
+ | <references/> | ||
+ | </blockquote> | ||
+ | |||
+ | ==Override a Widget Field== | ||
+ | |||
+ | You can override a method or a field no matter it exists or not. For example, it is easy to pass the application-specific data to the client, such as | ||
+ | |||
+ | <source lang="javascript"> | ||
+ | <label value="hello" w:myval="'${param.foo}'"/> | ||
+ | </source> | ||
+ | |||
+ | Notice that the content of the attribute must be a valid JavaScript snippet. To specify a string (as shown above), you have to enclose it with ' or " if you want to pass a string. It also means you can pass anything, such as <code>new Date()</code>. | ||
+ | |||
+ | ==== Override a Widget Method in Java ==== | ||
+ | |||
+ | In additions to ZUML, you could override a Widget method or field by use of <javadoc method="setWidgetMethod(java.lang.String, java.lang.String)" type="interface">org.zkoss.zk.ui.Component</javadoc> at the server. For example, | ||
+ | |||
+ | <source lang="java"> | ||
+ | label.setWidgetOverride("setValue", | ||
+ | "function (value) {this.$setValue('overloaded setValue');}"); | ||
+ | </source> | ||
+ | |||
+ | =Specify Your Own Widget Class= | ||
+ | |||
+ | You could specify your own implementation instead of the default widget class (at the client) as follows. | ||
+ | |||
+ | <source lang="xml"> | ||
+ | <zk xmlns:w="http://www.zkoss.org/2005/zk/client"> | ||
+ | ... | ||
+ | <button w:use="foo.MyButton"/> | ||
+ | </zk> | ||
+ | </source> | ||
+ | |||
+ | where <code>foo.MyButton</code> is a widget you implement. For example, | ||
+ | |||
+ | <source lang="javascript"> | ||
+ | zk.afterLoad("zul.wgt", function () { | ||
+ | zk.$package("foo").MyButton = zk.$extends(zul.wgt.Button, { | ||
+ | setLabel: function (label) { | ||
+ | this.$supers("setLabel", arguments); | ||
+ | //do whatever you want | ||
+ | } | ||
+ | }); | ||
+ | }); | ||
+ | </source> | ||
+ | |||
+ | Notice that <javadoc directory="jsdoc" method="afterLoad(_global_.String, _global_.Function)">_global_.zk</javadoc> is used to defer the declaration of <code>foo.MyButton</code> until <code>zul.wgt</code> has been loaded. | ||
+ | |||
+ | ==Load Additional JavaScript Files== | ||
+ | |||
+ | You could use <javadoc>org.zkoss.zul.Script</javadoc>, HTML SCRIPT tag or [[ZUML Reference/ZUML/Processing Instructions/script|script]] to load additional JavaScript files. Please refer to [[http://books.zkoss.org/wiki/ZK_Component_Reference/Essential_Components/Script|script]] for more information. | ||
+ | |||
+ | = The Client-Attribute Namespace = | ||
+ | |||
+ | [since 5.0.3] | ||
+ | |||
+ | The [[ZUML Reference/ZUML/Namespaces/Client Attribute|client-attribute namespace (<nowiki>http://www.zkoss.org/2005/zk/client/attribute</nowiki>; shortcut, <code>client/attribute</code>) is used to specify additional DOM attributes that are not generated by widgets. In other words, whatever attributes you specify with the client-attribute namespace will be generated directly to the browser's DOM tree. Whether it is meaningful, it is really up to the browser -- ZK does not handle or filter it at all. | ||
+ | |||
+ | For example, you want to listen to the <code>onload</code> event, and then you can do as follows. | ||
+ | |||
+ | <source lang="xml"> | ||
+ | <iframe src="http://www.google.com" width="100%" height="300px" | ||
+ | xmlns:ca="client/attribute" ca:onload="do_whater_you_want()"/> | ||
+ | </source> | ||
+ | |||
+ | If the attribute contains colon or other special characters, you can use the <code>attribute</code> element as follows. | ||
+ | |||
+ | <source lang="xml"> | ||
+ | <div xmlns:ca="http://www.zkoss.org/2005/zk/client/attribute"> | ||
+ | <attribute ca:name="ns:whatever"> | ||
+ | whatever_value_you_want | ||
+ | </attribute> | ||
+ | </div> | ||
+ | </source> | ||
+ | |||
+ | The other use of the client-attribute namespace is to specify attributes that are available only to certain browsers, such as accessibility and [http://www.section508.gov/index.cfm?FuseAction=Content&ID=12#Web Section 508]. | ||
=Version History= | =Version History= |
Revision as of 03:15, 1 December 2010
Override Widget's Default Behavior
There are many ways to override the default behavior of widgets and even ZK Client Engine. JavaScript is a dynamic language and you could override almost any method you want.
Override a Widget Method
For example, suppose we want to change the CSS style of a label when its value is changed, then we might have the code as follows.
<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>
where
- We specify client namespace to the
setValue
attribute to indicate it is the method to override - The content of the attribute is a complete function definition of the method, including
function ()
- You can access the widget by
this
in the function - You can access the original method by
this.$xxx
, where xxx is the method name being overridden. If the method doesn't exist, it is null. - To retrieve another widget, use
this.$f('anotherWidgetId')
or other methods as described in the previous section - You can specify EL expressions[1] in the content of the attribute, such as
w:setValue='function (value) { this.$setValue(value + "${whatever}")}';
Notice EL expressions are evaluated at the server before sent back to the client. Thus, you could any Java class or variables in EL expressions.
- ↑ EL expressions are allowed since ZK 5.0.2
Override a Default Widget Method
In previous section, we showed how to override method of a particular widget we declared. However, it only affects the behavior of a particular instance. If you want to modify the behavior of all instances of a widget class, you have to override the method in prototype
[1].
For example,
<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">
var oldSV = zul.wgt.Label.prototype.setValue;
zul.wgt.Label.prototype.setValue = function (){
arguments[0]="modified prototype"+arguments[0];
oldSV.apply(this, arguments);
}
</script>
<button label="change" onClick="labelone.setValue((new Date()).toString());
labeltwo.setValue((new Date()).toString());"/>
</window>
where we assign a new method to zul.wgt.Label.prototype.setValue
. Since it is prototype
, the setValue method of all instances are modified.
- ↑ For more information about JavaScript's prototype, please refer to Using Prototype Property in JavaScript and JavaScript prototype Property
Override a Widget Field
You can override a method or a field no matter it exists or not. For example, it is easy to pass the application-specific data to the client, such as
<label value="hello" w:myval="'${param.foo}'"/>
Notice that the content of the attribute must be a valid JavaScript snippet. To specify a string (as shown above), you have to enclose it with ' or " if you want to pass a string. It also means you can pass anything, such as new Date()
.
Override a Widget Method in Java
In additions to ZUML, you could override a Widget method or field by use of Component.setWidgetMethod(String, String) at the server. For example,
label.setWidgetOverride("setValue",
"function (value) {this.$setValue('overloaded setValue');}");
Specify Your Own 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.afterLoad("zul.wgt", function () {
zk.$package("foo").MyButton = zk.$extends(zul.wgt.Button, {
setLabel: function (label) {
this.$supers("setLabel", arguments);
//do whatever you want
}
});
});
Notice that zk.afterLoad(String, Function) is used to defer the declaration of foo.MyButton
until zul.wgt
has been loaded.
Load Additional JavaScript Files
You could use Script, HTML SCRIPT tag or script to load additional JavaScript files. Please refer to [[1]] for more information.
The Client-Attribute Namespace
[since 5.0.3]
The [[ZUML Reference/ZUML/Namespaces/Client Attribute|client-attribute namespace (http://www.zkoss.org/2005/zk/client/attribute; shortcut, client/attribute
) is used to specify additional DOM attributes that are not generated by widgets. In other words, whatever attributes you specify with the client-attribute namespace will be generated directly to the browser's DOM tree. Whether it is meaningful, it is really up to the browser -- ZK does not handle or filter it at all.
For example, you want to listen to the onload
event, and then you can do as follows.
<iframe src="http://www.google.com" width="100%" height="300px"
xmlns:ca="client/attribute" ca:onload="do_whater_you_want()"/>
If the attribute contains colon or other special characters, you can use the attribute
element as follows.
<div xmlns:ca="http://www.zkoss.org/2005/zk/client/attribute">
<attribute ca:name="ns:whatever">
whatever_value_you_want
</attribute>
</div>
The other use of the client-attribute namespace is to specify attributes that are available only to certain browsers, such as accessibility and Section 508.
Version History
Version | Date | Content |
---|---|---|