Class OtpField
- All Implemented Interfaces:
AttachNotifier,BlurNotifier<OtpField>,DetachNotifier,Focusable<OtpField>,FocusNotifier<OtpField>,HasAriaLabel,HasElement,HasEnabled,HasHelper,HasLabel,HasPlaceholder,HasSize,HasStyle,HasValidation,HasValue<AbstractField.ComponentValueChangeEvent<OtpField,,String>, String> HasValueAndElement<AbstractField.ComponentValueChangeEvent<OtpField,,String>, String> HasAllowedCharPattern,HasPrefix,HasSuffix,HasTooltip,HasValidationProperties,InputField<AbstractField.ComponentValueChangeEvent<OtpField,,String>, String> HasValidator<String>,HasValueChangeMode,Serializable
The field renders one visual slot per character, advances as the user types, accepts a pasted or
auto-filled code, and integrates with Binder like any other Vaadin input field.
Value
The value is a String that may be shorter than getLength(): what the user typed
is always the value, and "not finished yet" is a constraint violation rather than a hidden value.
Applications that only care about the finished code use
addCompleteListener(ComponentEventListener) instead of inspecting the length of every
value change.
The value change mode defaults to ValueChangeMode.EAGER, so the server sees every
keystroke. Applications that would rather not transmit partial codes can switch to
ValueChangeMode.ON_CHANGE, which leaves the complete event intact.
Validation
The field has three built-in constraints:
- required — the value is empty while
setRequiredIndicatorVisible(boolean)is enabled - incomplete — the value is non-empty and shorter than
getLength() - invalid — the value is longer than
getLength(), or contains characters the field does not accept. A user cannot enter such a value, so this reports a value that was set programmatically, typically a stored code that no longer fits the configuration of the field
getDefaultValidator() reports all three, so a Binder picks them up
automatically, and
the error messages come from OtpFieldI18n. Verifying a code against a back end is the
responsibility of the application: use
addCompleteListener together with
HasValidationProperties.setInvalid(boolean) and HasValidationProperties.setErrorMessage(String) for that, or hand validation
over entirely with setManualValidation(boolean).
The field generates, sends, verifies or expires nothing: it is an input control, not a security control. Masking is a shoulder-surfing measure only.
Example
OtpField otp = new OtpField("Verification code", 6);
otp.addCompleteListener(e -> verifyCode(e.getValue()));
- Since:
- 1.0.0
- Author:
- Flowing Code
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from class com.vaadin.flow.component.AbstractField
AbstractField.ComponentValueChangeEvent<C extends Component,V> Nested classes/interfaces inherited from interface com.vaadin.flow.component.BlurNotifier
BlurNotifier.BlurEvent<C extends Component>Nested classes/interfaces inherited from interface com.vaadin.flow.component.FocusNotifier
FocusNotifier.FocusEvent<C extends Component>Nested classes/interfaces inherited from interface com.vaadin.flow.component.HasValue
HasValue.ValueChangeEvent<V>, HasValue.ValueChangeListener<E extends HasValue.ValueChangeEvent<?>> -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringThe allowed character pattern that accepts digits and Latin letters in either case.static final intThe default number of slots, the dominant convention for TOTP and SMS codes.static final StringThe default mask glyph, a bullet.static final intThe largest supported number of slots.static final intThe smallest supported number of slots.static final StringThe allowed character pattern that accepts digits only: the default, and the convention for TOTP and SMS codes.Fields inherited from interface com.vaadin.flow.data.value.HasValueChangeMode
DEFAULT_CHANGE_TIMEOUT -
Constructor Summary
ConstructorsConstructorDescriptionOtpField()OtpField(int length) Constructs an empty field with the given length.Constructs an empty field with the given label.Constructs an empty field with the given label and length.OtpField(String label, HasValue.ValueChangeListener<? super AbstractField.ComponentValueChangeEvent<OtpField, String>> listener) Constructs an empty field with the given label and a value change listener. -
Method Summary
Modifier and TypeMethodDescriptionAdds a listener that is notified when the entered code becomes complete.voidclear()Empties the field and returns the caret to the first slot.Gets the case conversion applied to the value.getI18n()Gets the internationalization object of this field.Gets theinputmodeof the field.intGets the number of slots.Gets the glyph rendered in filled slots while the field is masked.getValue()Returns the code entered so far, which may be shorter thangetLength().intbooleanGets whether the field automatically receives focus when the page loads.booleanisMasked()Gets whether the entered characters are hidden behind a mask glyph.voidsetAllowedCharPattern(String pattern) Sets the characters the field accepts, as a single-character regular expression.voidsetAriaLabel(String ariaLabel) voidsetAriaLabelledBy(String labelledBy) voidsetAutofocus(boolean autofocus) Sets whether the field should automatically receive focus when the page loads.voidsetCaseConversion(OtpCaseConversion caseConversion) Sets the case conversion applied to typed, pasted and programmatically set values.voidsetI18n(OtpFieldI18n i18n) Sets the internationalization object of this field.voidsetInputMode(String inputMode) Sets theinputmodeof the field, the hint that decides which on-screen keyboard mobile browsers show.voidsetLength(int length) Sets the number of slots, which is also the length at which the code is complete.voidsetManualValidation(boolean enabled) voidsetMasked(boolean masked) Sets whether the entered characters are hidden behind a mask glyph.voidsetMaskGlyph(String maskGlyph) Sets the glyph rendered in filled slots while the field is masked.voidsetPlaceholder(String placeholder) Sets the placeholder shown in empty slots.voidsetRequiredIndicatorVisible(boolean required) Sets whether the user is required to provide a value.voidSets the value of the field, after applying the configured case conversion.voidsetValueChangeMode(ValueChangeMode valueChangeMode) voidsetValueChangeTimeout(int valueChangeTimeout) protected voidvalidate()Validates the current value against the built-in constraints and updates the invalid state and the error message accordingly.Methods inherited from class com.vaadin.flow.component.AbstractSinglePropertyField
getSynchronizationRegistration, hasValidValue, setPresentationValue, setSynchronizedEventMethods inherited from class com.vaadin.flow.component.AbstractField
addValueChangeListener, bindValue, isEmpty, setModelValue, valueEqualsMethods inherited from class com.vaadin.flow.component.Component
addListener, bindVisible, findAncestor, fireEvent, from, get, getChildren, getElement, getEventBus, getId, getListeners, getLocale, getParent, getTestId, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getUI, hasListener, isAttached, isTemplateMapped, isVisible, onAttach, onDetach, onEnabledStateChanged, removeFromParent, scrollIntoView, scrollIntoView, set, setElement, setId, setTestId, setVisibleMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface com.vaadin.flow.component.AttachNotifier
addAttachListenerMethods inherited from interface com.vaadin.flow.component.BlurNotifier
addBlurListenerMethods inherited from interface com.vaadin.flow.component.DetachNotifier
addDetachListenerMethods inherited from interface com.vaadin.flow.component.Focusable
addFocusShortcut, blur, focus, focus, getTabIndex, setTabIndexMethods inherited from interface com.vaadin.flow.component.FocusNotifier
addFocusListenerMethods inherited from interface com.vaadin.flow.component.shared.HasAllowedCharPattern
getAllowedCharPatternMethods inherited from interface com.vaadin.flow.component.HasAriaLabel
setAriaLabelledByMethods inherited from interface com.vaadin.flow.component.HasElement
getElementMethods inherited from interface com.vaadin.flow.component.HasEnabled
bindEnabled, isEnabled, setEnabledMethods inherited from interface com.vaadin.flow.component.HasHelper
bindHelperText, getHelperComponent, getHelperText, setHelperComponent, setHelperTextMethods inherited from interface com.vaadin.flow.component.HasPlaceholder
bindPlaceholder, getPlaceholderMethods inherited from interface com.vaadin.flow.component.shared.HasPrefix
getPrefixComponent, setPrefixComponentMethods inherited from interface com.vaadin.flow.component.HasSize
bindHeight, bindWidth, getHeight, getHeightUnit, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getWidth, getWidthUnit, setHeight, setHeight, setHeightFull, setMaxHeight, setMaxHeight, setMaxWidth, setMaxWidth, setMinHeight, setMinHeight, setMinWidth, setMinWidth, setSizeFull, setSizeUndefined, setWidth, setWidth, setWidthFullMethods inherited from interface com.vaadin.flow.component.HasStyle
addClassName, addClassNames, bindClassName, bindClassNames, getClassName, getClassNames, getStyle, hasClassName, removeClassName, removeClassNames, setClassName, setClassNameMethods inherited from interface com.vaadin.flow.component.shared.HasSuffix
getSuffixComponent, setSuffixComponentMethods inherited from interface com.vaadin.flow.component.shared.HasTooltip
getTooltip, setTooltipMarkdown, setTooltipTextMethods inherited from interface com.vaadin.flow.component.shared.HasValidationProperties
getErrorMessage, isInvalid, setErrorMessage, setInvalidMethods inherited from interface com.vaadin.flow.data.binder.HasValidator
addValidationStatusChangeListenerMethods inherited from interface com.vaadin.flow.component.HasValue
addValueChangeListener, bindValue, getOptionalValue, isEmptyMethods inherited from interface com.vaadin.flow.component.HasValueAndElement
bindReadOnly, bindRequiredIndicatorVisible, isReadOnly, isRequiredIndicatorVisible, setReadOnly
-
Field Details
-
MIN_LENGTH
public static final int MIN_LENGTHThe smallest supported number of slots.- See Also:
-
MAX_LENGTH
public static final int MAX_LENGTHThe largest supported number of slots.- See Also:
-
DEFAULT_LENGTH
public static final int DEFAULT_LENGTHThe default number of slots, the dominant convention for TOTP and SMS codes.- See Also:
-
DEFAULT_MASK_GLYPH
The default mask glyph, a bullet.- See Also:
-
NUMERIC
The allowed character pattern that accepts digits only: the default, and the convention for TOTP and SMS codes. It is the only pattern that implies aninputmodeofnumeric.- See Also:
-
ALPHANUMERIC
The allowed character pattern that accepts digits and Latin letters in either case.- See Also:
-
-
Constructor Details
-
OtpField
public OtpField() -
OtpField
public OtpField(int length) Constructs an empty field with the given length.- Parameters:
length- the number of slots, between 1 and 24- Throws:
IllegalArgumentException- if the length is out of range
-
OtpField
Constructs an empty field with the given label.- Parameters:
label- the text to set as the label
-
OtpField
Constructs an empty field with the given label and length.- Parameters:
label- the text to set as the labellength- the number of slots, between 1 and 24- Throws:
IllegalArgumentException- if the length is out of range
-
OtpField
public OtpField(String label, HasValue.ValueChangeListener<? super AbstractField.ComponentValueChangeEvent<OtpField, String>> listener) Constructs an empty field with the given label and a value change listener.- Parameters:
label- the text to set as the labellistener- the value change listener- See Also:
-
-
Method Details
-
setLength
public void setLength(int length) Sets the number of slots, which is also the length at which the code is complete.If the current value is longer than the new length it is truncated, which fires a value change event. A multi-character placeholder that no longer matches the new length is kept but not rendered, so set the placeholder after the length.
- Parameters:
length- the number of slots, between 1 and 24- Throws:
IllegalArgumentException- if the length is out of range
-
getLength
public int getLength()Gets the number of slots.- Returns:
- the number of slots
- See Also:
-
setAllowedCharPattern
Sets the characters the field accepts, as a single-character regular expression.NUMERICandALPHANUMERICcover the common cases, and any other single-character expression works as well, such as[0-9A-Fa-f]for hexadecimal.The pattern also assigns the default
inputmode:NUMERICimpliesnumeric, so that mobile browsers show a digit keypad, and every other pattern leaves the input mode empty. CallsetInputMode(String)after this method to state a different one.- Specified by:
setAllowedCharPatternin interfaceHasAllowedCharPattern- Parameters:
pattern- the allowed character pattern, ornullto accept every character
-
setInputMode
Sets theinputmodeof the field, the hint that decides which on-screen keyboard mobile browsers show.setAllowedCharPattern(String)assigns a default input mode, so call this method after it.- Parameters:
inputMode- aninputmodevalue such asnumericortext, or the empty string to state none; notnull
-
getInputMode
Gets theinputmodeof the field.- Returns:
- the input mode, or the empty string if the field states none
- See Also:
-
setCaseConversion
Sets the case conversion applied to typed, pasted and programmatically set values.- Parameters:
caseConversion- the case conversion, notnull
-
getCaseConversion
Gets the case conversion applied to the value.- Returns:
- the case conversion, never
null - See Also:
-
setMasked
public void setMasked(boolean masked) Sets whether the entered characters are hidden behind a mask glyph.Masking is visual only: it does not change the value, and it does not hide the code from assistive technology. It is a shoulder-surfing measure, not a security control.
- Parameters:
masked-trueto render the mask glyph instead of the characters
-
isMasked
public boolean isMasked()Gets whether the entered characters are hidden behind a mask glyph.- Returns:
trueif the field is masked- See Also:
-
setMaskGlyph
Sets the glyph rendered in filled slots while the field is masked.- Parameters:
maskGlyph- a single character, notnull- Throws:
IllegalArgumentException- if the glyph is not exactly one character
-
getMaskGlyph
Gets the glyph rendered in filled slots while the field is masked.- Returns:
- the mask glyph
- See Also:
-
setPlaceholder
Sets the placeholder shown in empty slots.A one-character placeholder is repeated in every empty slot; a placeholder that is exactly
getLength()characters long provides one character per slot.- Specified by:
setPlaceholderin interfaceHasPlaceholder- Parameters:
placeholder- the placeholder,nullor empty for none- Throws:
IllegalArgumentException- if the placeholder is neither one norgetLength()characters long
-
setRequiredIndicatorVisible
public void setRequiredIndicatorVisible(boolean required) Sets whether the user is required to provide a value. When required, an indicator appears next to the label and the field invalidates if the value is cleared.NOTE: the required indicator is only visible when the field has a label, see
HasLabel.setLabel(String).- Specified by:
setRequiredIndicatorVisiblein interfaceHasValue<AbstractField.ComponentValueChangeEvent<OtpField,String>, String> - Specified by:
setRequiredIndicatorVisiblein interfaceHasValueAndElement<AbstractField.ComponentValueChangeEvent<OtpField,String>, String> - Parameters:
required-trueto make the field required,falseotherwise- See Also:
-
addCompleteListener
Adds a listener that is notified when the entered code becomes complete.- Parameters:
listener- the listener to add, notnull- Returns:
- a registration for removing the listener
- See Also:
-
getValueChangeMode
The default value is
ValueChangeMode.EAGER, so that every keystroke reaches the server.ValueChangeMode.ON_CHANGEavoids transmitting partial codes; the complete event is fired in either case.- Specified by:
getValueChangeModein interfaceHasValueChangeMode
-
setValueChangeMode
- Specified by:
setValueChangeModein interfaceHasValueChangeMode
-
setValueChangeTimeout
public void setValueChangeTimeout(int valueChangeTimeout) - Specified by:
setValueChangeTimeoutin interfaceHasValueChangeMode
-
getValueChangeTimeout
public int getValueChangeTimeout()- Specified by:
getValueChangeTimeoutin interfaceHasValueChangeMode
-
setValue
Sets the value of the field, after applying the configured case conversion.A value that is longer than
getLength(), or that contains characters the field does not accept, is not rejected: it is set and reported by the validator, exactly as an out-of-range value is on the built-in Vaadin fields. Throwing here would instead propagate out ofBinder.readBean(Object)andBinder.setBean(Object)whenever a stored code no longer fits the configuration of the field.- Specified by:
setValuein interfaceHasValue<AbstractField.ComponentValueChangeEvent<OtpField,String>, String> - Overrides:
setValuein classAbstractField<OtpField,String> - Parameters:
value- the new value, notnull
-
getValue
Returns the code entered so far, which may be shorter thangetLength().- Specified by:
getValuein interfaceHasValue<AbstractField.ComponentValueChangeEvent<OtpField,String>, String> - Overrides:
getValuein classAbstractField<OtpField,String> - Returns:
- the current value, never
null
-
getEmptyValue
- Specified by:
getEmptyValuein interfaceHasValue<AbstractField.ComponentValueChangeEvent<OtpField,String>, String> - Overrides:
getEmptyValuein classAbstractField<OtpField,String>
-
clear
public void clear()Empties the field and returns the caret to the first slot. -
setAutofocus
public void setAutofocus(boolean autofocus) Sets whether the field should automatically receive focus when the page loads.- Parameters:
autofocus-trueto focus the field on attach
-
isAutofocus
public boolean isAutofocus()Gets whether the field automatically receives focus when the page loads.- Returns:
trueif the field is focused on attach- See Also:
-
setAriaLabel
- Specified by:
setAriaLabelin interfaceHasAriaLabel
-
getAriaLabel
- Specified by:
getAriaLabelin interfaceHasAriaLabel
-
setAriaLabelledBy
- Specified by:
setAriaLabelledByin interfaceHasAriaLabel
-
getAriaLabelledBy
- Specified by:
getAriaLabelledByin interfaceHasAriaLabel
-
getDefaultValidator
The returned validator reports the required and the incomplete constraint, using the error messages of the
OtpFieldI18nobject of this field.- Specified by:
getDefaultValidatorin interfaceHasValidator<String>
-
setManualValidation
public void setManualValidation(boolean enabled) - Specified by:
setManualValidationin interfaceHasValidation
-
validate
protected void validate()Validates the current value against the built-in constraints and updates the invalid state and the error message accordingly. A custom error message set withHasValidationProperties.setErrorMessage(String)takes priority over the messages of theOtpFieldI18nobject.The method does nothing while manual validation is enabled.
-
setI18n
Sets the internationalization object of this field.- Parameters:
i18n- the i18n object, notnull
-
getI18n
Gets the internationalization object of this field.NOTE: updating the returned instance does not update the field unless it is set again with
setI18n(OtpFieldI18n).- Returns:
- the i18n object, never
null
-