-
1. Re: selectOneMenu and a4j:support problem
tmalatinszki Oct 15, 2009 9:24 AM (in response to vdeminico)Hi Valerio,
In Seam You should use s:convertEntity tag with h:selectOneMenu, here's an example:
<h:selectOneMenu value="#{regioneAction.selectedRegione}"> <s:selectItems value="#{regioni}" var="reg" label="#{reg.nome}"/> <a4j:support event="onchange" action="#{regioneAction.selectProvincia}"/> <s:convertEntity/> </h:selectOneMenu>
In regioneAction bean:
private Regione selectedRegione; // getters-setters and other stuffs public void selectProvincia(){ logger.info("Regione selected: " + selectedRegione.getNome()); }
Regrettably @DataModelSelection is not working with h:selectOneMenu (as You experienced it always returns with the first element), but in this case You don't need it anyway.
Regards,
Tamas
-
2. Re: selectOneMenu and a4j:support problem
vdeminico Oct 15, 2009 2:44 PM (in response to vdeminico)Hi Tamas,
here is my code:registration.xhtml
<h:selectOneMenu id="regioneSelect" value="#{regioneAction.selectedRegione}" require="true"> <s:selectItems value="#{regioni}" var="reg" label="#{reg.nome}"/> <a4j:support event="onchange" action="#{regioneAction.selectProvincia}" reRender="provinciaSelect"/> <s:convertEntity/> </h:selectOneMenu>
and the action bean:
@Name("regioneAction") public class RegioneAction { @In RegioneService regioneService; @In ProvinciaService provinciaService; @Logger Log logger; @DataModel(scope=ScopeType.PAGE) @Out(required=false) private List<Regione> regioni; Regione selectedRegione; @Out(required=false,scope=ScopeType.PAGE) private List<Provincia> provincie=new ArrayList<Provincia>(); @Factory(value="regioni") public void retrieveAllRegioni() { regioni = regioneService.retrieveAllRegione(); } public void selectProvincia() { logger.info("Regione.name: " + selectedRegione); } //getters and setters
it prints out this error:
sourceId=registrationForm:valueDecoration1:regioneSelect[severity=(ERROR 2), summary=(value is not valid), detail=(value is not valid)]
Why?
Thanks,
Valerio. -
3. Re: selectOneMenu and a4j:support problem
tmalatinszki Oct 15, 2009 3:15 PM (in response to vdeminico)Hi Valerio,
You have to override hashCode() and equals() methods in Regione entity.
Check this post, they had the same issue with h:selectOneMenu.
Regards,
Tamas
-
4. Re: selectOneMenu and a4j:support problem
vdeminico Oct 15, 2009 4:29 PM (in response to vdeminico)Ok Tamas, I solved that problem... But now I have another one...
I have implemented the equals() and hashcode() methods on the Entity classes. Now my code is this:
action bean:
@Name("regioneAction") public class RegioneAction { @In RegioneService regioneService; @In ProvinciaService provinciaService; @Logger Log logger; @DataModel(scope=ScopeType.PAGE) @Out(required=false) private List<Regione> regioni; Regione selectedRegione = new Regione(); @Out(required=false,scope=ScopeType.PAGE) private List<Provincia> provincie=new ArrayList<Provincia>(); @Factory(value="regioni") public void retrieveAllRegioni() { regioni = regioneService.retrieveAllRegione(); } public void selectProvincia() { if(selectedRegione!=null) { logger.info("Selected on regione combo... Regione.name: " + selectedRegione.getNome()); provincie = provinciaService.retrieveProvincieForRegione(selectedRegione); } } }
registration.xhtml:
<s:decorate id="valueDecoration1" template="layout/edit.xhtml"> <ui:define name="label"> <h:outputLabel for="regioneSelect">Regione:</h:outputLabel> </ui:define> <h:selectOneMenu id="regioneSelect" value="#{regioneAction.selectedRegione}" require="true"> <s:selectItems value="#{regioni}" var="reg" label="#{reg.nome}" /> <a4j:support event="onchange" action="#{regioneAction.selectProvincia}" reRender="provinciaSelect" bypassUpdates="false" /> <s:convertEntity/> </h:selectOneMenu> </s:decorate> <s:decorate id="valueDecoration2" template="layout/edit.xhtml"> <ui:define name="label"> <h:outputLabel for="provinciaSelect">Provincia:</h:outputLabel> </ui:define> <h:selectOneMenu id="provinciaSelect" value="" require="true"> <s:selectItems value="#{provincie}" var="prov" label="#{prov.nome}"/> </h:selectOneMenu> </s:decorate>
It has a strange behavior... the first time I select a value on the regioneSelect it normally load the provincia select values... when I select a regione again, it prints out this exception:
16:19:35,953 ERROR [ExceptionFilter] handling uncaught exception javax.servlet.ServletException at javax.faces.webapp.FacesServlet.service(FacesServlet.java:256) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141) at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281) at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Unknown Source) Caused by: java.util.NoSuchElementException at javax.faces.component.SelectItemsIterator.next(SelectItemsIterator.java:117) at javax.faces.component.SelectItemsIterator.next(SelectItemsIterator.java:144) at javax.faces.component.SelectItemsIterator.next(SelectItemsIterator.java:49) at javax.faces.component.UISelectOne.matchValue(UISelectOne.java:164) at javax.faces.component.UISelectOne.validateValue(UISelectOne.java:137) at javax.faces.component.UIInput.validate(UIInput.java:867) at javax.faces.component.UIInput.executeValidate(UIInput.java:1065) at javax.faces.component.UIInput.processValidators(UIInput.java:666) at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1033) at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1033) at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1033) at javax.faces.component.UIForm.processValidators(UIForm.java:229) at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1033) at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:662) at org.ajax4jsf.component.AjaxViewRoot.access$201(AjaxViewRoot.java:57) at org.ajax4jsf.component.AjaxViewRoot$3.invokeRoot(AjaxViewRoot.java:319) at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnRegionOrRoot(JsfOneOneInvoker.java:56) at org.ajax4jsf.context.AjaxContextImpl.invokeOnRegionOrRoot(AjaxContextImpl.java:170) at org.ajax4jsf.component.AjaxViewRoot.processValidators(AjaxViewRoot.java:333) at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:100) at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244) ... 31 more
Any ideas?????
Thanks,
Valerio. -
5. Re: selectOneMenu and a4j:support problem
tmalatinszki Oct 16, 2009 10:27 AM (in response to vdeminico)Have You tried to modify provinciaSelect element the same way as regioneSelect (with definied value attribute and s:convertEntity tag)? Or, just for test: do You receive the error messages if You remove the full provinciaSelect tag from Your XHTML code?
Regards,
Tamas
-
6. Re: selectOneMenu and a4j:support problem
vdeminico Oct 16, 2009 12:55 PM (in response to vdeminico)I don't know which could be the problem... maybe the list in the action was not the same on the new request... However I have solved considering regioni list as a simple class field, not a DataModel, the same for provincie. I access these property through the regioneAction seam component and now it works correctly.
This is my new regioneAction bean code:@Name("regioneAction") @Scope(ScopeType.PAGE) public class RegioneAction { @In RegioneService regioneService; @In ProvinciaService provinciaService; @In ComuneService comuneService; @Logger Log logger; private List<Regione> regioni; private List<Provincia> provincie=new ArrayList<Provincia>(); private List<Comune> comuni=new ArrayList<Comune>(); Regione selectedRegione; Provincia selectedProvincia; public void retrieveAllRegioni() { if(regioni==null) regioni = regioneService.retrieveAllRegione(); } public void selectRegione() { if(selectedRegione!=null) { logger.info("Selected on regione combo... Regione.name: " + selectedRegione.getNome()); provincie=provinciaService.retrieveProvincieForRegione(selectedRegione); comuni.clear(); } } public void selectProvincia() { if(selectedRegione!=null) { logger.info("Selected on provincia combo... Provincia.name: " + selectedProvincia.getNome()); comuni=comuneService.retrieveComuniForProvincia(selectedProvincia); } } public Regione getSelectedRegione() { return selectedRegione; } public void setSelectedRegione(Regione selectedRegione) { this.selectedRegione = selectedRegione; } public List<Regione> getRegioni() { return this.regioni; } public void setRegioni(List<Regione> reg) { this.regioni=reg; } public List<Provincia> getProvincie() { return provincie; } public void setProvincie(List<Provincia> provincie) { this.provincie = provincie; } public List<Comune> getComuni() { return comuni; } public void setComuni(List<Comune> comuni) { this.comuni = comuni; } public Provincia getSelectedProvincia() { return selectedProvincia; } public void setSelectedProvincia(Provincia selectedProvincia) { this.selectedProvincia = selectedProvincia; } }
Thanks for your support Tamas.
Valerio. -
7. Re: selectOneMenu and a4j:support problem
vdeminico Nov 26, 2009 1:37 PM (in response to vdeminico)Hi,
I note a strange behaviour in the code example as above...
The complete example provides three selectOneMenus that are dependent each other. The xhtml code is the following:<s:decorate id="regioneSelectDecoration" template="layout/edit.xhtml"> <ui:define name="label"> <h:outputLabel for="regioneSelect">Regione:</h:outputLabel> </ui:define> <h:selectOneMenu id="regioneSelect" value="#{regioneAction.selectedRegione}" required="true" rendered="#{empty attivita.comune}"> <s:selectItems value="#{regioneAction.regioni}" var="reg" label="#{reg.nome}" noSelectionLabel="--Selezionare una regione--"/> <a4j:support event="onchange" action="#{regioneAction.selectRegione}" reRender="provinciaSelect,comuneSelect" bypassUpdates="false" ajaxSingle="true"> <s:conversationId value="#{conversation.id}"/> </a4j:support> <s:convertEntity/> </h:selectOneMenu> <h:outputText value="#{attivita.comune.provincia.regione.nome}" rendered="#{not empty attivita.comune}" /> </s:decorate> <s:decorate id="provinciaSelectDecoration" template="layout/edit.xhtml"> <ui:define name="label"> <h:outputLabel for="provinciaSelect">Provincia:</h:outputLabel> </ui:define> <h:selectOneMenu id="provinciaSelect" value="#{regioneAction.selectedProvincia}" required="true" rendered="#{empty attivita.comune}"> <s:selectItems value="#{regioneAction.provincie}" var="prov" label="#{prov.nome}" noSelectionLabel="--Selezionare una provincia--"/> <a4j:support event="onchange" action="#{regioneAction.selectProvincia}" reRender="comuneSelect" bypassUpdates="false" ajaxSingle="true"> <s:conversationId value="#{conversation.id}"/> </a4j:support> <s:convertEntity /> </h:selectOneMenu> <h:outputText value="#{attivita.comune.provincia.nome}" rendered="#{not empty attivita.comune}" /> </s:decorate> <s:decorate id="comuneSelectDecoration" template="layout/edit.xhtml"> <ui:define name="label"> <h:outputLabel for="comuneSelect">Comune:</h:outputLabel> </ui:define> <h:selectOneMenu id="comuneSelect" value="#{attivita.comune}" required="true" rendered="#{empty attivita.comune}"> <s:selectItems value="#{regioneAction.comuni}" var="com" label="#{com.nome}" noSelectionLabel="--Selezionare un comune--"/> <a4j:support event="onchange" action="#{regioneAction.selectComune()}" bypassUpdates="false" ajaxSingle="true"> <s:conversationId value="#{conversation.id}"/> </a4j:support> <s:convertEntity /> </h:selectOneMenu> <h:outputText value="#{attivita.comune.nome}" rendered="#{not empty attivita.comune}" /> </s:decorate>
and the action class is:
public void selectRegione() { if(selectedRegione!=null) { logger.info("Selected on regione combo... Regione.name: " + selectedRegione.getNome()); provincie=provinciaService.retrieveProvincieForRegione(selectedRegione); comuni.clear(); } } /**Metodo che gestisce la selezione di una provincia e carica la lista dei comuni. * */ public void selectProvincia() { if(selectedRegione!=null) { logger.info("Selected on provincia combo... Provincia.name: " + selectedProvincia.getNome()); comuni=comuneService.retrieveComuniForProvincia(selectedProvincia); } } public void selectComune() { if (selectedProvincia!=null) { Attivita attivita = (Attivita) Component.getInstance(Attivita.class); selectedComune = attivita.getComune(); logger.info("Selected on comune combo... Comune.name: " + selectedComune.getNome()); logger.info("Retrieving Localita list for comune: " + selectedComune.getNome()); listaLocalita = localitaService.retrieveLocalitaForComune(selectedComune); } }
it executes into a conversation, so I use a s:conversation into the a4j:support element. The problem is that if I select a Regione, then the Provincia is correctly updated. Same if I select a Provincia... it updates the Comune field. And if I select a different Regione or Provincia, it works fine updating the related fields. Then I select a Comune on the third field. When I do this operation, the onchange event on all select fields are not fired. So selecting a new item in Provincia doesn't fire any event (action method is not executed!). Why this behaviour??? Could it be a Seam 2.0.3 bug????
Thanks,
Valerio.