3 Replies Latest reply on Mar 18, 2012 12:03 PM by Momo Merle

    a4j:ajax not working with conditionally rendered h:selectOneMenu

    Josh Schneider Newbie

      Hello. I'm having a problem with an application we're testing on (an admittedly unsupported configuration of) RF4.1 with JSF2.1 (servlet API is only 2.5). We're trying to port from a stack running JSF 1.2 and RF 3.3.1. We have our pages rendering correctly, and much is working, but this one issue has us stumped. This page was fully working on our old stack, using a4j:support.


      We have a couple of cascading drop-downs using h:selectOneMenu, each with a4j:ajax support. The first drop-down sets a bean property and successfully renders the second drop-down, but the second drop-down is then supposed to set further bean properties and render other componenets on the page, and that's failing.


      We added a dummy listener on the bean and it is successfully called by the first drop-down, but not the second. If we remove the conditional rendering around the second drop-down, it also calls the listener. We're stumped as to why the second drop-down doesn't even fire the listener when it's contained within a conditionally rendered block. Side-note: Firebug shows that the a4j:ajax js IS fired on use of the second drop-down, even though the listener isn't called.


      Here's some code. The first two blocks are the drop-downs and the following blocks are what the second-dropdown is supposed to render. Again, the real issue is that the second drop-down seems to do nothing unless it is rendered on page load.




                                    <li id="payBillMethodSelect">

                                      <h:outputLabel id="payBillSelectPaymentMethodLabel" forceId="true"

                                          value="#{bundle.payBillSelectPaymentMethod}" />

                                      <h:selectOneMenu id="payBillSelectPaymentMethod" value="#{paymentManagedBean.selectedPaymentAccount}" required="true" forceId="true">

                                          <a4j:ajax event="change" render="paymentMethodsPanel" listener="#{paymentManagedBean.generalPurposeTestListener}" />

                                          <f:selectItems value="#{paymentManagedBean.accountNickNames}" />





                              <a4j:outputPanel id="paymentMethodsPanel"


                                  <h:panelGroup rendered="#{paymentManagedBean.renderAddPayment}">



                                              <h:outputLabel id="payBillSelectPaymentTypeLabel"

                                                  value="SELECT PAYMENT TYPE" forceId="true" />

                                              <h:selectOneMenu id="payBillSelectPaymentAccountType" value="#{paymentManagedBean.selectedPaymentAccountType}" required="true" forceId="true">

                                                  <a4j:ajax event="change" render="paymentTypesPanel securityCodePanel" listener="#{paymentManagedBean.generalPurposeTestListener}" />

                                                  <f:selectItems value="#{paymentManagedBean.paymentAccountTypes}" />








                              <a4j:outputPanel id="securityCodePanel"

                                  layout="block" forceId="true">

                                  <h:panelGroup rendered="#{paymentManagedBean.renderSecurityCode}">



                                              <h:outputLabel for="payBillInputSecurityCode"

                                                      value="Security Code/CVV" />


                                                      id="payBillInputSecurityCode" forceId="true"

                                                      value="#{paymentManagedBean.securityCode}" required="true" />







                      <a4j:outputPanel id="paymentTypesPanel"

                          layout="block" styleClass="clear" forceId="true">

                          <h:panelGroup rendered="#{paymentManagedBean.renderCheckingTabContent || paymentManagedBean.renderSavingsTabContent}">

                              <div class="cssbox">

                                  <ui:include id="paymentCheckingSavingsContent"

                                      src="/pages/content/paymentTabCheckingSavingsContent.xhtml" />



                          <h:panelGroup rendered="#{paymentManagedBean.renderCreditTabContent}" id="paymentCredit">

                              <div class="cssbox">

                                  <ui:include id="paymentCreditContent"

                                      src="/pages/content/paymentTabCreditContent.xhtml" />



                          <h:panelGroup rendered="#{paymentManagedBean.renderDebitTabContent}" id="paymentDebit">

                              <div class="cssbox">

                                  <ui:include id="paymentDebitContent"

                                      src="/pages/content/paymentTabDebitContent.xhtml" />







      I'm leaving any bean code off since I think it's irrelevant, but will post more if needed. Thanks in advance.

        • 1. Re: a4j:ajax not working with conditionally rendered h:selectOneMenu
          Josh Schneider Newbie

          Sorry, evidently I didn't markup my code block correctly. Still looks legible.


          Here's a stripped down example of the same thing as a test case:


          <h:form name="testForm" id="richForm" forceId="true">

              <h:selectOneMenu id="city" value="#{pprBean.city}">

                  <f:selectItem itemLabel="Select City" itemValue="" />

                  <f:selectItems value="#{pprBean.cities}" />

                  <f:ajax render="suburbPanel" listener="#{pprBean.handleCityChange}" />



              <h:panelGroup id="suburbPanel" forceId="true">

                  <h:panelGroup rendered="#{pprBean.renderSuburb}">

                      <h:selectOneMenu id="suburbs" value="#{pprBean.suburb}">

                          <f:selectItem itemLabel="Select Suburb" itemValue="" />

                          <f:selectItems value="#{pprBean.suburbs}" />

                          <f:ajax render="thingPanel" listener="#{pprBean.handleSuburbChange}"/>





              <h:panelGroup id="thingPanel">

                  <ui:fragment id="thingGroup" rendered="#{pprBean.renderThing}">

                      <h:button value="Peace"/>






          package com.ods.ebill.rich.ui;
          import java.util.Map;
          import java.io.Serializable;  
          import java.util.HashMap;  
          import javax.faces.application.FacesMessage;  
          import javax.faces.context.FacesContext;  
          import org.springframework.context.annotation.Scope;
          import org.springframework.stereotype.Component;
          public class PPRBean implements Serializable {  
              private String city;  
              private String suburb;  
              private Map<String,String> cities = new HashMap<String, String>();  
              private Map<String,Map<String,String>> suburbsData = new HashMap<String, Map<String,String>>();  
              private Map<String,String> suburbs = new HashMap<String, String>();  
              private Map<String,Map<String,String>> hoodsData = new HashMap<String, Map<String,String>>();  
              private Map<String,String> hoods = new HashMap<String, String>();  
              public PPRBean() {  
                  cities.put("Istanbul", "Istanbul");  
                  cities.put("Ankara", "Ankara");  
                  cities.put("Izmir", "Izmir");  
                  Map<String,String> suburbsIstanbul = new HashMap<String, String>();  
                  suburbsIstanbul.put("Kadikoy", "Kadikoy");  
                  suburbsIstanbul.put("Levent", "Levent");  
                  suburbsIstanbul.put("Cengelkoy", "Cengelkoy");  
                  Map<String,String> suburbsAnkara = new HashMap<String, String>();  
                  suburbsAnkara.put("Kecioren", "Kecioren");  
                  suburbsAnkara.put("Cankaya", "Cankaya");  
                  suburbsAnkara.put("Yenimahalle", "Yenimahalle");  
                  Map<String,String> suburbsIzmir = new HashMap<String, String>();  
                  suburbsIzmir.put("Cesme", "Cesme");  
                  suburbsIzmir.put("Gumuldur", "Gumuldur");  
                  suburbsIzmir.put("Foca", "Foca");  
                  suburbsData.put("Istanbul", suburbsIstanbul);  
                  suburbsData.put("Ankara", suburbsAnkara);  
                  suburbsData.put("Izmir", suburbsIzmir);  
              public String getCity() {  
                  return city;  
              public void setCity(String city) {  
                  this.city = city;  
              public String getSuburb() {  
                  return suburb;  
              public void setSuburb(String suburb) {  
                  this.suburb = suburb;  
              public Map<String, String> getCities() {  
                  return cities;  
              public void setCities(Map<String, String> cities) {  
                  this.cities = cities;  
              public Map<String, Map<String, String>> getSuburbsData() {  
                  return suburbsData;  
              public void setSuburbsData(Map<String, Map<String, String>> suburbsData) {  
                  this.suburbsData = suburbsData;  
              public Map<String, String> getSuburbs() {  
                  return suburbs;  
              public void setSuburbs(Map<String, String> suburbs) {  
                  this.suburbs = suburbs;  
              public void handleCityChange() {  
                  if(city !=null && !city.equals(""))  
                      suburbs = suburbsData.get(city);  
                      suburbs = new HashMap<String, String>();  
              public void handleSuburbChange() {  
                  if(suburb !=null && !suburb.equals(""))  
                      hoods = hoodsData.get(suburb);  
                      hoods = new HashMap<String, String>();  
              public boolean getRenderSuburb() {
                  if(city !=null && !city.equals("")) {
                      return true;
                  } else return false;
              public boolean getRenderThing() {
                  if(suburb !=null && !suburb.equals("")) {
                      return true;
                  } else return false;
              public void displayLocation() {  
                  FacesMessage msg = new FacesMessage("Selected", "City:" + city + ", Suburb: " + suburb);    
                  FacesContext.getCurrentInstance().addMessage(null, msg);  
          • 2. Re: a4j:ajax not working with conditionally rendered h:selectOneMenu
            Josh Schneider Newbie

            I'll answer my own question now, in case it helps anyone else. Problems in the above code snippets lie in two places. In the first example, the backing bean has session scope, but has form init getter and setter methods and a postconstruct method for other reasons (which I don't understand, since I'm a front-end guy), and in the second example, the scope is request. In essence, we're losing the set state of the drop-downs in the bean, even on ajax requests. I thought about trying to implement view and/or conversation scope for Spring (following examples elsewhere), but evidently a revision of the backing bean should resolve the issue. In the second example, changing the scope to session actually makes it work (for the most part).

            • 3. Re: a4j:ajax not working with conditionally rendered h:selectOneMenu
              Momo Merle Newbie

              Hello. I got a problem with richfaces 4.2.Final on <a4j:ajax> on <h:selectonemenu>.

              my bean is onto @SessionScoped.

              The lsitener is executed but web page is note rendered.



              my web page newAnn.xhtml







              my web page newAnn.xhtml



              <tr:form  id="uploadForm" usesUpload="true">

              <!--             <h:graphicImage width="130" height="114" library="projet_jsf_pictures/TNTe2lSURGvirXCgW" name="Pippa-Middleton-sans-culotte-2.jpg" />-->

              <!--<h:graphicImage width="130" height="114" value="/img/nokia-lumia-900.jpg"/>-->



              <rich:calendar> hello</rich:calendar>

                                  <table border="0">



                                          <td class="libelle"> <h:outputText value="Region:"/></td>




                                                  id="Region" value="#{annonceController.regionA}" valueChangeListener="#{annonceController.regionChanged}" >

                                                                      <f:selectItems value="#{annonceController.annonce.tailleItems}"/>

                                                         <a4j:ajax event="valueChange" render="valeur" execute="@this"/>









                                          <a4j:outputPanel id="valeur">

                                              <td class="libelle">

                                                  <h:outputText  value="Departement:"  rendered="#{not empty annonceController.regionA}" />





                                                  <h:selectOneMenu value="#{annonceController.choosedDepartment}" valueChangeListener="#{annonceController.departementChanged}"                                               rendered="#{annonceController.afficher_departement}" id="department">


                                                                   <f:selectItems value="#{annonceController.dept}"/>






















              my bean is here




              * To change this template, choose Tools | Templates

              * and open the template in the editor.


              package com.mycompany.biblio.controller;



              import com.mycompany.biblio.business.AnnonceEJB;

              import com.mycompany.biblio.business.BookEJB;

              import com.mycompany.biblio.model.Annonce;

              import com.mycompany.biblio.model.Book;

              import com.mycompany.biblio.model.Departement;

              import com.mycompany.biblio.model.Utilisateur;

              import java.io.*;

              import java.util.logging.Level;

              import java.util.logging.Logger;

              import javax.ejb.EJB;

              import javax.faces.application.FacesMessage;

              import javax.faces.bean.ManagedBean;

              import javax.faces.bean.SessionScoped;

              import javax.faces.component.html.HtmlDataTable;

              import javax.faces.context.ExternalContext;

              import javax.faces.context.FacesContext;

              import javax.faces.event.AjaxBehaviorEvent;

              import javax.faces.event.ValueChangeEvent;

              import javax.faces.model.ListDataModel;

              import javax.faces.model.SelectItem;

              import  org.apache.myfaces.trinidad.model.UploadedFile;



              * @author Mahamadi




              public class AnnonceController {



              public void regionChanged(ValueChangeEvent e){


                           FacesContext context = FacesContext.getCurrentInstance();


                                FacesMessage message;


                                if(null != e.getNewValue()){

                                  //assign new value to localeCode

                              if( (Integer.parseInt(e.getNewValue().toString()))==0){

                                  afficher_departement = false;


                                  afficher_departement = true;



                              message  = new FacesMessage("l_valider -------- = "+l_valider+ "  --- "+ regionA);

                                context.addMessage("xn jbnzmxvb nvzx", message);









              the function regionChanged() is working but web page is not rendered. When I press F5 page is rendered.

              PLease help me.