-
FEATURED COMPONENTS
First time here? Check out the FAQ!
This is an extension of my earlier question about building a custom component that derives from an existing ZK component. I've read the ZK docs, also some blogs but cannot get this damn thing to work. I'm trying to build a custom 'ListheadExt' component that derives from 'Listhead'
My demo app ZK is:
<?page title="Auto Generated index.zul"?>
<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>
<listheadext>
<listheader label="ID" sort="auto" />
<listheader label="Surname" sort="auto" />
<listheader label="First name" sort="auto" />
</listheadext>
<listitem>
<listcell label="5" />
<listcell label="Smith" />
<listcell label="Fred" />
</listitem>
<listitem>
<listcell label="7" />
<listcell label="Jones" />
<listcell label="Mike" />
</listitem>
</listbox>
</vlayout>
</window>
When I run my test app the web page simply hangs when the ZK window is created with the 'Processing...' pop up appearing and staying there.
When I try to debug the web page under IE I get the following errors appearing in the console section, see:
HTML1524: Invalid DOCTYPE. The shortest valid doctype is "<!DOCTYPE html>".
TemplateColumnsTest01, line 1 character 1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
This is the source of the test web page...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<title>Auto Generated index.zul</title>
<link rel="stylesheet" type="text/css" href="/TemplateColumnsTest01/zkau/web/439b83ff/zul/css/zk.wcs"/>
<script type="text/javascript" src="/TemplateColumnsTest01/zkau/web/439b83ff/js/zk.wpd" charset="UTF-8"></script>
<script type="text/javascript" src="/TemplateColumnsTest01/zkau/web/439b83ff/js/zul.lang.wpd" charset="UTF-8"></script>
<!-- ZK 6.5.2 2013032614 -->
</head>
<body>
<div id="jBKQ_" class="z-temp"><div id="zk_proc" class="z-loading"><div class="z-loading-indicator"><span class="z-loading-icon"></span>Processing...</div></div></div>
<script class="z-runonce" type="text/javascript">//<![CDATA[
zkmx(
[0,'jBKQ_',{
dt:'z_xui',cu:'/TemplateColumnsTest01',uu:'/TemplateColumnsTest01/zkau',ru:'/index.zul'
}
,[
['zul.wnd.Window','jBKQ0',{
$$onSize:false,$$onMaximize:false,$$onOpen:false,$$onMinimize:false,$$onZIndex:false,$onClose:true,$$onMove:false,width:'300px',title:'Hello World!!',border:'normal'
}
,[
['zul.box.Vlayout','jBKQ1',{},[
['zul.sel.Listbox','jBKQ2',{
$$onRender:true,$$onSelect:false,$$onDataLoading:true,$$onAnchorPos:false,$$onAcrossPage:true,$$onInnerWidth:false,$$onPageSize:true,$$onScrollPos:false,_topPad:0,_totalSize:2,_offset:0
}
,[
['com.eis.zk.listbox.ListheadExt','jBKQ3',{
$$onColSize:false
}
,[
['zul.sel.Listheader','jBKQ4',{
$onSort:true,label:'ID',sortDescending:'fromServer',sortAscending:'fromServer'
}
,[]],
['zul.sel.Listheader','jBKQ5',{
$onSort:true,label:'Surname',sortDescending:'fromServer',sortAscending:'fromServer'
}
,[]],
['zul.sel.Listheader','jBKQ6',{
$onSort:true,label:'First name',sortDescending:'fromServer',sortAscending:'fromServer'
}
,[]]]],
['zul.sel.Listitem','jBKQ7',{
_index:0
}
,[
['zul.sel.Listcell','jBKQ8',{
label:'5'
}
,[]],
['zul.sel.Listcell','jBKQ9',{
label:'Smith'
}
,[]],
['zul.sel.Listcell','jBKQa',{
label:'Fred'
}
,[]]]],
['zul.sel.Listitem','jBKQb',{
_index:1
}
,[
['zul.sel.Listcell','jBKQc',{
label:'7'
}
,[]],
['zul.sel.Listcell','jBKQd',{
label:'Jones'
}
,[]],
['zul.sel.Listcell','jBKQe',{
label:'Mike'
}
,[]]]]]]]]]]]]);
//]]>
</script>
<noscript>
<div class="noscript"><p>Sorry, JavaScript must be enabled.<br/>Change your browser options, then <a href="">try again</a>.</p></div>
</noscript>
</body>
</html>
Any suggestions?
Here's the source code as it currently stands:
The Java class:
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 lang-addon.xml file:
<language-addon>
<addon-name>mycomps</addon-name>
<version>
<version-class>com.eis.zk.listbox.Version</version-class>
<version-uid>0.0.1-SNAPSHOT</version-uid>
<zk-version>6.5.2</zk-version><!-- or later -->
</version>
<language-name>xul/html</language-name>
<component>
<component-name>listheadext</component-name> <!-- required -->
<extends>listhead</extends>
<component-class>com.eis.zk.listbox.ListheadExt</component-class> <!-- required -->
<widget-class>com.eis.zk.listbox.ListheadExt</widget-class> <!-- required -->
<mold>
<mold-name>default</mold-name>
<mold-uri>mold/ListheadExt.js</mold-uri>
</mold>
</component>
</language-addon>
The JS widget:
zk.$package('com.eis.zk.listbox');
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 zk.wpd file:
<?xml version="1.0" encoding="UTF-8"?>
<package name="com.eis.zk.listbox" language="xul/html" depends="zul.sel" >
<widget name="ListheadExt" />
</package>
The mold JS file:
function (out) {
out.push('<span', this.domattrs_(), '>', this.getValue(), '</span>');
}
I'm at my wits end on this problem. If there is any kind soul out there willing to help me solve this, then I will be very happy to write up the solution for an article promoting ZK.
TIA
I've just run the same test app under Chrome, and using the developer panels this seems to show an error:
GET http://dellxps:8080/TemplateColumnsTest01/zkau/web/_zv2013032614/js/com.eis.zk.listbox.wpd 404 (/js/com.eis.zk.listbox.wpd) zk.wpd:20
zk.copy._load zk.wpd:20
k zk.wpd:21
zk.copy.zkx zk.wpd:21
zk.copy.zkmx zk.wpd:21
(anonymous function) dellxps/:17
Digging around elsewhere in the Chrome debugger shows an error:
HTTP Status 404 - /js/com.eis.zk.listbox.wpd</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>/js/com.eis.zk.listbox.wpd</u></p><p><b>description</b> <u>The requested resource (/js/com.eis.zk.listbox.wpd) is not available.
I've no experience of debugging this sort of stuff. Any suggestions for how I proceed?
The image below shows my custom component jar file structure:
Your widget class in lang-addon.xml is <widget-class>com.eis.zk.listbox.ListheadExt</widget-class>
however your folder structure do not match the package. From the image in your answer (btw you should move this info into your question itself instead of putting it in an answer here), the widget class file is in web/js/listbox
. It should be in web/js/com/eis/zk/listbox
Thanks for that. Once I put the 'js' files in the correct 'com/eis/zk/listbox' folder the page is now displayed. However, problems remain. For some reason the listbox title columns are not being displayed. Is this something to do with requiring a CS file for every component?
davout ( 2013-07-08 15:31:45 +0800 )editNow that I've got a custom component working that implements the functionality of its parent class, the next step is to introduce the behaviour specific to the custom component.
In this case I have a 'ListheadExt' component designed to display a variable number of extra list box columns. It can display a fixed set of columns (like 'ID', 'surname', and 'first name' shown below) and then a variable number of extra columns based upon a MVVM class collection property set into the 'dynamic' attribute.
<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>
I've added a binding annotation to the lang-addon-,xnml file like
<language-addon>
<addon-name>mycomps</addon-name>
<version>
<version-class>com.eis.zk.listbox.Version</version-class>
<version-uid>0.0.1-SNAPSHOT</version-uid>
<zk-version>6.5.2</zk-version><!-- or later -->
</version>
<language-name>xul/html</language-name>
<component>
<component-name>listheadext</component-name> <!-- required -->
<extends>listhead</extends>
<component-class>com.eis.zk.listbox.ListheadExt</component-class> <!-- required -->
<widget-class>com.eis.zk.listbox.ListheadExt</widget-class> <!-- required -->
<mold>
<mold-name>default</mold-name>
<mold-uri>mold/ListheadExt.js</mold-uri>
</mold>
<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>SAVE_EVENT</attribute-name>
<attribute-value>onChange</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>
</component>
</language-addon>
Yet when I run this test app the extra 'dynamic' columns are not being displayed. Any suggestions for what's missing?
The HTML source for the generated page is:
zkmx(
[0,'xCoX_',{dt:'z_8c10',cu:'/TemplateColumnsTest01',uu:'/TemplateColumnsTest01/zkau',ru:'/index.zul'},[
['zul.wnd.Window','xCoX0',{$$onSize:false,$$onMaximize:false,$$onOpen:false,$$onMinimize:false,$$onZIndex:false,$onClose:true,$$onMove:false,width:'300px',title:'Hello World!!',border:'normal'},[
['zul.box.Vlayout','xCoX1',{},[
['zul.sel.Listbox','xCoX2',{$$onRender:true,$$onSelect:false,$$onDataLoading:true,$$onAnchorPos:false,$$onAcrossPage:true,$$onInnerWidth:false,$$onPageSize:true,$$onScrollPos:false,model:true,_topPad:0,_totalSize:5,_offset:0},[
['com.eis.zk.listbox.ListheadExt','xCoX3',{$$onColSize:false,dynamic:['com.eis.zk.test.listbox.DynamicColumnDO@4769baee','com.eis.zk.test.listbox.DynamicColumnDO@6e6f83e2','com.eis.zk.test.listbox.DynamicColumnDO@5b3ba312','com.eis.zk.test.listbox.DynamicColumnDO@284f2189']},[
['zul.sel.Listheader','xCoX4',{$onSort:true,label:'ID',sortDescending:'fromServer',sortAscending:'fromServer'},[]],
['zul.sel.Listheader','xCoX5',{$onSort:true,label:'Surname',sortDescending:'fromServer',sortAscending:'fromServer'},[]],
['zul.sel.Listheader','xCoX6',{$onSort:true,label:'First name',sortDescending:'fromServer',sortAscending:'fromServer'},[]]]],
['zul.sel.Listitem','xCoXh',{_loaded:true,_index:0},[
['zul.sel.Listcell','xCoXi',{label:'jbloggs'},[]],
['zul.sel.Listcell','xCoXj',{label:'Bloggs'},[]],
['zul.sel.Listcell','xCoXk',{label:'Joe'},[]]]],
['zul.sel.Listitem','xCoXl',{_loaded:true,_index:1},[
['zul.sel.Listcell','xCoXm',{label:'asmith'},[]],
['zul.sel.Listcell','xCoXn',{label:'Smith'},[]],
['zul.sel.Listcell','xCoXo',{label:'Adam'},[]]]],
['zul.sel.Listitem','xCoXp',{_loaded:true,_index:2},[
['zul.sel.Listcell','xCoXq',{label:'ahitler'},[]],
['zul.sel.Listcell','xCoXr',{label:'Hilter'},[]],
['zul.sel.Listcell','xCoXs',{label:'Adolf'},[]]]],
['zul.sel.Listitem','xCoXt',{_loaded:true,_index:3},[
['zul.sel.Listcell','xCoXu',{label:'jstalin'},[]],
['zul.sel.Listcell','xCoXv',{label:'Stalin'},[]],
['zul.sel.Listcell','xCoXw',{label:'Joe'},[]]]],
['zul.sel.Listitem','xCoXx',{_loaded:true,_index:4},[
['zul.sel.Listcell','xCoXy',{label:'wchurchill'},[]],
['zul.sel.Listcell','xCoXz',{label:'Churchill'},[]],
['zul.sel.Listcell','xCoX_0',{label:'Winstone'},[]]]]]]]]]]]]);
//]]>
</s
Like listbox has ListboxDataLoader.java which define a default template how to render listitem. You should also provide a template for Listheadext to render Listheader.
vincentjian ( 2013-07-12 05:51:24 +0800 )editAsked: 2013-07-01 19:32:44 +0800
Seen: 87 times
Last updated: Jul 09 '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
What IE version did you see this error with? Is it IE10? IE 10 seems to have some issue with DOCTYPE (see here) Also are you sure you are using the IE Standards mode?
ashishd ( 2013-07-04 04:21:52 +0800 )editI've just tried running this under Chrome and looking at the debugger output there seems to be problem with:
davout ( 2013-07-04 22:01:22 +0800 )edit