Introduction
There are scenarios where you want to depend the "requireness" (between quotes, this word doesn't occur in an English dictionary) of an UIInput element on the UICommand action invoked. There are also a lot of hacks and workarounds written about it, e.g. using immediate="true" and valueChangeListener or binding attributes to retain the value (which gives you only two scenario cases) or moving the validation to the backing bean actions (which gives you endless scenario cases), etcetera.
Those workarounds require extra logic in the backing bean. It would be great if JSF offers an default possibility to let the requireness of the UIInput depend on the UICommand action invoked. Having an attribute like requiredActions which accepts a commaseparated string of the ID's of the buttons would be great. Unfortunately such an attribute isn't available. But don't feel disappointed, there is a possibility to use the request parameter map to determine which UICommand action invoked. Its client ID is namely available in the request parameter map. So just checking the presence of the client ID in the #{param} ought to be enough. KISS! ;)
Back to top
Basic JSF example
Here is a sample form. It represents a login form with two input fields and two buttons. The username as well as the password fields are required when you press the "Login" button, while the password field isn't required when you press the "Forget password" button. This is done by checking the presence of the client ID of the "Login" button in the required attribute of the password field. You can also check the absence of the client ID of the "Forget password" button as well.
The stuff is tested in a Java EE 5.0 environment with Tomcat 6.0 with Servlet 2.5, JSP 2.1 and JSF 1.2_07 (currently called Mojarra).
<h:form id="form"> <h:panelGrid columns="3"> <h:outputLabel for="username" value="Username" /> <h:inputText id="username" value="#{myBean.username}" required="true" /> <h:message for="username" style="color: red;" /> <h:outputLabel for="password" value="Password" /> <h:inputSecret id="password" value="#{myBean.password}" required="#{!empty param['form:login']}" /> <h:message for="password" style="color: red;" /> <h:panelGroup /> <h:panelGroup> <h:commandButton id="login" value="Login" action="#{myBean.login}" /> <h:commandButton id="forget" value="Forget password" action="#{myBean.forget}" /> </h:panelGroup> <h:message for="form" style="color: green;" /> </h:panelGrid> </h:form>
The appropriate test backing bean (request scoped) look like:
package mypackage; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; public class MyBean { // Init --------------------------------------------------------------------------------------- private String username; private String password; // Actions ------------------------------------------------------------------------------------ public void login() { // Just for debug. Don't do this in real! Hash the password, compare in DB and forget it ;) System.out.println("Login username: " + username); System.out.println("Login password: " + password); // Show succes message. FacesContext.getCurrentInstance().addMessage("form", new FacesMessage("Login succesful!")); } public void forget() { // Just for debug. System.out.println("Forget username: " + username); // Show succes message. FacesContext.getCurrentInstance().addMessage("form", new FacesMessage("New password sent!")); } // Getters ------------------------------------------------------------------------------------ public String getUsername() { return username; } public String getPassword() { return password; } // Setters ------------------------------------------------------------------------------------ public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } }
Now, when you hit the "Login" button, it will validate the username as well as the password fields, but when you hit the "Forget password" button, it will validate the username field only!
Back to top
Copyright - There is no copyright on the code. You can copy, change and distribute it freely. Just mentioning this site should be fair.
(C) December 2007, BalusC