Client Side Validation Framework is integrated with Bean Validation Specification.
<div class="card">
    <h:form>
        <p:messages/>
        <h:panelGrid columns="4" cellpadding="7" styleClass="mb-3">
            <p:outputLabel for="@next" value="Name: (@Size(min=2,max=5))"/>
            <p:inputText value="#{beanValidationView.name}" label="Name"/>
            <p:message for="@previous"/>
            <h:outputText value="#{beanValidationView.name}"/>
            <p:outputLabel for="@next" value="Age: (@Min(10) @Max(20))"/>
            <p:inputText value="#{beanValidationView.age}" label="Age"/>
            <p:message for="@previous"/>
            <h:outputText value="#{beanValidationView.age}"/>
            <p:outputLabel for="@next" value="Amount: (@DecimalMax('99.9'))"/>
            <p:inputText value="#{beanValidationView.amount}" label="Amount"/>
            <p:message for="@previous"/>
            <h:outputText value="#{beanValidationView.amount}"/>
            <p:outputLabel for="@next" value="Amount: (@Digits(integer=3,fraction=2))"/>
            <p:inputText value="#{beanValidationView.amount2}" label="Amount 2"/>
            <p:message for="@previous"/>
            <h:outputText value="#{beanValidationView.amount2}"/>
            <p:outputLabel for="@next" value="Pattern: (@Pattern(regexp='^[-+]?\\d+$'))"/>
            <p:inputText value="#{beanValidationView.pattern}" label="pattern"/>
            <p:message for="@previous"/>
            <h:outputText value="#{beanValidationView.pattern}"/>
            <p:outputLabel for="@next" value="Assert: (@AssertTrue)"/>
            <p:selectBooleanCheckbox value="#{beanValidationView.checked}"/>
            <p:message for="@previous"/>
            <h:outputText/>
            <p:outputLabel for="@next" value="Date (@Past)"/>
            <p:inputText value="#{beanValidationView.pastDate}">
                <f:convertDateTime pattern="MM/dd/yyyy"/>
            </p:inputText>
            <p:message for="@previous"/>
            <h:outputText/>
            <p:outputLabel for="@next" value="Date (@Future)"/>
            <p:inputText value="#{beanValidationView.futureDate}">
                <f:convertDateTime pattern="MM/dd/yyyy"/>
            </p:inputText>
            <p:message for="@previous"/>
            <h:outputText/>
            <p:outputLabel for="@next" value="Radio Input"/>
            <p:selectOneRadio value="#{beanValidationView.bool}">
                <f:selectItem itemValue="#{true}" itemLabel="True"/>
                <f:selectItem itemValue="#{false}" itemLabel="False"/>
            </p:selectOneRadio>
            <p:message for="@previous"/>
            <h:outputText/>
        </h:panelGrid>
        <p:commandButton value="Save" ajax="false" icon="pi pi-check" validateClient="true" styleClass="mr-3" />
        <p:commandButton value="Save with disabled CSV" ajax="false" icon="pi pi-check" />
    </h:form>
</div>
package org.primefaces.showcase.view.csv;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Future;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Past;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import java.util.Date;
import io.quarkus.runtime.annotations.RegisterForReflection;
@Named
@RequestScoped
@RegisterForReflection(serialization = true)
public class BeanValidationView {
    @Size(min = 2, max = 5)
    private String name;
    @Min(10)
    @Max(20)
    private Integer age;
    @DecimalMax(value = "99.9", message = "Shold not exceed 99.9")
    private Double amount;
    @Digits(integer = 3, fraction = 2)
    private Double amount2;
    @AssertTrue
    private boolean checked;
    @Past
    private Date pastDate;
    @Future
    private Date futureDate;
    @Pattern(regexp = "^[-+]?\\d+$")
    private String pattern;
    @NotNull
    private Boolean bool;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Double getAmount() {
        return amount;
    }
    public void setAmount(Double amount) {
        this.amount = amount;
    }
    public Double getAmount2() {
        return amount2;
    }
    public void setAmount2(Double amount2) {
        this.amount2 = amount2;
    }
    public boolean isChecked() {
        return checked;
    }
    public void setChecked(boolean checked) {
        this.checked = checked;
    }
    public Date getPastDate() {
        return pastDate;
    }
    public void setPastDate(Date pastDate) {
        this.pastDate = pastDate;
    }
    public Date getFutureDate() {
        return futureDate;
    }
    public void setFutureDate(Date futureDate) {
        this.futureDate = futureDate;
    }
    public String getPattern() {
        return pattern;
    }
    public void setPattern(String pattern) {
        this.pattern = pattern;
    }
    public Boolean getBool() {
        return bool;
    }
    public void setBool(Boolean bool) {
        this.bool = bool;
    }
}