-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi,
We are integrating a zul page in a JSF component in a Portlet.
When the component is standalone (only the zul page) everything works as it should.
In order to integrate the zul page in the JSF component, we are using the method desctibed here (zk. 5.0.5)
When we activate the databinding by annotation in a zul page (<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>),
the databinding seems to work, but no events are sent from the client browser. When we remove the annotation, the events are sent again, but of course the databinding doesn't work anymore.
We have also tried to instatiate the databinder directly from the java code:
Renders.render(svlctx, request,response,
new GenericRichlet() {
public void service(Page page) throws Exception {
window = new Window();
window.setId("zkWindow");
window.setPage(page);
applyProperties();
HtmlMacroComponent bookEventComponent = new HtmlMacroComponent();
bookEventComponent.setMacroURI("calendar.zul");
bookEventComponent.setParent(window);
bookEventComponent.applyProperties();
bookEventComponent.afterCompose();
window.appendChild(bookEventComponent);
Renders.render(svlctx, request, response, window, null, responseWriter);
doAfterCompose();
[...]
AnnotateDataBinderInit o = new AnnotateDataBinderInit();
o.doInit(page, new HashMap());
try {
o.doAfterCompose(page, comps);
} catch (Exception e) {
e.printStackTrace();
}
In this case , the events are sent, but the databinder is instantiated only partially (not all components are binded)
Without annotatebinder init...
['zul.inp.Combobox','z_r7e_c',{id:'endTime',$onChange:true,width:'60px',sclass:'time'},[]],
['zul.db.Datebox','z_r7e_d',{id:'endDate',prolog:'\t\n\t\t\t',cols:11,format:'d MMM yyyy'},[]],
With ann... but no event start
['zul.inp.Combobox','z_epu_c',{id:'endTime',$onChange:true,width:'60px',sclass:'time',value:'10:30'},[]],
['zul.db.Datebox','z_epu_d',{id:'endDate',$onChange:true,prolog:'\t\n\t\t\t',cols:11,format:'d MMM yyyy',value:'8 nov. 2010'},[]],
What are we doing wrong ?
Thanks,
Olivier
Hi chantereau,
What version of JSF and implementation are you working with? Can you provide a war file with all the dependencies so as to quickly reproduce this issue. Or at least complete source code is also appreciated. Thanks.
Hi chantereau,
I would suggest using Executions.createComponents() instead of HtmlMacroComponent as it reads better. Here is the example code that I demonstrates ZK databinding and event with ZK component wrapped as JSF component.
Please note that I used JSF 2.0 (Mojarra 2.0.2 (FCS b10) to be specific) on Apache Tomcat/6.0.29 and ZK 5.0.5-FL EE for this.
data.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:zk="http://www.zkoss.org/jsf/zss"> <h:head> <title>Window in JSF Demo</title> </h:head> <h:body> <h:form> <zk:window id="mywin" title="Data Binding Demo" border="normal" apply="org.zkoss.zkjsf.demo.WindowComposer" width="500px" height="500px"> </zk:window> </h:form> </h:body> </html>
<window> <div id="div"> <label value="Name:" /> <label value="@{user.name}" /> <separator /> <label value="Age:" /> <label value="@{user.age}" /> </div> <button label="dialog" id="btn" /> </window>
@ManagedBean @SessionScoped public class WindowComposer extends GenericForwardComposer{ private AnnotateDataBinder binder; private transient Button btn; public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); User user = new User("Jimmy", 26); binder = new AnnotateDataBinder(comp); binder.bindBean("user", user); binder.loadAll(); } public void onClick$btn(Event evt) throws InterruptedException { Messagebox.show("Hello"); } }
and finally WindowTag.java
@FacesComponent(value = "window") public class WindowTag extends UIComponentBase { private static final Log log = Log.lookup(WindowTag.class); private Window window; public void encodeBegin(FacesContext context) throws IOException { ServletContext svlctx = (ServletContext)context.getExternalContext().getContext(); HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse(); ResponseWriter responseWriter = context.getResponseWriter(); try { Renders.render(svlctx, request,response, new GenericRichlet() { public void service(Page page) throws Exception { window = (Window) Executions.createComponents("user.zul", null, null); window.setPage(page); applyProperties(); doAfterCompose(); } }, null, responseWriter); } catch (ServletException e) { throw new IOException(e.getMessage()); } } /** apply ZK component properties as retrieved from JSF custom component tag */ private void applyProperties() { Map<String, Object> attrs = getAttributes(); Set<String> attrNames = attrs.keySet(); for (Iterator iterator = attrNames.iterator(); iterator.hasNext();) { String attrName = (String) iterator.next(); if(!"apply".equals(attrName)) { try { Property.assign(window, attrName, attrs.get(attrName).toString()); } catch(PropertyNotFoundException pnfe) { log.debug(pnfe.getMessage()); } } } } /** apply composer by calling doAfterCompose after ZK component is composed */ private void doAfterCompose() throws Exception { Object o = getAttributes().get("apply"); if(o instanceof String) { o = Classes.newInstanceByThread(o.toString()); } if(o instanceof Composer) { ((Composer)o).doAfterCompose(window); } } @Override public String getFamily() { // TODO Auto-generated method stub return "window"; } }
Hi,
I have found the problem, it was caused by a bad databing on my listbox. I removed that databinding and everything works now. The databinding for the listbox worked in Zk but not in Zk in JSF.
I didnt have any errors messages just events didn't get posted. I have replaced the databinding of the listbox by "manual binding" (get/set)..
This is the example of the code that didn't work (that blocked all the events from the page):
public class LibelleId { public LibelleId(String id, String libelle){ this.id = id; this.libelle = libelle; } private String id; private String libelle; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getLibelle() { return libelle; } public void setLibelle(String libelle) { this.libelle = libelle; } public boolean equals(Object other) { if (this == other) return true; if (!(other instanceof LibelleId)) return false; LibelleId otherA = (LibelleId) other; return ((id == null) ? otherA.id == null : id.equals(otherA.id)); } public int hashCode() { int hash = 1; hash = hash * 31 + (id == null ? 0 : id.hashCode()); return hash; } } public ListModel getCalendarsTitles(){ List<LibelleId> calendarsTitles = new ArrayList<LibelleId>(); calendarsTitles.add(new LibelleId("C1","1- Calendrier 1")); calendarsTitles.add(new LibelleId("C2","2- Calendrier 2")); calendarsTitles.add(new LibelleId("C3","3- Calendrier 3")); calendarsTitles.add(new LibelleId("C4","4- Calendrier 4")); return new ListModelList(calendarsTitles); } @Override public LibelleId getCalendarLibelleId() { return _calendarId; } @Override public void setCalendarLibelleId(LibelleId calendarId) { _calendarId = calendarId; }
<listbox id="agendaListBox" class="details" mold="select" model="@{eventWindow$composer.calendarsTitles}" selectedItem ="@{eventWindow$composer.event.calendarLibelleId}"> <listitem self="@{each=libelleId}" value="@{libelleId.id}" label="@{libelleId.libelle}"/> </listbox>
Asked: 2010-11-08 03:13:19 +0800
Seen: 572 times
Last updated: Nov 17 '10