InputOtp is an input for one-time passwords and PINs with one input per character. Typing moves to the next input, a pasted code is distributed over the inputs and mobile browsers can fill in a code received by SMS.
<p:growl>
<p:autoUpdate/>
</p:growl>
<h:form>
<div class="card">
<h5 class="mt-0">Basic</h5>
<p class="mt-0">The <i>complete</i> event fires when all characters are entered.</p>
<p:outputLabel for="@next" value="Verification code" styleClass="block mb-2"/>
<p:inputOtp value="#{inputOtpView.code}" length="6" integerOnly="true">
<p:ajax event="complete" listener="#{inputOtpView.onComplete}"/>
</p:inputOtp>
</div>
<div class="card">
<h5 class="mt-0">Mask</h5>
<p:inputOtp value="#{inputOtpView.pin}" mask="true" integerOnly="true"/>
</div>
<div class="card">
<h5 class="mt-0">Separator</h5>
<div class="flex flex-column gap-3">
<p:inputOtp length="6" separator="-"/>
<p:inputOtp length="6" integerOnly="true">
<f:facet name="separator">
<i class="pi pi-minus"/>
</f:facet>
</p:inputOtp>
</div>
</div>
<div class="card">
<h5 class="mt-0">Placeholder</h5>
<div class="flex flex-column gap-3">
<p:inputOtp placeholder="0" integerOnly="true"/>
<p:inputOtp length="5" placeholder="ABCDE"/>
</div>
</div>
<div class="card">
<h5 class="mt-0">Sizes</h5>
<div class="flex flex-column gap-3">
<p:inputOtp inputStyleClass="p-inputtext-sm"/>
<p:inputOtp/>
<p:inputOtp inputStyleClass="p-inputtext-lg"/>
</div>
</div>
<div class="card">
<h5 class="mt-0">Disabled and Readonly</h5>
<div class="flex flex-column gap-3">
<p:inputOtp value="1234" disabled="true"/>
<p:inputOtp value="5678" readonly="true"/>
</div>
</div>
<div class="card">
<h5 class="mt-0">Validation</h5>
<p class="mt-0">A partially entered code is invalid.</p>
<div class="flex flex-wrap align-items-start gap-3">
<div>
<p:inputOtp id="token" value="#{inputOtpView.token}" length="6" integerOnly="true" required="true"
label="Token"/>
<p:message for="token"/>
</div>
<p:commandButton value="Submit" action="#{inputOtpView.submit}" process="@this token" update="@form"/>
</div>
</div>
</h:form>
<h:form>
<div class="card">
<h5 class="mt-0">Client Side Validation</h5>
<p class="mt-0">The code is validated in the browser before the form is submitted.</p>
<div class="flex flex-wrap align-items-start gap-3">
<div>
<p:inputOtp id="csvToken" value="#{inputOtpView.csvToken}" length="6" integerOnly="true" required="true"
label="Token"/>
<p:message for="csvToken"/>
</div>
<p:commandButton value="Submit" action="#{inputOtpView.submit}" update="@form" validateClient="true"/>
</div>
</div>
</h:form>
package org.primefaces.showcase.view.input;
import java.io.Serializable;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
@Named
@ViewScoped
public class InputOtpView implements Serializable {
private String code;
private String pin = "1234";
private String token;
private String csvToken;
public void onComplete() {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_INFO, "Code entered", code));
}
public void submit() {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_INFO, "Submitted", "Token: " + token + ", CSV token: " + csvToken));
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPin() {
return pin;
}
public void setPin(String pin) {
this.pin = pin;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getCsvToken() {
return csvToken;
}
public void setCsvToken(String csvToken) {
this.csvToken = csvToken;
}
}