Form Validations: Mandatory, Email Type, and Form.Valid
Key Takeaways
- The Form widget exposes a Valid boolean that aggregates the validation state of all inputs inside it — True only when every input passes its validation rules; checking Form.Valid is the standard guard before calling a save Server Action.
- Setting an Input widget's Mandatory property to True requires a non-empty value; OutSystems automatically marks the input invalid and sets Form.Valid to False when the bound variable is empty.
- Using the Email data type on an Input's bound variable gives automatic email-format validation without writing a regex; combined with Mandatory = True, both checks apply on submit.
- Client-side validation runs in the browser and provides instant UX feedback but can be bypassed; server-side validation in the Server Action is authoritative and must re-validate inputs and raise exceptions for invalid data.
- Two-way data binding connects an Input widget to a Local Variable through the Variable property; the variable's data type drives type validation while the Input's Mandatory property drives the required-field check.
Form Validations: Mandatory, Email Type, and Form.Valid
Quick Answer: OutSystems Reactive Web App forms validate inputs through a combination of widget properties and the Form widget's Valid boolean. Set an Input widget's Mandatory property to True to require a non-empty value; use the Email data type on the bound variable to get automatic email-format validation. The Form widget aggregates all input validations into a single Form.Valid boolean — True only when every input passes. Client-side validation runs in the browser before submit; server-side validation runs in the Server Action and can raise exceptions for invalid data that bypassed the client. This sub-topic is roughly 8% of the exam (4 questions).
The Form Widget and Its Valid Property
The Form widget groups input widgets and exposes a Valid boolean property that aggregates the validation state of every input inside it. Form.Valid is True only when all contained inputs pass their validation rules (Mandatory, data-type format, custom validation). When any input fails, Form.Valid is False and OutSystems automatically displays the validation message next to the offending input. A typical submit flow in a Client Action is:
- Check
Form.Valid. - If True, call the Server Action to save.
- If False, show a Feedback Message asking the user to correct the highlighted fields — the inputs already show their own messages.
Checking Form.Valid is the standard guard before calling a save Server Action; skipping it means the Client Action proceeds even with invalid inputs, relying solely on server-side validation and degrading UX.
Mandatory Property
The Mandatory property on an Input widget enforces that the field is not empty. When Mandatory = True and the bound variable is empty (null, empty Text, NullIdentifier, or default), OutSystems sets the input's validation state to invalid, displays a default is-mandatory message (configurable per input), and sets Form.Valid to False.
Mandatory is a widget-level property — it is set on the Input, not on the entity attribute or variable definition. This means the same entity attribute can be Mandatory on one screen's form and optional on another, depending on the UI context. The default validation message can be overridden in the Input's Validation Messages section to provide domain-specific guidance.
Email Data Type Validation
When an Input widget's bound variable has the Email data type, OutSystems automatically validates that the entered text matches email syntax (for example, user@domain.com). This is a data-type-level validation — you do not write a regex or custom validator; choosing the Email type is sufficient. An Email-type variable with Mandatory = True applies both checks on submit:
- Mandatory: the field must not be empty.
- Email format: the text must be a valid email address.
If either fails, the input is marked invalid and Form.Valid becomes False. The Email data type is distinct from Text — using Text would skip format validation even if the field is semantically an email, so choosing the correct data type is what activates the automatic format check.
Client-Side vs Server-Side Validation
Validation runs in two places:
| Layer | Where | What it checks | When |
|---|---|---|---|
| Client-side | Browser, in the Client Action | Mandatory, Email format, built-in widget validations | Before the Server Action call, when Form.Valid is evaluated |
| Server-side | Server Action | Re-checks inputs; raises exceptions; runs business rules (e.g., duplicate email check) | Inside the Server Action, after the Client Action calls it |
Client-side validation improves UX (instant feedback, no round-trip) but is not a security boundary — a user can bypass the browser. Server-side validation is authoritative: the Server Action must re-validate inputs and raise exceptions (e.g., Raise Exception with a User Exception) for invalid data. For business rules that need database access (e.g., is this email already registered?), validation must be server-side because the Client Action cannot query the database directly.
Data Binding and Validation Messages
Two-way data binding connects an Input widget to a Local Variable: set the Input's Variable property to the local variable, and OutSystems automatically syncs the UI value to the variable and back. The bound variable's data type drives type validation (Text, Integer, Decimal, Date Time, Boolean, Email), while the Input widget's Mandatory property drives the required-field check.
Validation messages are shown next to the invalid input automatically. You can customize the Validation Message text on each Input to override the default is-mandatory or invalid-format message, and show a Feedback Message (toast) from the Client Action when Form.Valid is False to summarize the errors.
Common Validation Scenarios
| Scenario | Setup |
|---|---|
| Required text field | Input bound to Variable (Text), Mandatory = True |
| Required, valid email | Input bound to Variable (Email), Mandatory = True |
| Required integer with range | Input bound to Variable (Integer), Mandatory = True, plus custom server-side range check |
| Optional email (blank allowed, but if filled must be valid) | Input bound to Variable (Email), Mandatory = False |
| Conditional mandatory (required only if another field is set) | Custom logic in Client Action setting the input Valid property; server-side re-check |
The conditional-mandatory case is an exam favorite: OutSystems does not natively support mandatory-if-X through the Mandatory property alone — you set the input's Valid property programmatically in the Client Action or raise a User Exception server-side. Always pair client-side UX validation with server-side authoritative validation to handle browser bypass and complex business rules that require database lookups.
What does the OutSystems Form widget's Valid property represent?
An Input widget is bound to an Email-type variable with Mandatory = True. What validations does OutSystems apply automatically on form submit?
Why must server-side validation accompany client-side validation in an OutSystems Reactive Web App?