-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I'm trying to create my first custom zk component - 'ListheadExt' - a sub class of the 'Listhead'. The purpose of the new custom component is to support the run time generation of dynamic list box columns, like this:
<listbox model="@load(vm.users)">
<listheadext dynamic="@load(vm.dynamicColumns)">
<listheader label="ID" sort="auto" />
<listheader label="Surname" sort="auto" />
<listheader label="First name" sort="auto" />
<template name="dynamic" var="c">
<listheader label="@load(c.title)" sort="auto" />
</template>
</listheadext>
<template name="model" var="u">
<listitem>
<listcell label="@load(u.userID)" />
<listcell label="@load(u.surname)" />
<listcell label="@load(u.firstName)" />
</listitem>
</template>
</listbox>
The 'ListheadExt' component has a new 'dynamic' attribute that holds an array of beans. I then use a template that uses the 'dynamic' array to generate a set of variable extra 'listheader' entries.
My Java class is defined as:
public class ListheadExt extends Listhead {
private static final long serialVersionUID = 4873341159574624409L;
private ArrayList<?> fDynamic;
@Override
protected void renderProperties(ContentRenderer renderer) throws IOException {
super.renderProperties(renderer);
render(renderer, "dynamic", fDynamic);
}
public ListheadExt() {
}
public ArrayList<?> getDynamic() {
return fDynamic;
}
public void setDynamic(ArrayList<?> anArray) {
fDynamic = anArray;
if (fDynamic != anArray) {
fDynamic = anArray;
smartUpdate("dynamic",anArray);
}
}
}
My matching widget is defined as:
(function () {
com.eis.zk.listbox.ListheadExt = zk.$extends(zul.db.Datebox, {
_dynamic : '', // default value
getDynamic : function() {
return this._dynamic;
},
setDynamic : function(value) {
if (this._dynamic != value) {
this._dynamic = value;
if (this.desktop)
this.$n().innerHTML = zUtl.encodeXML(value);
}
}
});
})();
The addon xml file is:
<language-addon>
<addon-name>listheadext</addon-name>
<language-name>xul/html</language-name>
<depends>zul</depends>
<component>
<component-name>listheadext</component-name>
<component-class>com.eis.zk.listbox.ListheadExt</component-class>
<extends>listhead</extends>
<widget-class>com.eis.zk.listbox.ListheadExt</widget-class>
</component>
</language-addon>
My zk.xml file is:
<zk>
<device-config>
<device-type>ajax</device-type>
<timeout-uri>/timeout.zul</timeout-uri><!-- An empty URL can cause the
browser to reload the same URL -->
</device-config>
<language-config>
<addon-uri>/WEB-INF/listheadext-addon.xml</addon-uri>
</language-config>
</zk>
If I run my test app I get an error:
SEVERE: Servlet.service() for servlet zkLoader threw exception org.zkoss.zk.ui.UiException: Property 'dynamic' not found on type org.zkoss.zul.Listhead at [file:/C:/Users/Ian/Workspaces/MyEclipse%2010/.metadata/.me_tcat/webapps/TemplateColumnsTest01/index.zul, line:10] at org.zkoss.bind.impl.MiscUtil.mergeExceptionInfo(MiscUtil.java:175) at org.zkoss.bind.impl.BindEvaluatorXImpl.setValue(BindEvaluatorXImpl.java:58) at org.zkoss.bind.impl.LoadPropertyBindingImpl.load(LoadPropertyBindingImpl.java:91) at org.zkoss.bind.impl.PropertyBindingHandler.doLoadBinding(PropertyBindingHandler.java:171) at org.zkoss.bind.impl.PropertyBindingHandler.doLoad(PropertyBindingHandler.java:372) at org.zkoss.bind.impl.BinderImpl.loadComponentProperties0(BinderImpl.java:2069) at org.zkoss.bind.impl.BinderImpl.loadComponent0(BinderImpl.java:2046) at org.zkoss.bind.impl.BinderImpl.loadComponent0(BinderImpl.java:2049) at org.zkoss.bind.impl.BinderImpl.loadComponent0(BinderImpl.java:2049) at org.zkoss.bind.impl.BinderImpl.loadComponent0(BinderImpl.java:2049) at org.zkoss.bind.impl.BinderImpl.loadComponent(BinderImpl.java:2037) at org.zkoss.bind.BindComposer$BinderKeeper$Loader.load(BindComposer.java:486) at org.zkoss.bind.BindComposer$BinderKeeper.loadComponentForAllBinders(BindComposer.java:468) at org.zkoss.bind.BindComposer.doAfterCompose(BindComposer.java:177) at org.zkoss.zk.ui.impl.UiEngineImpl.doAfterCompose(UiEngineImpl.java:537) at org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:832) at org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:778) at org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:687) at org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:651) at org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage0(UiEngineImpl.java:401) at org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage(UiEngineImpl.java:316) at org.zkoss.zk.ui.http.DHtmlLayoutServlet.process(DHtmlLayoutServlet.java:215) at org.zkoss.zk.ui.http.DHtmlLayoutServlet.doGet(DHtmlLayoutServlet.java:136) at javax.servlet.http.HttpServlet.service(HttpServlet.java:690) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Thread.java:619)
Any ideas?
Hi, you have to define the property "dynamic" in lang-addon.xml file, then it can be used in zkbind. Please refer to the document.
OK, I've updated the addon.xml file to include the annotation definition, as shown below. See:
<language-addon> <addon-name>listheadext</addon-name> <language-name>xul/html</language-name>
<depends>zul</depends>
<component>
<component-name>listheadext</component-name>
<component-class>com.eis.zk.listbox.ListheadExt</component-class>
<extends>listhead</extends>
<annotation>
<annotation-name>ZKBIND</annotation-name>
<property-name>dynamic</property-name>
<attribute>
<attribute-name>ACCESS</attribute-name>
<attribute-value>both</attribute-value>
</attribute>
<attribute>
<attribute-name>LOAD_REPLACEMENT</attribute-name>
<attribute-value>dynamic</attribute-value>
</attribute>
<attribute>
<attribute-name>LOAD_TYPE</attribute-name>
<attribute-value>java.util.ArrayList</attribute-value>
</attribute>
</annotation>
<widget-class>com.eis.zk.listbox.ListheadExt</widget-class>
</component>
</language-addon>
Now when I run the test web app the ZUL appears but just hangs, with the 'processing..." popup box appearing.
In the Java class my property is...
private ArrayList<?> fDynamic;
Is this supported by the JavaScript side?
Any suggestions?
I noticed that if I comment out the template that uses the 'listheadext' dynamic property and then even remove the 'dynamic' property so that the ZUL looks like...
<listbox model="@load(vm.users)">
<listheadext>
<listheader label="ID" sort="auto" />
<listheader label="Surname" sort="auto" />
<listheader label="First name" sort="auto" />
<!--
<template name="dynamic" var="c">
<listheader label="@load(c.title)" sort="auto" />
</template>
-->
</listheadext>
<template name="model" var="u">
<listitem>
<listcell label="@load(u.userID)" />
<listcell label="@load(u.surname)" />
<listcell label="@load(u.firstName)" />
</listitem>
</template>
</listbox>
... when I run the app it still hangs. Any suggestions?
If I'm deriving a custom component from an existing component do I need to implement any rendering code in the new js file?
Thanks for the various helpers so far, but I still can't get my 'ListheadExt' custom component to display.
In order to prove basics I've trimmed by ZUL file back to a point where all I have is 'ListheadExt' replacing the normal 'Listhead' in a standard listbox tag construction. Even this doesn't work, all I get in the ZUL file opening but with displaying hanging with the 'processing...' popup showing.
To recap what I've defined so far...
The zul file...
<window title="Hello World!!" border="normal" width="300px" apply="org.zkoss.bind.BindComposer" viewmodel="@id('vm') @init('com.eis.zk.test.listbox.DynamicListboxVM')">
<vlayout>
<listbox model="@load(vm.users)">
<listheadext>
<listheader label="ID" sort="auto" />
<listheader label="Surname" sort="auto" />
<listheader label="First name" sort="auto" />
</listheadext>
<template name="model" var="u">
<listitem>
<listcell label="@load(u.userID)" />
<listcell label="@load(u.surname)" />
<listcell label="@load(u.firstName)" />
</listitem>
</template>
</listbox>
</vlayout>
</window>
The java file...
public class ListheadExt extends Listhead {
private static final long serialVersionUID = 4873341159574624409L;
private Collection<?> fDynamic;
@Override
protected void renderProperties(ContentRenderer renderer) throws IOException {
super.renderProperties(renderer);
render(renderer, "dynamic", fDynamic);
}
public ListheadExt() {
System.out.println("ListheadExt constructor");
}
public Collection<?> getDynamic() {
return fDynamic;
}
public void setDynamic(Collection<?> anArray) {
fDynamic = anArray;
if (fDynamic != anArray) {
fDynamic = anArray;
smartUpdate("dynamic",anArray);
}
}
}
The js file...
(function () { com.eis.zk.listbox.ListheadExt = zk.$extends(zul.sel.Listhead, {
_dynamic : null,
getDynamic : function() {
return this._dynamic;
},
setDynamic : function(value) {
if (this._dynamic != value) {
this._dynamic = value;
if (this.desktop)
this.$n().innerHTML = zUtl.encodeXML(value);
}
}
});
})();
The js mold file...
(function (out) { out.push('<span', this.domattrs_(),="" '="">', this.getValue(), ''); } )();
The addon.xml file...
<language-addon> <addon-name>listheadext</addon-name> <language-name>xul/html</language-name>
<depends>zul</depends>
<component>
<component-name>listheadext</component-name>
<component-class>com.eis.zk.listbox.ListheadExt</component-class>
<extends>listhead</extends>
<annotation>
<annotation-name>ZKBIND</annotation-name>
<property-name>dynamic</property-name>
<attribute>
<attribute-name>ACCESS</attribute-name>
<attribute-value>load</attribute-value>
</attribute>
<attribute>
<attribute-name>LOAD_REPLACEMENT</attribute-name>
<attribute-value>dynamic</attribute-value>
</attribute>
<attribute>
<attribute-name>LOAD_TYPE</attribute-name>
<attribute-value>java.util.Collection</attribute-value>
</attribute>
</annotation>
<widget-class>com.eis.zk.listbox.ListheadExt</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>mold/ListheadExt.js</mold-uri>
</mold>
</component>
</language-addon>
The wpd file...
package name="com.eis.zk.listbox" language="xul/html" depends="zul.sel"> <widget name="ListheadExt"/> </package>
Any helpers?
Hi, I modified your mold js file as follows, then test with simple zul without MVVM and it works fine. Also did you put ListheadExt.js file under "web/js" folder? Please double check the component structure with the document reference.
Test ZUL
<listbox>
<listheadext>
<listheader label="ID" sort="auto" />
<listheader label="Surname" sort="auto" />
<listheader label="First name" sort="auto" />
</listheadext>
<listitem>
<listcell label="ID 1" />
<listcell label="Surname 1" />
<listcell label="first name 1" />
</listitem>
<listitem>
<listcell label="ID 2" />
<listcell label="Surname 2" />
<listcell label="first name 2" />
</listitem>
</listbox>
mold.js
function (out) {
out.push('<span', this.domattrs_(), '>', this.getValue(), '</span>');
}
Asked: 2013-06-04 07:09:02 +0800
Seen: 186 times
Last updated: Jun 07 '13
composite component help [closed]
EL in a forEach @command not working?
Different template for each grid row
Cardlayout animation is broken
Grid RowRender slow using 6.5.1 and sizable=true
setVisible(false), component will load or not
Decimalbox and doublebox value rounded on iPad
history management with page status