OGE logoOGE

Form validation

There is exactly one validation engine here: Angular's Signal Forms. validationRules is declarative sugar that compiles into a schema — a required rule becomes required(), stringLength becomes minLength()/maxLength(), and so on. Nothing in @oge-ui/forms re-implements validation.

Which means the rules only apply where the form owns the model, i.e. [(formData)]. Bind [fieldTree] or [formGroup] and the caller owns validation; the form warns in dev mode if you set rules anyway.

validationRules Signal Forms summary focus

Declarative rules

Rules are plain objects with a string-union type. Messages come from @oge-ui/inputs' message table, so the text under a field is identical whether the editor is used inside a form or on its own.

required stringLength email numeric

Custom & cross-field rules

A custom rule receives its own value and the whole model, which is how a confirm-password check works without a second engine. There is deliberately no compare rule type — a rule object that names another field loses type safety, and validate() with valueOf() in a real schema does it properly.

custom cross-field async

Angular Signal Forms

Bind the tree that form() returns. The schema owns everything: validity, required marks, disabled and read-only state. The form binds Angular's own FormField directive, so min/max/minLength/pattern reach the editors automatically — which is also why a template [disabled] binding is not written in this mode; the directive would overwrite it.

[fieldTree] schema disabled() readonly()

valid: false

Reactive forms

An existing FormGroup binds straight in — the editors' control-value-accessor path carries the value, and the control's own validators drive the messages. Use this to put a form layout over code you are not ready to migrate.

[formGroup] Validators FormControl

group.valid: false

Validation summary

The summary is a role="alert" list, so a failed submit is announced. Every row is a real button that focuses its field, and a failed submit also moves focus to the first invalid field and scrolls it into view. Render it yourself, or let the form do it with [showValidationSummary].

<oge-validation-summary> errors() focus()

2 fields need your attention

Schema-carried layout

Angular 22's createMetadataKey() lets a schema carry more than validation. Attach a label, a hint, a group, a column span or an editor next to the rules, and <oge-form [fieldTree]> generates the entire layout — no items array, no template children. Angular's own REQUIRED/MIN/MAX/PATTERN metadata already reaches the editors, so none of it is duplicated.

metadata() OGE_FORM_LABEL OGE_FORM_GROUP
Contact
Work address, please

Configuration

Every user-facing string — the required mark, the optional mark, the summary heading — lives in the messages interface, so a translation is one provider. Layout defaults can be set the same way and overridden per instance.

provideOgeFormsConfig messages