javing
javing

Reputation: 12413

JSF 2.0 Custom Validation problem

I want to validate the inputs to my JSF page inside my Managed bean, but for some reason it does not work?

@ManagedBean
@RequestScoped
public class RegistrationController {
//values passed from the JSF page
private String name; 
...
public void validateName(FacesContext context, UIComponent validate,
        Object value) {
    String inputFromField = (String) value;
    String simpleTextPatternText = "^[a-zA-Z0-9]+$";
    Pattern textPattern = null;
    Matcher nameMatcher = null;
    textPattern = Pattern.compile(simpleTextPatternText);
    nameMatcher = textPattern.matcher(getName());

    if (!nameMatcher.matches()) {
        ((UIInput) validate).setValid(false);
        FacesMessage msg = new FacesMessage(
                "your name cant contain special characters");
        context.addMessage(validate.getClientId(), msg);
    }
}

This is how input component looks like(Inside a form):

<h:inputText value="#{registrationController.name}" validator="#{registrationController.validateName}" required="true">
        <h:message for="nameInput"/>

When i enter a wrong input i dont see the validation message, and in the console i see this:

INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver. INFO: WARNING: FacesMessage(s) have been enqueued, but may not have been displayed. sourceId=bRegForm:j_idt7[severity=(ERROR 2), summary=(bRegForm:j_idt7: Validation Error: Value is required.), detail=(bRegForm:j_idt7: Validation Error: Value is required.)]

What it could be? Am i forgetting something? Do i have to add something to my configuration files...?

Upvotes: 2

Views: 4028

Answers (1)

BalusC
BalusC

Reputation: 1108537

You forgot to give your input component an id. That's where the for attribute of <h:message> should point to.

<h:inputText id="nameInput">

Unrelated to the concrete problem, your approach is clumsy and technically wrong. As per the specification, you should throw a ValidatorException. So instead of

((UIInput) validate).setValid(false);
context.addMessage(validate.getClientId(), msg);

do

throw new ValidatorException(msg);

Then JSF will worry about setting the component as invalid and adding the message to the context.


There's a second problem, you're validating the local value instead of the submitted value.

Replace

nameMatcher = textPattern.matcher(getName());

by

nameMatcher = textPattern.matcher(inputFromField);

Upvotes: 4

Related Questions