Friday, March 5, 2010

JSF reset form data when conversion fails

Problem:

My JSF form had some input text fields,one command link to another page, one command button for submit and one command button for reset. The text boxes accepts only Long values. I use a backing bean method in the action of reset button to reset the default values (pulled out from data base).

If character is entered in text box and a conversion error occured while sumbitting( save button) then if the user clicks reset or commandLink the same conversion error occurs. Because when we click reset or commandLink to another page, the page is going through the entire jsf life cycle where validtion and conversion happens before action. So we are getting the conversion error even if we try to reset the value.

We need the conversion error only when clicking save button and for reset , commandLink it should not throw any conversion error as these operations have nothing to do with the input data.

Solution:

Use immediate="true" with reset button and commandLink. With immediate attribute we are forcing the action to happen before conversion/validation occurs. Then the commandLink works fine as it is navigating to some other page. The reset button should show the same page with the default values set by the action method. This won't happen as expected. The submitted values will not be cleared even after reset. This is because the view is not getting rendered with immediate attribute. For this to happen we need to render the view explicitly in our code.

setting immediate attribute:


 <h:commandLink id="url_3" value="" immediate="true" action="#{BackingBean.approve}">Approve Page</h:commandLink>  
 <h:inputText size="4" value="#{BackingBean.productPrice}" converter="javax.faces.Long" converterMessage="Not a number"/>  
 <h:commandButton id="save" type="submit" value="Save" action="#{BackingBean.save}"/>  
 <h:commandButton id="reset" immediate="true" value="Reset" action="#{BackingBean.reset}"/>  
sample code to force the view in reset action method:
 public String reset(){  
   setInitialValues();  
   FacesContext context = FacesContext.getCurrentInstance();  
   Application application = context.getApplication();  
   ViewHandler viewHandler = application.getViewHandler();  
   UIViewRoot viewRoot = viewHandler.createView(context,context.getViewRoot().getViewId());  
   context.setViewRoot(viewRoot);  
   return "success" ;  
  }  
More information about immediate attribute:
Immediate attribute
More information about clearing input data:
Clear input component

Followers