Unify Logo Footer.svg
Unify Applications
Logo
Specialized Inputs

Specialized Inputs

Logo

12 mins READ

Specialized Inputs

Purpose-built input controls for OTP codes, rich text, ratings, sliders, currency amounts, and handwritten signatures — each with unique behavior and gotchas.

Pin Input Block (OTP)

The Pin Input block collects a fixed-length code — 4 or 6 digits — one cell per character, the classic OTP (one-time password) entry pattern. Five visual variants change how each cell looks: Box, Underline, Circle, Solid Circle, and Check Circle. The last two never show the typed character. A new block is a 6-digit unmasked Box.

Content properties

PropertyTypeDefaultDescription
length4 | 66How many digit cells the code has. Only 4 and 6 are offered.
variantbox | underline | circle | solid-circle | check-circleboxVisual style of each cell. Solid Circle and Check Circle permanently hide the typed character — no masking option needed or available.
maskedbooleanfalseReplaces typed digits with a masking character. Appears only when variant is Box, Underline, or Circle.
maskingCharacter● | ∗ | - | ?● (dot)Symbol shown in place of each digit when masked is on.
placeholderstring (1 char)Single character shown in every empty cell. Only the first character is used; it repeats across all cells. Appears when variant shows digits.

Events, Methods & State

NameTypeDescription
On ChangeeventFires on every character typed or removed. Payload: value (the whole code so far).
resetPinInputmethodClears the entered code. resetToDefault param has no effect since there is no default value.
{{ id.value }}stringThe code entered so far as a plain string — unmasked even when masking is on.

Note: There is no "complete" event. On Change fires on every character with the full code so far; nothing fires when the last cell is filled. To auto-submit when all digits are entered, add a condition on the On Change handler that checks {{ pinInput1.value }} length equals your pin length.

OTP Form Field

The OTP form field renders the same Pin Input widget inside a Form block. The field type is labeled "Pin Input" in the builder. A key difference from other fields: it has no Default Value and its "Is Optional" toggle is always hidden (the field is treated as optional; use validity conditions to enforce completeness).

Key properties unique to OTP

PropertyTypeDefaultWhereDescription
Length4 | 66Content → Pin Input optionsHow many digit boxes. Only 4 and 6 supported.
Variantbox | underline | circle | solid-circle | check-circleboxAppearanceCell style. Solid Circle / Check Circle hide the digit.
MaskedbooleanfalseAppearanceReplace digit with masking character (only for digit-visible variants).

Warning: No Default Value and no Is Optional toggle. The OTP field always starts empty. To enforce that all digits are filled, add a Validity Condition with a Minimum Length operator set to the code length (4 or 6). This is checked on submit and cannot be replaced with the Is Optional switch.

Rich Text Block

The Rich Text block is a standalone WYSIWYG editor for authoring and displaying formatted content — headings, bold, lists, links, tables, images, colors, and highlights. Its value is an HTML string exposed as {{ id.value }}. Inside a Form, use the Rich Text form field to include it in the submit payload.

Key properties

PropertyTypeDefaultDescription
defaultValuestring (HTML)Initial content authored in a mini rich-text editor. When bound to a dynamic value, the content re-applies when that value changes — this replaces what the user is typing.
placeholderstringEnter your text hereHint text shown while the editor is empty.
minNumberOfLinesnumber3Minimum editor height in lines before it grows with content.
maxNumberOfLinesnumber5Maximum height in lines; content scrolls beyond this. If max < min, the cap is silently ignored.
toolbarVariantstandard | slashstandardStandard shows a fixed formatting bar. Slash hides it; block commands are typed inline with /.
variantoutlined | solid | ghostoutlinedVisual frame. Ghost is only available with the Slash toolbar; switching to Standard resets Ghost to Outlined.
extensionConfigFeaturesfeature togglesAll onControls which formatting capabilities (bold, italic, table, link, image, etc.) are available. Turning a tool off removes it from both the toolbar and the editor's keyboard shortcuts.
disabledconditionMakes the content non-editable while it stays visible. There is no separate read-only mode.

Events, Methods & State

NameTypeDescription
On ChangeeventFires on every edit as the user types or applies formatting — no debounce. Payload: value (current HTML).
setValuemethodReplaces all content with value and optionally focuses the editor (autofocus param, on by default).
insertValueAtCursormethodInserts value at the current cursor position.
resetValuemethodWith resetToDefault on, restores the configured default. With it off, clears the editor.
{{ id.value }}string (HTML)Current content as an HTML string. Anything that reads this and does not render HTML will see raw tags.

