A custom client converter or a validator can be implemented easily. Both JSF and Bean Validation APIs are supported.
<script>
//<![CDATA[
/**
* Faces Validator
*/
PrimeFaces.validator['custom.emailValidator'] = {
pattern: /\S+@\S+/,
validate: function (element, value) {
//use element.data() to access validation metadata, in this case there is none.
if (!this.pattern.test(value)) {
throw {
summary: 'Validation Error',
detail: value + ' is not a valid email.',
severity: 'error'
}
}
}
};
/**
* Bean validator
*/
PrimeFaces.validator['Email'] = {
pattern: /\S+@\S+/,
MESSAGE_ID: 'org.primefaces.examples.validate.email.message',
validate: function (element, value) {
var vc = PrimeFaces.validation.ValidationContext;
if (!this.pattern.test(value)) {
var msgStr = element.data('p-email-msg'),
msg = msgStr ? {summary: 'Validation Error', detail: msgStr, severity: 'error'} : vc.getMessage(this.MESSAGE_ID);
throw msg;
}
}
};
//]]>
</script>
<div class="card">
<h:form>
<p:growl showDetail="true"/>
<h:panelGrid columns="4" cellpadding="7">
<p:outputLabel for="email1" value="Email 1: (JSF Validation)"/>
<p:inputText id="email1" value="#{customValidationView.text}">
<f:validator validatorId="custom.emailValidator"/>
</p:inputText>
<p:message for="email1" display="tooltip"/>
<h:outputText value="#{customValidationView.text}"/>
<p:outputLabel for="email2" value="Email 2: (Bean Validation)"/>
<p:inputText id="email2" value="#{customValidationView.email}"/>
<p:message for="email2" display="tooltip"/>
<h:outputText value="#{customValidationView.email}"/>
</h:panelGrid>
<p:commandButton value="Save" ajax="false" icon="pi pi-check" validateClient="true" styleClass="mt-3" />
</h:form>
</div>
package org.primefaces.showcase.view.csv;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
import io.quarkus.runtime.annotations.RegisterForReflection;
@Named
@RequestScoped
@RegisterForReflection(serialization = true)
public class CustomValidationView {
private String text;
@Email(message = "must be a valid email")
private String email;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
package org.primefaces.showcase.view.csv;
import java.util.Map;
import java.util.regex.Pattern;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.validator.FacesValidator;
import jakarta.faces.validator.Validator;
import jakarta.faces.validator.ValidatorException;
import org.primefaces.validate.ClientValidator;
/**
* Custom JSF Validator for Email input
*/
@FacesValidator("custom.emailValidator")
public class EmailValidator implements Validator, ClientValidator {
private static final String EMAIL_PATTERN = """
^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@\
[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$\
""";
private Pattern pattern;
public EmailValidator() {
pattern = Pattern.compile(EMAIL_PATTERN);
}
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (value == null) {
return;
}
if (!pattern.matcher(value.toString()).matches()) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Validation Error",
value + " is not a valid email;"));
}
}
@Override
public Map<String, Object> getMetadata() {
return null;
}
@Override
public String getValidatorId() {
return "custom.emailValidator";
}
}
package org.primefaces.showcase.view.csv;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import org.primefaces.validate.bean.ClientConstraint;
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = EmailConstraintValidator.class)
@ClientConstraint(resolvedBy = EmailClientValidationConstraint.class)
@Documented
public @interface Email {
String message() default "{org.primefaces.examples.primefaces}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
package org.primefaces.showcase.view.csv;
import java.util.regex.Pattern;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
/**
* ConstraintValidator for @Email
*/
public class EmailConstraintValidator implements ConstraintValidator<Email, String> {
private static final String EMAIL_PATTERN = """
^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@\
[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$\
""";
private Pattern pattern;
@Override
public void initialize(Email a) {
pattern = Pattern.compile(EMAIL_PATTERN);
}
@Override
public boolean isValid(String value, ConstraintValidatorContext cvc) {
if (value == null) {
return true;
}
else {
return pattern.matcher(value).matches();
}
}
}
package org.primefaces.showcase.view.csv;
import io.quarkus.runtime.annotations.RegisterForReflection;
import org.primefaces.validate.bean.AbstractClientValidationConstraint;
/**
* ClientValidationConstraint for @Email annotation
*/
@RegisterForReflection
public class EmailClientValidationConstraint extends AbstractClientValidationConstraint {
public static final String MESSAGE_METADATA = "data-p-email-msg";
public EmailClientValidationConstraint() {
super(null, MESSAGE_METADATA);
}
@Override
public String getValidatorId() {
return Email.class.getSimpleName();
}
}