Introduction
This article describe how to create helper tag by custom component to help programmer to do something easier/better.
NOTE:
This does not mean "this is a good way, follow this pattern"
Just show a possible way that you can give it a try and see if it makes the world better.
Result
Online demo:
http://screencast.com/t/gC2rGFg3KkuU
Program
index.zul
Contains a/button with very long url, also contains a/button/image/ with short url and specify parameters with custom helper component.
<zk>
<!-- Tested with ZK 6.5.2
test link available at wiki: http://en.wikipedia.org/wiki/Google_Chart_API
-->
<!-- basically you can write something as below,
now assume that you need to
find a typo
or
change some params...
-->
<div>
<a href="http://chart.apis.google.com/chart?chs=200x200&chdlp=b&chtt=Uberman&chdl=Asleep%7CAwake&chd=t:1,11,1,11,1,11,1,11,1,11,1,11&cht=p&chco=586F8E%7C7D858F"
target="blank">
open chart
</a>
</div>
<div>
<button href="http://chart.apis.google.com/chart?chs=200x200&chdlp=b&chtt=Uberman&chdl=Asleep%7CAwake&chd=t:1,11,1,11,1,11,1,11,1,11,1,11&cht=p&chco=586F8E%7C7D858F"
target="blank" label="open chart, too" />
</div>
<!-- or you can define a helper component to
make those params clear as below
to reduce server memory you can specify
stubonly="true" to helper tags
Of course this probably is not needed if
you load those params from DB/Java-Beans and
build link at server side
Just show a possibility that such kind of helper
can help you do some fast prototyping in zul page
without server side (AP level) support
And it is possible to change params dynamically so
probably will be useful when using it with MVVM
You can also define the helper tag as another component with
another name in lang-addon.xml, see index_defined.zul
-->
<div>
<a href="http://chart.apis.google.com/chart" target="blank">
also open chart
<div name="chs" value="200x200"
stubonly="true" use="helper.Param" />
<div name="chdlp" value="b"
stubonly="true" use="helper.Param" />
<div name="chtt" value="Uberman"
stubonly="true" use="helper.Param" />
<div name="chdl" value="Asleep%7CAwake"
stubonly="true" use="helper.Param" />
<div name="chd" value="t:1,11,1,11,1,11,1,11,1,11,1,11"
stubonly="true" use="helper.Param" />
<div name="cht" value="p"
stubonly="true" use="helper.Param" />
<div name="chco" value="586F8E%7C7D858F"
stubonly="true" use="helper.Param" />
</a>
</div>
<!-- for components that do not support child, you can
use give it an ID and specify the ID as target of param
-->
<div>
<button id="btn" label="still open chart" href="http://chart.apis.google.com/chart"
target="blank" />
<div name="chs" value="200x200"
target="btn"
stubonly="true" use="helper.Param" />
<div name="chdlp" value="b"
target="btn"
stubonly="true" use="helper.Param" />
<div name="chtt" value="Uberman"
target="btn"
stubonly="true" use="helper.Param" />
<div name="chdl" value="Asleep%7CAwake"
target="btn"
stubonly="true" use="helper.Param" />
<div name="chd" value="t:1,11,1,11,1,11,1,11,1,11,1,11"
target="btn"
stubonly="true" use="helper.Param" />
<div name="cht" value="p"
target="btn"
stubonly="true" use="helper.Param" />
<div name="chco" value="586F8E%7C7D858F"
target="btn"
stubonly="true" use="helper.Param" />
</div>
<div>
Display an image
<image id="img" src="http://chart.apis.google.com/chart" />
<div name="chs" value="200x200"
target="img"
stubonly="true" use="helper.Param" />
<div name="chdlp" value="b"
target="img"
stubonly="true" use="helper.Param" />
<div name="chtt" value="Uberman"
target="img"
stubonly="true" use="helper.Param" />
<div name="chdl" value="Asleep%7CAwake"
target="img"
stubonly="true" use="helper.Param" />
<div name="chd" value="t:1,11,1,11,1,11,1,11,1,11,1,11"
target="img"
id="dynaParam"
use="helper.Param" />
<div name="cht" value="p"
target="img"
stubonly="true" use="helper.Param" />
<div name="chco" value="586F8E%7C7D858F"
target="img"
stubonly="true" use="helper.Param" />
and change it dynamically
<combobox onSelect="dynaParam.setValue(self.getValue());">
<comboitem label="t:1,11,1,11,1,11,1,11,1,11,1,11" />
<comboitem label="t:2,10,2,10,2,10,2,10,2,10,2,10" />
</combobox>
</div>
</zk>
index_defined.zul
Similar to index.zul, just use the custom component with another name defined in lang-addon.xml.
<zk>
<!-- test link available at wiki: http://en.wikipedia.org/wiki/Google_Chart_API -->
<!-- Do the same as index.zul with
predefined param component.
-->
<div>
<a href="http://chart.apis.google.com/chart?chs=200x200&chdlp=b&chtt=Uberman&chdl=Asleep%7CAwake&chd=t:1,11,1,11,1,11,1,11,1,11,1,11&cht=p&chco=586F8E%7C7D858F"
target="blank">
open chart
</a>
</div>
<div>
<button href="http://chart.apis.google.com/chart?chs=200x200&chdlp=b&chtt=Uberman&chdl=Asleep%7CAwake&chd=t:1,11,1,11,1,11,1,11,1,11,1,11&cht=p&chco=586F8E%7C7D858F"
target="blank" label="open chart, too" />
</div>
<div>
<a href="http://chart.apis.google.com/chart" target="blank">
also open chart
<param name="chs" value="200x200"
stubonly="true" />
<param name="chdlp" value="b"
stubonly="true" />
<param name="chtt" value="Uberman"
stubonly="true" />
<param name="chdl" value="Asleep%7CAwake"
stubonly="true" />
<param name="chd" value="t:1,11,1,11,1,11,1,11,1,11,1,11"
stubonly="true" />
<param name="cht" value="p"
stubonly="true" />
<param name="chco" value="586F8E%7C7D858F"
stubonly="true" />
</a>
</div>
<div>
<button id="btn" label="still open chart" href="http://chart.apis.google.com/chart"
target="blank" />
<param name="chs" value="200x200"
target="btn"
stubonly="true" />
<param name="chdlp" value="b"
target="btn"
stubonly="true" />
<param name="chtt" value="Uberman"
target="btn"
stubonly="true" />
<param name="chdl" value="Asleep%7CAwake"
target="btn"
stubonly="true" />
<param name="chd" value="t:1,11,1,11,1,11,1,11,1,11,1,11"
target="btn"
stubonly="true" />
<param name="cht" value="p"
target="btn"
stubonly="true" />
<param name="chco" value="586F8E%7C7D858F"
target="btn"
stubonly="true" />
</div>
<div>
Display an image
<image id="img" src="http://chart.apis.google.com/chart" />
<param name="chs" value="200x200"
target="img"
stubonly="true" />
<param name="chdlp" value="b"
target="img"
stubonly="true" />
<param name="chtt" value="Uberman"
target="img"
stubonly="true" />
<param name="chdl" value="Asleep%7CAwake"
target="img"
stubonly="true" />
<param name="chd" value="t:1,11,1,11,1,11,1,11,1,11,1,11"
target="img"
id="dynaParam"
use="helper.Param" />
<param name="cht" value="p"
target="img"
stubonly="true" />
<param name="chco" value="586F8E%7C7D858F"
target="img"
stubonly="true" />
and change it dynamically
<combobox onSelect="dynaParam.setValue(self.getValue());">
<comboitem label="t:1,11,1,11,1,11,1,11,1,11,1,11" />
<comboitem label="t:2,10,2,10,2,10,2,10,2,10,2,10" />
</combobox>
</div>
</zk>
Param.java
The implementation of custom helper component,
package helper;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.A;
import org.zkoss.zul.Button;
import org.zkoss.zul.Div;
import org.zkoss.zul.Image;
/** Tested with ZK 6.5.2
*
* @author benbai123
*
*/
public class Param extends Div {
private static final long serialVersionUID = 8842930664701238051L;
private String _name = "";
private String _value = "";
private String _target;
private String _oldValue = "";
@SuppressWarnings({ "unchecked", "rawtypes" })
public Param () {
// update target url while created
addEventListener(Events.ON_CREATE, new EventListener () {
public void onEvent (Event event) {
updateTargetUrl();
}
});
// do not output any html
setWidgetOverride ("redraw", "function (out) {}");
}
// setters
public void setTarget (String target) {
_target = target;
}
public void setName (String name) {
if (name == null) {
name = "";
}
_name = name;
}
public void setValue (String value) {
if (value == null) {
value = "";
}
_value = value;
updateTargetUrl();
}
private void updateTargetUrl () {
if (!_name.isEmpty() && !_value.isEmpty()) {
Component target = findTarget();
if (target instanceof A) {
A link = (A)target;
String url = updateUrl(link.getHref());
link.setHref(url);
} else if (target instanceof Button) {
Button btn = (Button)target;
String url = updateUrl(btn.getHref());
btn.setHref(url);
} else if (target instanceof Image) {
Image img = (Image)target;
String url = updateUrl(img.getSrc());
img.setSrc(url);
}
}
}
// try to find target to update
private Component findTarget () {
if (_target != null && !_target.isEmpty()) {
return getParent().getFellowIfAny(_target);
} else if (getParent() instanceof A) {
return getParent();
}
return null;
}
// update url with param/value
private String updateUrl (String url) {
String value;
if (url.indexOf("?") == -1) {
url += "?";
} else {
url += "&";
}
value = _name + "=" + _value;
// replace old value or append new value at tail
if (!_oldValue.isEmpty()) {
url.replace(_oldValue, value);
} else {
url += value;
}
return url;
}
}
lang-addon.xml
Define 'param' component.
<!-- Tested with ZK 6.5.2
Define param component
-->
<language-addon>
<addon-name>param</addon-name>
<language-name>xul/html</language-name>
<!-- It specifies what language addons this addon
depends on. If specified, this addon will be
parsed after all the specified addons are parsed -->
<depends>zul</depends>
<!-- define param -->
<component>
<component-name>param</component-name>
<!-- extends div and change java class -->
<extends>div</extends>
<component-class>helper.Param</component-class>
</component>
</language-addon>
zk.xml
Load lang-addon.xml.
<zk>
<!-- load lang-addon.xml -->
<language-config>
<addon-uri>/WEB-INF/lang-addon.xml</addon-uri>
</language-config>
</zk>
References
Language Definition
http://books.zkoss.org/wiki/ZK_Client-side_Reference/Language_Definition
The language-config Element
http://books.zkoss.org/wiki/ZK_Configuration_Reference/zk.xml/The_language-config_Element
Download
Full project at github
https://github.com/benbai123/ZK_Practice/tree/master/Components/projects/Components_Customization/ParamTagForUrl
Demo Flash
No comments:
Post a Comment