Warning: Binding Default value to the block's own value causes cursor jumps. If Default value is bound to an expression that echoes {{ richText1.value }}, every keystroke re-applies the content and the cursor drops to the end. Bind Default value to a different source; read what the user typed from {{ id.value }}.

Rating Block

The Rating block shows a row of icons (stars by default) that users click to pick a score from 1 up to a configurable maximum. Decimal values from bound data render as partially filled icons. Setting Editable to false makes it a read-only display widget.

Properties

PropertyTypeDefaultDescription
maxRatingnumber5How many icons the scale has. This is the highest score the user can give.
defaultValuestring (bindable)2Score on first render. Dynamic value keeps updating the block. Non-numeric text is silently ignored. A dynamic default overwrites the user's rating without firing On Value Change.
editableboolean | conditiontrueWhen false, clicks and hover are disabled — the block shows the score as a read-only display.
iconicon selectionstarThe icon set used for the scale (filled, half-filled, and unfilled variants chosen together).
ratedColor / unratedColorcoloramber / light greyFill colors for selected and unselected portions of the scale.

Events, Methods & State

NameTypeDescription
On Value ChangeeventFires when the user clicks an icon. Payload: value (number).
setValuemethodSets the score. Empty or non-numeric value clears the rating (resolves to 0).
{{ id.value }}numberCurrent score. A value above maxRating shows capped (all icons filled) but state holds the real number.

Note: Users can only click whole numbers and cannot click below 1. To offer a "clear rating" affordance, add a button that calls setValue with an empty value.

Rating Form Field

The RATING form field provides the same icon-row picker inside a Form block. Unlike the standalone block, Maximum Rating lives in the Validation section, and the field can be made required via Is Optional.

PropertySectionDefaultDescription
Default valueContentHow many icons start filled. Dynamic default re-applies when bound value changes.
Maximum ratingValidation5How many icons are shown. Note: in Validation, not Appearance.
Is optionalValidationtrueTurn off to require a rating before submit.
ratingIconAppearancestarThe icon used for each step — accepts conditional values so color can change based on score.
ratedColor / unratedColorAppearancewarning / grayBoth accept conditional expressions — the fill color can change based on another value.

In a mapped form, Rating offers no extra formatting properties — icon, colors, and max rating cannot come from the data source.

Slider Form Field

The SLIDER form field is a draggable track for picking a number between a minimum and maximum. A Range variant lets the user select a start–end pair together. The Value Type property formats the displayed value as a number, percent, currency amount, duration, or physical unit.

Properties

PropertySectionDefaultDescription
VariantContent → Slider optionssingleSingle — one handle; value is a bare number. Range — two handles; value is an object { start, end }. Range hides the Default value field; use Start value and End value instead.
Value TypeContent → Slider optionsNUMBERHow the selected value is displayed and formatted: Number, Percent, Currency, Duration, or Unit. Each choice exposes its own formatting options (e.g. Unit Type picker for Unit mode).
Min valueValidation0Left end of the track. Track bounds live in Validation, not Appearance.
Max valueValidation100Right end of the track.
Step sizeValidation1Increment the handle snaps to.
Number inputAppearancetrueShows a text box next to the track so users can type an exact value. Turning it off makes dragging the only entry method.
Show marker labelsAppearancetrueShows min and max values at the ends of the track.

Warning: Range variant submits an object, not a number. Reading {{ form.data.sliderKey }} on a Range slider gives { start: ..., end: ... }. Read the ends as {{ form.data.sliderKey.start }} and {{ form.data.sliderKey.end }}. A Single slider returns a bare number.

Note: The default slider min is 0 and max is 100. A slider meant for 0–10 still shows 0–100 until you change Min value and Max value in Validation.

Currency Input Form Field

The CURRENCY_INPUT form field collects a monetary amount together with its currency code in one field. Its value is an object — not a plain number — holding both the currency code and the amount.

Properties

