jsf 2 - Composite Component containing inputText with ajax -
the way works
seeking hard solution, found forgot leading h:head tags in usage component. adding them made errors disappear. finish solution here lastly code:
the composite component class="lang-xml prettyprint-override"><ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:composite="http://java.sun.com/jsf/composite"> <composite:interface> <composite:attribute name="value" required="true" /> <composite:attribute name="size" required="false" default="20" /> <composite:clientbehavior name="change" event="change" targets="input" /> </composite:interface> <composite:implementation> <h:inputtext id="input" value="#{cc.attrs.value}" size="#{cc.attrs.size}" /> </composite:implementation>
the bean class="lang-java prettyprint-override">@managedbean @sessionscoped public class mybean { private string value1; private string value2; private string value3; public string exec() { this.value2 = value3; homecoming ""; } public void listenajax(ajaxbehaviorevent e) { uiinput = (uiinput) e.getcomponent(); value2 = (string) i.getvalue(); system.out.println("ajax value = " + i.getvalue()); system.out.println("value1 = " + value1); system.out.println("value2 = " + value2); system.out.println("value3 = " + value3); } public string getvalue3() { homecoming value3; } public string getvalue2() { homecoming value2; } public string getvalue1() { homecoming value1; } public void setvalue1(string value1) { this.value1 = value1; } public void setvalue3(string value3) { this.value3 = value3; } }
the calling xhtml file class="lang-xml prettyprint-override"><!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" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:test="http://java.sun.com/jsf/composite/test"> <h:head> </h:head> <h:body> <h:form id="form"> <h:panelgrid columns="2"> <h:outputtext value="value3" /> <h:inputtext value="#{mybean.value3}"> <f:ajax event="change" render="see" listener="#{mybean.listenajax}" /> </h:inputtext> <h:outputtext value="value1" /> <test:test value="#{mybean.value1}"> <f:ajax event="change" render=":form:see" listener="#{mybean.listenajax}" /> </test:test> <h:outputtext value="value2" /> <h:outputtext id="see" value="#{mybean.value2}" /> <h:outputtext value="" /> <h:commandbutton action="#{mybean.exec}" value="set" /> </h:panelgrid> </h:form> </h:body> </html>
finally, gave me hints , helped me finding out bugs.
improvements step 2
redesigning component have this:
composite component: class="lang-xml prettyprint-override"><ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:composite="http://java.sun.com/jsf/composite"> <composite:interface> <composite:attribute name="value" required="true" /> <composite:attribute name="size" required="false" default="20" /> <composite:clientbehavior name="change" event="change" targets="input" /> </composite:interface> <composite:implementation> <h:inputtext id="input" value="#{cc.attrs.value}" size="#{cc.attrs.size}" /> </composite:implementation>
managed bean: class="lang-java prettyprint-override">@managedbean @sessionscoped public class mybean { private string value1; private string value2; private string value3; public string exec() { this.value2 = value3; homecoming ""; } public void listen(ajaxbehaviorevent e) { uiinput = (uiinput) e.getcomponent(); value2 = (string) i.getvalue(); system.out.println("ajax value = " + i.getvalue()); system.out.println("value1 = " + value1); system.out.println("value2 = " + value2); system.out.println("value3 = " + value3); } public string getvalue3() { homecoming value3; } public string getvalue2() { homecoming value2; } public string getvalue1() { homecoming value1; } public void setvalue1(string value1) { this.value1 = value1; } public void setvalue3(string value3) { this.value3 = value3; }
}
usage: class="lang-xml prettyprint-override"><!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" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:test="http://java.sun.com/jsf/composite/test"> <h:body> <h:form> <test:test value="#{mybean.value1}"> <f:ajax event="change" render=":out" listener="#{mybean.listen}" /> </test:test> <h:inputtext value="#{mybean.value3}"> <f:ajax event="change" render=":out" listener="#{mybean.listen}" /> </h:inputtext> <h:commandbutton action="#{mybean.exec}" value="set" /> </h:form> <h:outputtext id="out" value="#{mybean.value2}" /> </h:body> </html>
nevertheless no ajax response done component outside of form (no results in log window). confusing me, how can create work?
improvements step 1 (old)
so tried improve code, changing composite component to
class="lang-xml prettyprint-override"><ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:composite="http://java.sun.com/jsf/composite"> <composite:interface> <composite:attribute name="value" required="true" /> <composite:attribute name="size" required="false" default="20" /> <composite:clientbehavior name="change" event="change" targets="#{cc.clientid}:input" /> </composite:interface> <composite:implementation> <h:inputtext id="input" value="#{cc.attrs.value}" size="#{cc.attrs.size}" /> </composite:implementation>
and phone call be
class="lang-xml prettyprint-override"><my:test value="#{test.value1}"> <f:ajax event="change" render=":out" listener="#{test.listen}" /> </my:test> <h:outputtext id="out" value="#{test.value2}" />
with result nil happens. may create work?
the original post*
i'd create composite component working ajax. googled lot, found solutions here on stackoverflow, seemed work buttons only. here have inputtext
component, how can give component ajax event listener? executing illustration (see below) gives error:
com.sun.faces.lifecycle.invokeapplicationphase execute warning: 0 java.lang.arrayindexoutofboundsexception: 0 @ org.apache.el.parser.astvalue.convertargs(astvalue.java:320) @ org.apache.el.parser.astvalue.invoke(astvalue.java:274) @ org.apache.el.methodexpressionimpl.invoke(methodexpressionimpl.java:274) @ com.sun.faces.facelets.el.contextualcompositemethodexpression.invoke(contextualcompositemethodexpression.java:187) @ com.sun.faces.facelets.tag.tagattributeimpl$attributelookupmethodexpression.invoke(tagattributeimpl.java:473) @ com.sun.faces.facelets.tag.jsf.core.ajaxbehaviorlistenerimpl.processajaxbehavior(ajaxhandler.java:459) @ javax.faces.event.ajaxbehaviorevent.processlistener(ajaxbehaviorevent.java:113) @ javax.faces.component.behavior.behaviorbase.broadcast(behaviorbase.java:106) @ javax.faces.component.uicomponentbase.broadcast(uicomponentbase.java:809) @ javax.faces.component.uiviewroot.broadcastevents(uiviewroot.java:800) @ javax.faces.component.uiviewroot.processapplication(uiviewroot.java:1292) @ com.sun.faces.lifecycle.invokeapplicationphase.execute(invokeapplicationphase.java:81) @ com.sun.faces.lifecycle.phase.dophase(phase.java:101) @ com.sun.faces.lifecycle.lifecycleimpl.execute(lifecycleimpl.java:181) @ javax.faces.webapp.facesservlet.service(facesservlet.java:645) @ org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:305) @ org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:210) @ org.apache.catalina.core.standardwrappervalve.invoke(standardwrappervalve.java:222) @ org.apache.catalina.core.standardcontextvalve.invoke(standardcontextvalve.java:123) @ org.apache.catalina.authenticator.authenticatorbase.invoke(authenticatorbase.java:472) @ org.apache.catalina.core.standardhostvalve.invoke(standardhostvalve.java:171) @ org.apache.catalina.valves.errorreportvalve.invoke(errorreportvalve.java:99) @ org.apache.catalina.valves.accesslogvalve.invoke(accesslogvalve.java:936) @ org.apache.catalina.core.standardenginevalve.invoke(standardenginevalve.java:118) @ org.apache.catalina.connector.coyoteadapter.service(coyoteadapter.java:407) @ org.apache.coyote.http11.abstracthttp11processor.process(abstracthttp11processor.java:1004) @ org.apache.coyote.abstractprotocol$abstractconnectionhandler.process(abstractprotocol.java:589) @ org.apache.tomcat.util.net.jioendpoint$socketprocessor.run(jioendpoint.java:310) @ java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1110) @ java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:603) @ java.lang.thread.run(thread.java:722)
my composite component:
class="lang-xml prettyprint-override"><ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:composite="http://java.sun.com/jsf/composite"> <composite:interface> <composite:attribute name="value" required="true" /> <composite:attribute name="size" required="false" default="20" /> <composite:attribute name="enableajax" required="false" default="false" /> <composite:attribute name="ajaxrender" required="false" /> <composite:attribute name="ajaxlistener" required="false" method-signature="void listen(javax.faces.event.ajaxbehaviorevent)" /> </composite:interface> <composite:implementation> <h:inputtext id="input" value="#{cc.attrs.value}" size="#{cc.attrs.size}"> <f:ajax event="change" render="#{cc.attrs.ajaxrender}" listener="#{cc.attrs.ajaxlistener}" disabled="#{!cc.attrs.enableajax}" /> </h:inputtext> </composite:implementation>
my call:
class="lang-xml prettyprint-override"><my:test value="#{test.value1}" ajaxrender=":out" ajaxlistener="#{test.listen}" enableajax="true" /> <h:outputtext id="out" value="#{test.value2}" />
my bean:
class="lang-java prettyprint-override">@managedbean @sessionscoped public class test { private string value1; private string value2; ... public void listen(ajaxbehaviorevent e) { value2 = (string) ((uiinput) e.getcomponent()).getvalue(); } ... (getter & setter) }
btw. composite component much more complex, reduced illustration relevant parts.
the <cc:clientbehavior>
should work. targets
wrong.
<composite:clientbehavior name="change" event="change" targets="#{cc.clientid}:input" />
it must relative composite itself, not parent/viewroot or whatever (as theoretically require editing composite component everytime when set in different naming container parent!).
thus, so
<composite:clientbehavior name="change" event="change" targets="input" />
ajax jsf-2 composite-component
No comments:
Post a Comment