5 Replies Latest reply: Feb 9, 2011 7:49 AM by rafael.sales RSS

modal panel rerendering bug?

Akaine Harga Novice

I'll try to be brief but it's somehow difficult to explain, though relatively easy to simulate.

 

Let's say we have a simple catalogue administration page:

<a4j:keepAlive beanName="controller_cars" />
<a4j:form id="form_cars">
     <rich:panel style="text-align: right;">
          <a4j:commandButton value="Add new" reRender="modal_car" action="#{controller_cars.prepareNewCar}" oncomplete="#{rich:component('modal_car')}.show();return false;"/>
     </rich:panel>
     <!-- some ther stuff including existant cars list, etc. -->
</a4j:form>

<rich:modalPanel id="modal_car" autosized="true" width="400">
     <f:facet name="header">
          <h:outputText value="Add new car" />
     </f:facet>
     <a4j:form id="form_car">
          <h:panelGrid columns="2">
               <h:outputText value="Model: *" />
               <h:inputText value="#{controller_cars.car.model}" size="25" maxlength="128" required="true" requiredMessage="- Car model is required" />
               <h:outputText value="Brand: *" />
               <rich:comboBox value="#{controller_cars.car.catBrand.idcatbrand}" defaultLabel="Put some value" converter="converterSI" width="152" required="true" requiredMessage="- Brand is required" validator="validator_cat" validatorMessage="- Invalid brand">
                    <f:selectItems value="#{controller_cars.brandsSI}" />
               </rich:comboBox>
               <h:outputText value="Year: *" />
               <rich:comboBox value="#{controller_cars.car.year}" defaultLabel="Put some value" converter="converterSI" width="152" required="true" requiredMessage="- Year is required" validator="validator_cat" validatorMessage="- Invalid year">
                    <f:selectItems value="#{controller_cars.yearsSI}" />
               </rich:comboBox>
               <h:outputText value="Price: *" />
               <rich:inputNumberSpinner value="#{controller_cars.car.price}" minValue="0.00" maxValue="999999.00" cycled="false" step="1000.00" inputSize="15" required="true" requiredMessage="- Price is required" validator="validator_notzero" validatorMessage="- The price must be above zero"/>
          </h:panelGrid>
          <div style="text-align: center;">
               <a4j:commandButton value="Save" type="submit" action="#{controller_cars.saveCar}" oncomplete="#{facesContext.maximumSeverity == null ? 'Richfaces.hideModalPanel(\'modal_car\');' : 'Richfaces.showModalPanel(\'modal_errors\')'};" reRender="form_cars" />
               <rich:spacer width="10" />
               <a4j:commandButton value="Cancel" ajaxSingle="true" type="button" action="#{controller_cars.flushCar}" oncomplete="#{rich:component('modal_car')}.hide();return false;" />
          </div>
     </a4j:form>
</rich:modalPanel>

 

And the backing bean:

public class ControllerCars {
     
     private List<Car> cars = new ArrayList<Car>(0);
     private List<SelectItem> brandsSI = new ArrayList<SelectItem>(0);
     private List<SelectItem> yearsSI = new ArrayList<SelectItem>(0);
     private Car car; //an entity bean with correspondant fields inside
     
     @EJB private CarFacadeLocal carFL;
     
     
     // VIEW METHODS =======================================
     public String loadPageCars(){
          return "LOAD_Cars";
     }
     
     //a method that is called every time the page is loaded using javascript
     public void reloadView(){
          car = null;
          cars = loadCars(); //a method that loads the cars list
          //some other stuff the page needs lo be loaded
     }
     
     
     // CAR MODAL ==========================================
     public void flushCar(){
          car = null;
          brandsSI.clear();
          yearsSI.clear();
     }
     
     public void prepareNewCar(){
          car = new Car(); //it's a default construtor, no fields initialized
          brandsSI = fillBrands(); //a private method to fill the list with SelectItems
          yearsSI = fillYears(); //same as above
     }
     
     public void saveCar(){
          carFL.save(car);
          flushCar();
          cars = loadCars();
     }
     
     // etc.
}

 

Looks pretty simple... Now, the actual error I've been experiencing since the beggining of times:

1. I click the "Add new" button and a modal opens (the car object is getting initialized)

2. I fill some data missing a field

3. I click "Save" and a modal_errors window pops up showing the list of errors (the required field I've missed for ex.)

4. I close the errors modal and click the "Cancel" button (the car object is getting nulled at this moment)

5. I click the "Add new" button again (the car object id getting initialized again with ampty fields) and the modal_car is opened

 

At this point the form_car will have the old values I left before I hit the "Cancel" button and I have no explanation for this.

- all methods are getting executed as they should

- I printed out the Car fields and they all have null value at the moment of initialization

- this happens in all popular browsers (FF,IE,Safari,Chrome,Opera)

- I have several corporate size applications based on this architecture and they all have this flaw while the rest is working perfectly fine

- the modal_errors is a simple modal panel with rich:messages inside and a button to close it, no events attached

 

My guess is that the temporal js backing bean fields counterparts are not getting wiped out when I press "Cancel" and somehow the error modal is affecting the process, since if I don't hit the "Save" button prior to "Cancel" the form is getting cleared as it should.

 

JSF 1.2, Facelets 1.1.15, RF 3.3.3 GA, Jboss 5.1 GA

 

Any ideas?