PropertyDefaultDescription
Allow currency changetrueLets users pick a different currency. When off, the selector is display-only.
Decimal placesMaximum digits after the decimal. Amount is rounded to this on commit (when the user leaves the field).
Pad decimal placesfalseIncludes trailing zeros to always show the configured number of decimal places.
Show Comma SeparatorfalseDisplays the amount with comma grouping. INR, BDT, NPR, BTN, and MVR use Indian grouping (10,00,000); all others use Western (1,000,000).
Type / SourceLOOKUPWhere the currency list comes from: Manual (static entries) or Mapped (lookup from the built-in currency list). Default is LOOKUP showing all currencies.
Default valueObject with currencyCode and optionally amount. Example: {"currencyCode":"USD","amount":1000}.

Value shape & events

Warning: The value is an object, not a number. {{ form.data.fieldKey }} returns the whole { currencyCode, amount } object. To get just the number, read {{ form.data.fieldKey.amount }}. To get the currency, read {{ form.data.fieldKey.currencyCode }}.

On Change fires when the amount is committed (user leaves the field) or the currency is changed. The form data does not update while the user is typing — mid-type values always see the previous committed amount. On Focus and On Blur also fire on the amount input.

If text that can't parse as a number is left in the field, it is silently replaced with 0 on commit. Clearing the field entirely stores an empty amount but preserves the currencyCode.

Signature Block

The Signature block gives users a drawing pad to sign with a finger, stylus, or mouse. Drawing updates a live preview in state; calling Capture Signature uploads the drawing as an image file. The block has no Content section — everything lives in the Appearance panel.

Appearance properties

PropertyDefaultDescription
signatureColorinverse primaryInk color of the drawn stroke.
strokeWidth2Thickness of the drawn stroke in pixels.
stylesbg quaternary, 200px height, 100% widthBackground color fills the drawing pad. Width, height, min/max, margin, padding, radius all available.

Events, Methods & State

NameTypeDescription
On Signature CaptureeventFires after captureSignature finishes uploading. Not fired if the pad is blank or upload fails.
captureSignaturemethodUploads the current drawing as an image, stores details in {{ id.uploadedSignature }}, then fires On Signature Capture. Silent no-op if the pad is empty.
clearSignaturemethodWipes the pad and clears both signaturePreview and uploadedSignature from state.
{{ id.signaturePreview }}stringIn-progress drawing as inline image data — updates live while drawing.
{{ id.uploadedSignature }}objectUploaded file details (name, url, type…) — set only after captureSignature completes.
{{ id.isEmpty }}booleanWhether the pad is blank. Starts true.

Warning: Drawing alone uploads nothing. While the user draws, only signaturePreview and isEmpty update. No file exists until something calls captureSignature. Wire your Save action inside the On Signature Capture event, not on a button click, so it runs only after the upload completes.

Note: File format differs by platform. Web apps upload the signature as JPEG; native mobile apps upload PNG. Downstream systems that validate file type must accept both.

Frequently Asked Questions

How do I auto-submit when the user finishes entering an OTP?

The Pin Input block has no "code complete" event. Instead, wire the On Change event and add a condition: when {{ pinInput1.value }} has length equal to your pin length (4 or 6), run your verify action. Use {{ pinInput1.value.length == 6 }} as the condition. This fires automatically the instant the last cell is filled.

Why is the Rich Text block exposing HTML tags in my email body?

The Rich Text block's value is an HTML string. If you feed {{ richText1.value }} to a plain-text consumer — a text block, a notification message body configured as plain text — you'll see raw <p> and <strong> tags. Use the value only in consumers that render HTML, such as an email body set to HTML mode or an HTML display component.

How do I read just the amount number from a Currency Input field?

The Currency Input field stores an object: { currencyCode: "USD", amount: 1000 }. Reading {{ form.data.priceField }} gives you the whole object. To get just the number, use {{ form.data.priceField.amount }}. For the currency code, use {{ form.data.priceField.currencyCode }}. Remember the amount commits on blur — mid-typing, the previous value is still in state.

My signature is saved but clicking Clear removes it — why?

The clearSignature method clears both the pad's drawing and the uploadedSignature state. If you call Clear before saving the captured reference to your record, the file still exists in storage but you've lost the URL pointer. Always save {{ signature1.uploadedSignature }} to your data source first, then optionally clear the pad afterward.

What does the Slider Range variant submit, and how do I read both values?

The Range variant submits an object with two keys: { start: <number>, end: <number> }. Read the lower bound as {{ form.data.priceRange.start }} and the upper bound as {{ form.data.priceRange.end }}. The Single variant returns a bare number. Make sure any condition or query that consumes the slider value handles the correct shape for the variant you've chosen.

Step-by-Step Examples