Reputation: 27899
I need to validate a length of the value held by a UIInput
component only if the value of that UIInput
component is either null
or an empty.
The length validator - <f:validateLength>
should be skipped / bypassed, in case the value is null
or empty.
I have tried the following approach with no success.
<p:inputTextarea id="address" autoResize="false" value="#{testManagedBean.address}" maxlength="1000" minQueryLength="10" cols="35" rows="7">
<f:validateLength minimum="5" maximum="1000" disabled="#{empty testManagedBean.address}"/>
</p:inputTextarea>
<p:message for="address" display="both" showSummary="false"/>
<p:commandButton value="Submit" actionListener="#{testManagedBean.action}"/>
The bean:
@ManagedBean
@ViewScoped
public final class TestManagedBean implements Serializable
{
private String address;
private static final long serialVersionUID = 1L;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public void action() {
System.out.println("action() called.");
}
}
This field - "address" is actually optional but if some users provide an input then, it should contain minimum of five characters in length.
EDIT:
I'm using disabled="#{empty param['form:address']}"
to disable the validator, when the UIInput
component has a null or empty value (not to dig further for a better way as this works anyway).
Upvotes: 0
Views: 5345
Reputation: 20691
You're on the right track, but you're not pulling the value off the component properly.
Bind the component to the page scope and retrieve the value like so:
<p:inputTextarea id="address" binding="#{theAddress}" autoResize="false" value="#{testManagedBean.address}" maxlength="1000" minQueryLength="10" cols="35" rows="7">
<f:validateLength minimum="5" maximum="1000" disabled="#{empty theAddress.getSubmittedValue()}"/>
</p:inputTextarea>
Your current approach requires the textArea's value to be written to the backing bean. This can't happen until validation occurs (remember: testManagedBean.address
is available only after successful validation); you're expecting that same value during validation: catch 22.
Upvotes: 1
Reputation: 1221
No need for OmniFaces: you can create your own validator. You have to create a class that implements the javax.faces.validator.Validator
interface, overrides the validate()
method, and call it in your xhtml
page. An alternative would be:
<p:inputTextarea id="address" autoResize="false" value="#{testManagedBean.address}" maxlength="1000" minQueryLength="10" cols="35" rows="7">
<f:validator validatorId="myValidator"/>
</p:inputTextarea>
The validator class:
@FacesValidator("myValidator")
public class MyValidator Validator{
@Override
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
String myValue = value.toString();
if(myValue != null && !myValue.isEmpty() && (myValue.length() <= 5 || myValue.length() >= 1000)){
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
"MyValidator Error: ",
"This error appears if your input has less than 5 chars or more than 1000."));
}
}
}
Upvotes: 2