Duplicate text in <p:messages> summary and detail

Seitaridis picture Seitaridis · Nov 20, 2012 · Viewed 13.3k times · Source

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>  

Answer

BalusC picture BalusC · Nov 20, 2012

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" />