2 Replies Latest reply on Apr 25, 2009 8:24 PM by Pucky Loucks

    I've got something wrong with form and outputPanel

    Pucky Loucks Newbie

      I Have a form that has radio button in it for users to select and option, and when they do it reRender's an output panel that contains other fields for the form.


      the problem is that when the user fills out the form and selects the Radio option and then sees the new fields, and fills them out, they aren't included in the post. i.e. the object is null in the EJB.  Any ideas?



      Form



      <h:form id="childinfo">
                          <fieldset id="child">
                          <legend>Learner's Legal Name</legend>
                          <ul>
                               <li>
                                    <s:decorate id="firstname" template="/layout/edit.xhtml">
                                         <ui:define name="label">First Name</ui:define>
                                         <h:inputText id="learnerfirstname" required="true" value="#{learner.firstname}"/>
                                    </s:decorate>
                               </li>
                               <li>
                                    <h:outputLabel value="Middle Name(s)" for="learnermiddlename"/>
                                    <h:inputText value="#{learner.middlename}" id="learnermiddlename"/>
                               </li>
                               <li>
                                    <s:decorate id="lastname" template="/layout/edit.xhtml">
                                         <ui:define name="label">Last Name</ui:define>
                                         <h:inputText value="#{learner.lastname}" required="true" id="learnerlastname"/>
                                    </s:decorate>
                               </li>
                               <li class="date">
                                    <s:decorate id="learnerbirthdatedecorate" template="/layout/edit.xhtml">
                                    <ui:define name="label">Date of Birth (YYYY/MM/dd/)</ui:define>
                                         <rich:calendar required="true"  id="learnerbirthdate" enableManualInput="true" datePattern="yyyy/MM/dd" value="#{learner.birthdate}"/>
                                    </s:decorate>
                                </li>
                               <li class="gender">
                                    <s:decorate id="gender" template="/layout/edit.xhtml">
                                         <ui:define name="label">Sex</ui:define>
                                         <h:selectOneMenu id="selectGender" required="true" value="#{learner.gender}">
                                              <f:selectItem itemValue="F" itemLabel="Female"/>
                                              <f:selectItem itemValue="M" itemLabel="Male"/>
                                         </h:selectOneMenu>
                                    </s:decorate>
                               </li>
                               <li class="confirm">
                                    <s:decorate template="/layout/edit-reversed.xhtml">
                                         <ui:define name="label">&#160;I have entered the above information matching the birth certificate exactly.</ui:define>
                                         <h:selectBooleanCheckbox value="#{learner.matchbirthcert}" required="true" id="matchbirthcert"/>
                                    </s:decorate>
                               </li>
                               <li>&#160;<br />
                                    <h:outputLabel value="Usual Name" for="usualfirstname"/>
                                    <h:inputText id="usualfirstname" value="#{learner.usualname}"/>
                               </li>
                          </ul>
                          </fieldset>
                          
                          <fieldset>
                               <legend>Program Options</legend>
                               
                               <a4j:region>
                               <s:decorate id="programdivision" template="/layout/edit.xhtml">
                                    <h:selectOneRadio value="#{programDivision}" required="true" layout="pageDirection">
                                         <s:selectItems var="programDivision" value="#{programDivisionList.resultList}"  label="#{programDivision.enrollmentQuestion}"></s:selectItems>
                                         <s:convertEntity></s:convertEntity>
                                         <a4j:support event="onchange" reRender="programoutput,k12,hlnPannel"></a4j:support>
                                    </h:selectOneRadio>
                               </s:decorate>
                               </a4j:region>
                          </fieldset>
           
                     
                     
                          <a4j:outputPanel id="programoutput">
                               <a4j:outputPanel id="k12" rendered="#{programDivision.name eq 'k-9' || programDivision.name eq '10-12'}">
                                    <fieldset id="medical">
                                    <legend>Medical Information</legend>
                                    <ul>
                                         <li>
                                         <a4j:region>
                                              <s:decorate template="/layout/edit.xhtml">
                                                   <ui:define name="label">Medical Number</ui:define>
                                                   <h:inputText value="#{medicalinformation.medicalnumber}" required="true" id="learnermedicalnumber"/>
                                              </s:decorate>
                                         </a4j:region>
                                         </li>
                                         <li>
                                              <s:decorate id="doctorname" template="/layout/edit.xhtml">
                                                   <ui:define name="label">Doctor Name</ui:define>
                                                   <h:inputText value="#{medicalinformation.doctorname}" required="true" id="learnerdoctorname"/>
                                              </s:decorate>
                                         </li>
                                         <li>
                                              <h:outputLabel value="Medical Condition" for="medicalcondition"/>
                                              <h:inputTextarea id="medicalcondition" value="#{medicalinformation.medicalcondition}" style="width:668px; height:57px;"/>
                                         </li>
                                    </ul>
                                    </fieldset>
      
                                              
                          
                          </a4j:outputPanel>
                          <a4j:outputPanel id="hlnPannel" rendered="#{programDivision.name eq 'HLN'}">
                          
                          
                          <fieldset id="optionalinfo">
                          <legend>Optional Services</legend>
                               <ul>
                               <li>
                                    <s:decorate id="photoid" template="/layout/edit-reversed.xhtml">
                                         <ui:define name="label"> Photo ID </ui:define>
                                         <h:selectBooleanCheckbox value="#{learner.photoid}" />
                                    </s:decorate>
                                    &#160; </li>
                               <li>
                                    <s:decorate id="gocard" template="/layout/edit-reversed.xhtml">
                                         <ui:define name="label">aCard.</ui:define>
                                         <h:selectBooleanCheckbox value="#{learner.gocard}"/>
                                    </s:decorate>
                                    &#160; </li>
                               <li>
                                    <s:decorate id="villageaccount" template="/layout/edit-reversed.xhtml">
                                         <ui:define name="label">Account. </ui:define>
                                         <h:selectBooleanCheckbox value="#{learner.villageaccount}"/>
                                    </s:decorate>
      
                               </li>
                          </ul>
                          
                          </fieldset>
                      
                          </a4j:outputPanel>
                          </a4j:outputPanel>
                          
                  <h:commandButton action="#{enrollmentProcess.addLearner}" value="Add Learner"/>
                          
                          
                     </h:form>
      



      EJB


      package com.selfdesign.sdlcextranet.session;
      
      import ....
      
      @Stateful
      @Name("enrollmentProcess")
      public class EnrollmentProcessBean implements Serializable, EnrollmentProcess {
           
      
           private static final long serialVersionUID = -2819661205144201835L;
      
           private String enrollmentYearName;
           private String organizationName;
           private String programName;
           private Program program;
      
           @PersistenceContext(type=PersistenceContextType.EXTENDED)
               private transient EntityManager em;
           
      
               @Logger private transient Log log;
                
      
               @SuppressWarnings("unused")
                @In private transient FacesMessages facesMessages;
           
           @RequestParameter
           String id;
           
           
           @In(create=true)
           @Out
           private Family family;
           
           @In(create=true)
           @Out
           private Parent parent;
           
           @In(create=true)
           @Out
           private Address address;
           
           @In(create=true)
           @Out
           private Learner learner;
           
           @In(create=true)
           private FamilyYearlyAgreement familyyearlyagreement;
           
           @In(create=true)
           private FamilyEnrollmentSurvey familyenrollmentsurvey;
           
           @In(create=true)
           @Out
           private MedicalInformation medicalinformation;
           
           @In(create=true)
           @Out
           private SpecialEdLearner specialedlearner;
           
           @In(create=true)
           @Out
           private ProgramDivision programDivision;
      
           
           @Out
           private Map<YearlyAgreement, Boolean> selectedAgreements = new HashMap<YearlyAgreement, Boolean>();
           
           @Transient
          @In(create=true)
          private Renderer renderer;
          
           @Transient
          @In
          FacesContext facesContext;
      
           
           
           public Map<YearlyAgreement, Boolean> getSelectedAgreements() {
                return selectedAgreements;
           }
      
          other methods.....
      
           public String addLearner(){
                log.info("add learner: #0",this.family.getFamilyid());
                
                Query q = em.createNamedQuery("findFamily").setParameter("familyid", this.family.getFamilyid());
                this.family = (Family) q.getSingleResult();
                
                this.learner.setMedicalinformation(medicalinformation);
                
                if(this.specialedlearner.isSpecialedfundsotherschool()){
                     this.specialedlearner.setSpecialedgrant(true);
                }
      
                this.learner.setSpecialedlearner(this.specialedlearner);
                
                Query familyQuery = em.createNamedQuery("findFamily").setParameter("familyid", this.family.getFamilyid());
                this.family = (Family) familyQuery.getSingleResult();
                
                Query organizationQuery = em.createNamedQuery("findOrganization").setParameter("name", this.getOrganizationName());
                Organization org = (Organization)organizationQuery.getSingleResult();
                
                Program program =null;
                
                Iterator<Program> programList = org.getProgramList().iterator();
                
                while(programList.hasNext()){
                     Program tempProgram = programList.next();
                     if(tempProgram.equals(this.program)){
                          program = tempProgram;
                          break;
                     }
                     
                }
                
                EnrollmentYear year = null;
                
                Iterator<EnrollmentYear> yearlist = program.getEnrollmentYearList().iterator();
                
                while(yearlist.hasNext()){
                     EnrollmentYear tempyear = yearlist.next();
                     if(tempyear.getName().equalsIgnoreCase(this.getEnrollmentYearName())){
                          year = tempyear;
                          break;
                     }
                }
      
      
           
      
                     LearnerEnrollment le = new LearnerEnrollment();
                     le.setActive(true);
                     le.setApplicationDate(new Date());
                     le.setLearner(this.learner);
                     le.setEnrollmentyear(year);
                     le.setProgram(program);
                     le.setProgramDivision(programDivision);
                     programDivision.getLearnerEnrollmentList().add(le);
                     
                     this.learner.getLearnerEnrollmentList().add(le);
           
                
                this.family.addLearner(this.learner);
      
                this.family.setSpecialedfamily(this.learner.isSpecialEd());
                
                
                
                
                
                
                
                
                
                
                em.persist(this.family);
                
                String response = "added";
      
                if(specialedlearner.isHighincidence())
                {
                     response = "highincidence";
                }
                else if(specialedlearner.isPossibleLowIncidence())
                {
                     response = "lowincidence";
                }
                else
                {
                     this.learner = null;
                     this.learner = new Learner();
      
                     this.medicalinformation = null;
                     this.medicalinformation = new MedicalInformation();
                     this.specialedlearner = null;
                     this.specialedlearner = new SpecialEdLearner();
                     this.programDivision = null;
                     this.programDivision = new ProgramDivision();
                }
                
      
      
                
                
                return response;
           }
           
           
           etc...
      }
      
      



      Entity


      
      import java.io.Serializable;
      
      import javax.persistence.Entity;
      import javax.persistence.GeneratedValue;
      import javax.persistence.Id;
      import javax.persistence.Version;
      
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Scope;
      
      @Entity
      @Name("medicalinformation")
      @Scope(ScopeType.CONVERSATION)
      public class MedicalInformation implements Serializable {
      
           /**
            * 
            */
           private static final long serialVersionUID = 1L;
           private Long medicalinformationid;
           private Integer version;
           private String medicalnumber;
           private String doctorname;
           private String medicalcondition;
           
           public MedicalInformation()
           {
                
           }
           
           @Id @GeneratedValue
           public Long getMedicalinformationid() {
                return medicalinformationid;
           }
           public void setMedicalinformationid(Long medicalinformationid) {
                this.medicalinformationid = medicalinformationid;
           }
           
           @Version
           public Integer getVersion() {
                return version;
           }
           public void setVersion(Integer version) {
                this.version = version;
           }
           public String getMedicalnumber() {
                return medicalnumber;
           }
           public void setMedicalnumber(String medicalnumber) {
                this.medicalnumber = medicalnumber;
           }
           public String getDoctorname() {
                return doctorname;
           }
           public void setDoctorname(String doctorname) {
                this.doctorname = doctorname;
           }
           public String getMedicalcondition() {
                return medicalcondition;
           }
           public void setMedicalcondition(String medicalcondition) {
                this.medicalcondition = medicalcondition;
           }
      
           @Override
           public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result
                          + ((doctorname == null) ? 0 : doctorname.hashCode());
                result = prime
                          * result
                          + ((medicalcondition == null) ? 0 : medicalcondition.hashCode());
                result = prime
                          * result
                          + ((medicalinformationid == null) ? 0 : medicalinformationid
                                    .hashCode());
                result = prime * result
                          + ((medicalnumber == null) ? 0 : medicalnumber.hashCode());
                result = prime * result + ((version == null) ? 0 : version.hashCode());
                return result;
           }
      
           @Override
           public boolean equals(Object obj) {
                if (this == obj)
                     return true;
                if (obj == null)
                     return false;
                if (getClass() != obj.getClass())
                     return false;
                final MedicalInformation other = (MedicalInformation) obj;
                if (doctorname == null) {
                     if (other.doctorname != null)
                          return false;
                } else if (!doctorname.equals(other.doctorname))
                     return false;
                if (medicalcondition == null) {
                     if (other.medicalcondition != null)
                          return false;
                } else if (!medicalcondition.equals(other.medicalcondition))
                     return false;
                if (medicalinformationid == null) {
                     if (other.medicalinformationid != null)
                          return false;
                } else if (!medicalinformationid.equals(other.medicalinformationid))
                     return false;
                if (medicalnumber == null) {
                     if (other.medicalnumber != null)
                          return false;
                } else if (!medicalnumber.equals(other.medicalnumber))
                     return false;
                if (version == null) {
                     if (other.version != null)
                          return false;
                } else if (!version.equals(other.version))
                     return false;
                return true;
           }
           
           
           
      }
      
      


        • 1. Re: I've got something wrong with form and outputPanel
          Arbi Sookazian Master

          1) which object is null when the user submits the form?  If validation phase succeeds, JSF executes the update model values phase prior to executing the Invoke application (i.e. action method).  So add debug breakpoints for the relevant setter methods and go from there.


          2) this code is strange


          @PersistenceContext(type=PersistenceContextType.EXTENDED)
          private transient EntityManager em;
          



          Why aren't you using SMPC with @In?  You don't need the transient keyword b/c if you are using Hibernate as your persistence provider, then org.hibernate.ejb.EntityManagerImpl implements the javax.persistence.EntityManager interface, and EntityManagerImpl is serializable.


          3) I'm pretty sure you don't need the transient keyword for Log object either:


          http://www.redhat.com/docs/manuals/jboss/jboss-eap-4.3/doc/seam/api/org/jboss/seam/log/LogImpl.html


          4) prefer the JDK 5 for : each construct over Iterator:


          http://java.sun.com/j2se/1.5.0/docs/guide/language/foreach.html


          example (be sure to check for nulls as required):


          Iterator<Program> programList = org.getProgramList().iterator();
                    
                    while(programList.hasNext()){
                         Program tempProgram = programList.next();
                         if(tempProgram.equals(this.program)){
                              program = tempProgram;
                              break;
                         }
                         
                    }
                    
                    
          for (Program tempProgram : org.getPromList()) {
          
               
               if(tempProgram.equals(this.program)){
                    program = tempProgram;
                    break;
               }
               
          
          }



          5) avoid excessive use of @Outjection, it undermines loosely-couple components (there is a thread on this forum about that).

          • 2. Re: I've got something wrong with form and outputPanel
            Pucky Loucks Newbie

            Thanks for your response,


            The code that is null is the following.


            snippet from EJB


            public String addLearner(){
            log.info("add learner: #0",this.family.getFamilyid());
                      
            Query q = em.createNamedQuery("findFamily").setParameter("familyid", this.family.getFamilyid());
            this.family = (Family) q.getSingleResult();
                      
            this.learner.setMedicalinformation(medicalinformation);<== NULL HERE and others objects from the page, medicalinformation is empty, even though on the page it was filled in.
            



            If I removed the a4j:outputPanel then everything works fine, the problem is that I'm not wanting to show the medical information fields (wrapped in a fieldset) unless they have chosen a specific radio button. 


            FLOW is like this.


            1) user fills out learner's legal name info
            2) user selects which program to enroll in (ala programDivsion)


            3) reRender programoutput
            3a) if programDivision is k-9 render k12
            3b) if programDivision is 10-12 render k12
            3c) if programDivision is hln render hlnPannel



            The problem is that all the fields h:inputText's even if they are filled out are empty inside enrollmentProcess.addLearner() method (the EJB).


            again if I remove the a4j:outputPanel's and rerun the page, everything works, but I see items in the form that I shouldn't, because they are suppose to be hidden until the specific radio was selected (i.e. programDivision)


            Regarding all the cleanup ideas, ya this a very old system that I'm revisiting and  will have to revisit when I have time.


            Thanks