I have a form with few input fields & a select one menu. All fields are required="true", firstName, lastName, emailAddress, password, country.
Test Case # 1:
1) Enter values in all input fields, leave firstName field without entering any value,
Select a country (eg: United States) and submit the form, we can see error message
for firstName field required.
2) Keep the form as it is, with leaving firstName field without entering any value, then select country to "select one", and submit the form. we can see error message for firstName & country fields, But where as in dropdown it did not show "Select One", it shows United States (the previous selection).
I have the same problem with input fields, but i solved with a converter. Is there a way to solve this one. I went with few posts in stackoverflow, came to know that it is a bug in mojarra.
Here is my code...
userRegistration.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core" >
<h:body>
<h:form id="registrationForm">
<h:messages layout="table" infoClass="infoMsgs" errorClass="errMsgs"/>
<table>
<tr>
<td>First Name:</td>
<td>
<h:inputText size="40" maxlength="100"
required="true"
styleClass="#{component.valid ? '' : 'text_error'}"
value="#{registrationAction.firstName}" />
</td>
</tr>
<tr>
<td>Last Name:</td>
<td>
<h:inputText size="40" maxlength="100"
required="true"
styleClass="#{component.valid ? '' : 'text_error'}"
value="#{registrationAction.lastName}" />
</td>
</tr>
<tr>
<td>Email Address:</td>
<td>
<h:inputText size="40" maxlength="100"
required="true"
styleClass="#{component.valid ? '' : 'text_error'}"
value="#{registrationAction.emailAddress}" />
</td>
</tr>
<tr>
<td>Password:</td>
<td>
<h:inputSecret size="20" maxlength="15"
required="true"
styleClass="#{component.valid ? '' : 'text_error'}"
value="#{registrationAction.password}" />
</td>
</tr>
<tr>
<td>Country:</td>
<td>
<h:selectOneMenu id="yourCountry" name="yourCountry"
value="#{shortRegistrationAction.shortRegistrationForm.selectedCountry}"
required="true"
styleClass="#{component.valid ? '' : 'text_error'}">
<f:selectItem itemValue="#{null}" itemLabel="-Select One-" />
<f:selectItems value="#{registrationAction.countryList}" />
</h:selectOneMenu>
</td>
</tr>
<tr>
<td> </td>
<td>
<h:commandButton name="RegisterButton" id="RegisterButton"
styleClass="submitbutton"
value="Register"
action="#{registrationAction.registerUser}" />
</td>
</table>
</h:form>
</h:body>
</html>
RegistrationAction.java
package com.ebiz.web.bean;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import com.ebiz.service.ICountryService;
import com.ebiz.service.IUserService;
import com.ebiz.vo.UserVO;
import org.apache.log4j.Logger;
@ManagedBean(name = "registrationAction")
@ViewScoped
public class RegistrationAction implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger log = Logger.getLogger(RegistrationAction.class);
@ManagedProperty("#{countryService}")
private ICountryService countryService;
@ManagedProperty("#{userService}")
private IUserService userService;
private String firstName;
private String lastName;
private String emailAddress;
private String password;
private String selectedCountry;
private List<String> countryList;
@PostConstruct
public void init(){
countryList = countryService.getCountryList();
}
public void registerUser() {
UserVO userVO = new UserVO();
userVO.setFirstName(firstName);
userVO.setLastName(lastName);
userVO.setEmailAddress(emailAddress);
userVO.setPassword(password);
userVO.setCountry(selectedCountry);
userService.registerUser(userVO);
}
}
InputTextTrimmer.java
package com.ebiz.web.converter;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
@FacesConverter(forClass=String.class)
public class InputTextTrimmer implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
//return value != null ? value.trim() : null;
if (value == null || value.trim().isEmpty()) {
if (component instanceof EditableValueHolder) {
((EditableValueHolder) component).setSubmittedValue(null);
((EditableValueHolder) component).resetValue();
}
return null;
}
return value;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return (value == null) ? null : value.toString();
}
}