modal panel rerendering bug?
akaine Nov 6, 2010 6:20 PMI'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?