0

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).

Tiny
  • 27,221
  • 105
  • 339
  • 599

2 Answers2

2

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."));
    }
  }
}
rion18
  • 1,211
  • 16
  • 22
  • A custom validator is the last stage. I will use a custom validator, if I find no in-built way :) – Tiny Jun 19 '14 at 15:24
1

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.

kolossus
  • 20,559
  • 3
  • 52
  • 104
  • Sorry, nothing new happens by using `disabled="#{empty theAddress.getSubmittedValue()}"`. `theAddress.getSubmittedValue()` always remains empty. – Tiny Jun 19 '14 at 14:02
  • @Tiny - that's weird. Try a different condition: `#{theAddress.isLocalValueSet()}`. This returns a boolean. – kolossus Jun 19 '14 at 15:08
  • `#{theAddress.isLocalValueSet()}` returns `true` even though `` is left blank (no input is provided to ``). – Tiny Jun 19 '14 at 15:21
  • The validator was rightfully disabled, when I used `disabled="#{empty param['form:address']}"`. It is still inappropriate to depend directly upon request parameters. – Tiny Jun 19 '14 at 18:05
  • 1
    @Tiny - I believe the reason the empty text is failing to validate properly is related to : http://stackoverflow.com/q/14607439/1530938 – kolossus Jun 20 '14 at 14:45