7

When the email address is invalid the message displayed is "Invalid email.Invalid email.". I know that the message has two parts: summary and a details. I need both of these, but I want to have different info in each. How can I change the message to display "Invalid email: Please enter a valid email address" instead?

<p:messages showDetail="true" autoUpdate="true" closable="true" />
<h:panelGrid columns="2">
    <h:outputText value="#{label.email}: *" />
    <p:inputText required="true" value="#{userWizard.emailAddress}"
        validatorMessage="#{label.invalidEmail}" label="#{label.email}">
        <f:validateRegex pattern="^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$">
        </f:validateRegex>
    </p:inputText>
</h:panelGrid>  
Seitaridis
  • 4,459
  • 9
  • 53
  • 85
  • If I change the validatorMessage to "Invalid email: Please enter a valid email email address" this text appears twice in the message displayed: Invalid email: Please enter a valid email addressInvalid email: Please enter a valid email address. – Seitaridis Nov 20 '12 at 07:06

2 Answers2

11

This is not possible with validatorMessage (neither converterMessage nor requiredMessage). The value will be used as both the summary and the detail.

You'd need to homegrow a custom validator instead wherein you can construct the FacesMessage with the both parts yourself. Assuming that you've next to the label.email also a label.email_detail which represents the message detail, then it should look something like this:

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

    private static final Pattern PATTERN = Pattern.compile("([^.@]+)(\\.[^.@]+)*@([^.@]+\\.)+([^.@]+)");

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        if (value == null || ((String) value).isEmpty()) {
            return; // Let required="true" handle.
        }

        if (!PATTERN.matcher((String) value).matches()) {
            String summary = context.getApplication().evaluateExpressionGet(context, "#{label.email}", String.class);
            String detail = context.getApplication().evaluateExpressionGet(context, "#{label.email_detail}", String.class);
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail));
        }
    }

}

(note that I adapted the email regexp for better preparation on world domination; non-latin characters like Chinese, Hebrew, Cyrillic, etc are namely allowed in domain names and thus also email addresses since the new IANA decision in 2010)

which is then to be used as

<p:inputText ... validator="emailValidator" />
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I have tested your solution and it works. I have changed two parts. The `required=true` has also the same problem as the `validatorMessage`(it displays the same text twice), so I have handled the empty string value validation with the same email regex. `String` class has a `matches` method and I have used that method instead of the `Pattern` class. – Seitaridis Nov 20 '12 at 12:31
  • 1
    You're welcome. The `required="true"` would only have that problem when its summary and detail are exactly the same. You should then alter `javax.faces.component.UIInput.REQUIRED` and `javax.faces.component.UIInput.REQUIRED_DETAIL` properties of JSF ``. See also http://www.mkyong.com/jsf2/customize-validation-error-message-in-jsf-2-0/ – BalusC Nov 20 '12 at 12:32
  • As to the `Pattern` approach, I'm perfectly aware about `String#matches()`, but it recompiles the pattern everytime which is a quite expensive job. Compiling it once as constant and then reusing it is much faster. It's just a performance improvement approach. – BalusC Nov 20 '12 at 12:35
  • Thanks a lot. I will look over your recommendations. – Seitaridis Nov 20 '12 at 12:55
  • 1
    I would vote ten times for your answer. It helped me a lot. I have run into some troubles recently because of REQUIRED_DETAIL. I think it should be REQUIRED_detail. – Seitaridis Jan 11 '13 at 12:53
5

According to the documentation here : http://www.primefaces.org/docs/vdl/3.4/primefaces-p/messages.html

You could do something like that :

<p:messages showSummary="true" showDetails="true" />

You can also put them apart... for styling :

<p:messages showSummary="false" showDetails="true" />
<p:messages showSummary="true" showDetails="false" />

But you can't define the two error messages with validatorMessage :

http://www.primefaces.org/docs/vdl/3.4/primefaces-p/inputText.html

Alexandre Lavoie
  • 8,711
  • 3
  • 31
  • 72