gustavomr
gustavomr

Reputation: 89

jsf view not validating ajax blur

I have a ajax event blur that validate if a email already exist on database and it works.

<h:outputText value="Email:" />
<p:inputText id="email" value="#{pessoaBean.pessoa.email}"  
    required="true" requiredMessage="Informar o email."
    validatorMessage="Formato de email inválido" >
    <p:ajax event="blur"  listener="#{pessoaBean.verificaEmail}" 
        update="mensagens" />
    <f:validateRegex
        pattern="^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$" />
</p:inputText>

Bean Method:

public void verificaEmail() {

    if (new PessoaDao().verificaEmail(pessoa) == true) {
        FacesContext.getCurrentInstance().addMessage("formCadastrar:email",
                new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error",
                "email already exist"));

    }

}

When I submit my form with commandbutton it passes through my ajax validaton and submit my form even it have my error message displayed on screen.

My button code:

<p:commandButton value="Cadastrar"
    actionListener="#{pessoaBean.cadastrar}"
    update=":formPrincipal:tabelaPessoas,formCadastrar"
    oncomplete="if (!args.validationFailed){PF('dialogCadastrar').hide();} " 
    />

What happened here?

Upvotes: 0

Views: 824

Answers (1)

Aritz
Aritz

Reputation: 31669

Don't do the validation work in a listener method, as JSF has proper validators for that. Acording to the official docs:

Individual Validators should examine the value and component that they are passed, and throw a ValidatorException containing a FacesMessage, documenting any failures to conform to the required rules.

So let's implement the one you need:

@FacesValidator("emailValidator")
public class EmailValidator implements Validator{

    @Override
    public void validate(FacesContext context, UIComponent component,
            Object value) throws ValidatorException {

                if (new PessoaDao().verificaEmail(value.toString()) == true) {
                    throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error",
                            "email already exist"));
                }

        }

    }
}

Then, you only need to attach the validator to the input you're interested in:

<p:inputText id="email" value="#{pessoaBean.pessoa.email}"  
    required="true" requiredMessage="Informar o email."
    validatorMessage="Formato de email inválido" validator="emailValidator" />

This could of course be improved, you could add the regex validation into the code itself and also implement your own e-mail input composite component to be reused, with the validator already included.

See also:

Upvotes: 3

Related Questions