0

Events aren't sent from the browser on activation of the databinding (in a JSF component)

asked 2010-11-08 03:13:19 +0800

chantereau gravatar image chantereau
9

updated 2010-11-08 04:32:45 +0800

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)

http://books.zkoss.org/wiki/ZK_Developer's_Reference/Integration/Embed_ZK_Component_in_Foreign_Framework

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

delete flag offensive retag edit

4 Replies

Sort by ยป oldest newest

answered 2010-11-16 02:18:00 +0800

ashishd gravatar image ashishd flag of Taiwan
1972 6

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.

link publish delete flag offensive edit

answered 2010-11-16 20:03:23 +0800

ashishd gravatar image ashishd flag of Taiwan
1972 6

updated 2010-11-16 20:03:51 +0800

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>

user.zul
<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>

WindowComposer.java
@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";
	}
}

link publish delete flag offensive edit

answered 2010-11-17 03:12:16 +0800

ochantereau gravatar image ochantereau
24

updated 2010-11-17 03:12:56 +0800

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>

link publish delete flag offensive edit

answered 2010-11-17 05:03:26 +0800

ashishd gravatar image ashishd flag of Taiwan
1972 6

Hi ochantereau,
Can you please provide complete source code instead of fragments of it? It would be easier to reproduce it for everyone. Thanks.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-11-08 03:13:19 +0800

Seen: 572 times

Last updated: Nov 17 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More