Client Side Validation Framework implements Jakarta Faces validation API within the browser.
<div class="card">
<h:form>
<p:messages>
<p:autoUpdate/>
</p:messages>
<h:panelGroup id="grid" layout="block" styleClass="formgrid grid p-fluid">
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="name" value="Name"/>
<p:inputText id="name" value="#{validationView.text}" required="true" label="Name"/>
<p:message for="name"/>
<small>Value: <h:outputText value="#{validationView.text}"/></small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<p:outputLabel for="number" value="Number"/>
<p:inputNumber id="number" value="#{validationView.integer}">
<f:validateLength minimum="2" maximum="3"/>
</p:inputNumber>
<p:message for="number"/>
<small>Value: <h:outputText value="#{validationView.integer}"/></small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="color" value="Color"/>
<p:colorPicker id="color" value="#{validationView.color}" required="true" label="Color"/>
<p:message for="color"/>
<small>Value: <h:outputText value="#{validationView.color}"/></small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="dd" value="Double"/>
<p:inputText id="dd" value="#{validationView.doubleNumber}"
converterMessage="Cannot convert to double.">
<f:validateDoubleRange minimum="5.5" maximum="8.5"/>
</p:inputText>
<p:message for="dd"/>
<small>Value: <h:outputText value="#{validationView.doubleNumber}"/></small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="money" value="Currency ($)"/>
<p:inputText id="money" value="#{validationView.money}" label="Currency">
<f:convertNumber type="currency" currencySymbol="$"/>
</p:inputText>
<p:message for="money"/>
<small>Value:
<h:outputText value="#{validationView.money}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="regex" value="Regex (^[a-zA-Z]+$)"/>
<p:inputText id="regex" value="#{validationView.regexText}"
validatorMessage="Value does not match pattern.">
<f:validateRegex pattern="^[a-zA-Z]+$"/>
</p:inputText>
<p:message for="regex"/>
<small>Value: <h:outputText value="#{validationView.regexText}"/></small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="date" value="Date (java.util.Date)"/>
<p:inputText id="date" value="#{validationView.date}" label="Date (java.util.Date)">
<f:convertDateTime pattern="MM/dd/yyyy"/>
</p:inputText>
<p:message for="date"/>
<small>Value:
<h:outputText value="#{validationView.date}">
<f:convertDateTime pattern="MM/dd/yyyy"/>
</h:outputText>
</small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="date3" value="Date (java.util.Date; PF DatePicker)"
/>
<p:datePicker id="date3" value="#{validationView.date3}" pattern="MM/dd/yyyy"
label="Date (java.util.Date; PF DatePicker)">
<f:convertDateTime pattern="MM/dd/yyyy"/>
</p:datePicker>
<p:message for="date3"/>
<small>Value:
<h:outputText value="#{validationView.date3}">
<f:convertDateTime pattern="MM/dd/yyyy"/>
</h:outputText>
</small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="localDate" value="LocalDate (Java8)"/>
<p:inputText id="localDate" value="#{validationView.localDate}" label="LocalDate (Java8)">
<f:convertDateTime pattern="MM/dd/yyyy"/>
</p:inputText>
<p:message for="localDate"/>
<small>Value:
<h:outputText value="#{validationView.localDate}">
<f:convertDateTime pattern="MM/dd/yyyy"/>
</h:outputText>
</small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="localDate3" value="LocalDate (Java8; PF DatePicker)"
/>
<p:datePicker id="localDate3" value="#{validationView.localDate3}" pattern="MM/dd/yyyy"
label="LocalDate (Java8; PF DatePicker)">
<f:convertDateTime pattern="MM/dd/yyyy" type="localDate"/>
</p:datePicker>
<p:message for="localDate3"/>
<small>Value:
<h:outputText value="#{validationView.localDate3}">
<f:convertDateTime pattern="MM/dd/yyyy" type="localDate"/>
</h:outputText>
</small>
</div>
<div class="field col-12 md:col-6 xl:col-4">
<h:outputLabel for="desc" value="Description"/>
<p:inputTextarea id="desc" value="#{validationView.description}" required="true"
label="Description">
<f:validateLength minimum="3" maximum="10"/>
</p:inputTextarea>
<p:message for="desc"/>
<small>Value: <h:outputText value="#{validationView.description}"/></small>
</div>
</h:panelGroup>
<p:remoteCommand name="rc" update="grid" process="name number" validateClient="true"/>
<p:defaultCommand target="btnAjax"/>
<div class="pt-3">
<p:commandButton value="Non-Ajax" ajax="false" validateClient="true" styleClass="mr-2" />
<p:commandButton value="Ajax" id="btnAjax" update="grid" validateClient="true" styleClass="mr-2" />
<p:commandButton value="Partial" update="grid" process="name number" validateClient="true" styleClass="mr-2" />
<p:commandButton value="Disabled (without CSV)" ajax="false" styleClass="mr-2"/>
<p:commandButton value="Remote Command" type="button" onclick="rc()" />
</div>
</h:form>
</div>