Core Screen Widgets: Screen, Container, Expression, If, Link, and Button
Key Takeaways
- A Screen is the top-level UI page in a Reactive app — it holds the widget tree, Input Parameters, lifecycle events (OnInitialize, OnReady, OnParametersChanged), and Data Actions; Navigate targets a Screen.
- Container renders as an HTML element (default div, configurable Tag) and groups child widgets for layout or conditional rendering; its Visible property removes children from the render tree when false.
- Expression renders computed text; its Escape Content property defaults to Yes for XSS safety, and setting it to No on untrusted input is a known exam trap.
- If widget evaluates a Boolean Condition reactively and renders only the active True/False branch — no manual refresh needed; Ajax Refresh is Traditional Web only and does not exist in Reactive.
- Link navigates to a Screen (with Input Parameters) or external URL; Button runs a Client Action via OnClick; Is Default is Screen-wide Enter-key behavior while Is Form Default submits the enclosing Form.
Quick Answer: A Screen is the root UI page in an OutSystems Reactive app — it holds the widget tree, Input Parameters, and lifecycle events. Container groups child widgets (renders as a
divby default). Expression displays computed text. If conditionally renders one of two branches. Link navigates to a Screen or external URL. Button triggers a Client Action. These six widgets are the building blocks of every Reactive UI.
Screen Widget
The Screen is the foundational UI element in a Reactive Web App — every visible page is a Screen. A Screen has lifecycle events (OnInitialize, OnReady, OnParametersChanged), can declare Input Parameters, and contains a widget tree. Screens are navigation targets for Navigate and Link. A Screen can be parameterized (e.g., ProductId of type Integer) so the same Screen renders different data. In Reactive, the widget tree executes client-side; data fetching uses Data Actions or Aggregates on the Screen.
| Property / Element | Purpose |
|---|---|
| Name | Identifier used in Navigate and Link destinations |
| Input Parameters | Typed values passed when navigating (e.g., OrderId: Integer) |
| OnInitialize | Runs once before first render — set defaults |
| OnReady | Fires when the Screen DOM is ready |
| OnParametersChanged | Fires when Input Parameters change |
| Public | If checked, navigable from other modules |
Exam trap: OnInitialize runs once before first render. OnParametersChanged fires on subsequent parameter changes — it does NOT re-run OnInitialize. If you fetch in OnInitialize and parameters change, you must also fetch in OnParametersChanged or use a Data Action tied to the parameter.
Container Widget
The Container is the most-used widget — a grouping element rendering as an HTML <div> (or <section>, <article> via Tag). It serves two purposes: layout (group widgets for grid classes/CSS) and conditional rendering (an If wraps a Container; showing/hiding it shows/hides all children).
| Property | Purpose |
|---|---|
| Tag | HTML element rendered — div, section, article, span |
| Style Classes | Space-separated CSS classes applied to the element |
| Visible | Boolean expression; when false, the Container and all children are removed from the render tree |
| Enclose In | Whether the Container is wrapped by its parent widget |
Exam trap: Container's Visible property, when false, removes the Container and all children from the render tree entirely — not CSS display:none, but a full removal from the DOM. Changing a variable in the Visible expression automatically re-evaluates it.
Expression Widget
The Expression widget renders computed text at runtime. Its Value property accepts any displayable expression: formatted dates, concatenation, or computed values.
The Escape Content property defaults to Yes, which HTML-escapes the output to prevent injection. Set it to No only for trusted HTML markup (e.g., a rich-text field from a controlled source). Leaving Escape Content = No on user-supplied input is a cross-site scripting vulnerability and a recurring exam trap.
If Widget
The If widget conditionally renders one of two branches — True and False. The Condition property takes a Boolean expression; when true, the True branch renders; when false, the False branch renders. Each branch is a Container.
Key behaviors the exam tests:
- The Condition re-evaluates automatically when any variable in the expression changes (Reactive data flow — no manual refresh).
- Only the active branch is in the DOM; the inactive branch is not rendered.
- The False branch is optional; if empty, nothing renders when Condition is false.
- If widgets can be nested, though Switch is cleaner for value-based branching.
High-yield distinction: the If widget evaluates its Condition reactively — you never call a refresh mechanism. This differs from Traditional Web, where Ajax Refresh updates a conditional region.
Link Widget
The Link widget navigates to a Screen or external URL. Its primary property is Destination — a Screen (with Input Parameters) or an external URL string. A Link renders as an HTML <a> tag.
- Navigate to Screen:
Destination = ProductDetailScreen, passingProductId = 42. - External URL:
Destination = "https://example.com". - Enabled: Boolean — when false, the link is disabled.
A Link can run a Client Action via OnClick, but the idiomatic pattern is: Link → Navigate; Button → Client Action.
Button Widget
The Button widget triggers an action when clicked. Its OnClick event runs a Client Action in Reactive apps. A Button inside a Form can submit that Form when Is Form Default is true. Button properties:
| Property | Purpose |
|---|---|
| OnClick | Client Action to run when clicked |
| Enabled | Boolean controlling clickability |
| Style Classes | CSS classes such as btn-primary, btn-secondary |
| Is Default | Triggers on Enter pressed anywhere on the Screen |
| Is Form Default | Submits the enclosing Form on Enter |
Exam trap: Is Default makes a Button respond to Enter Screen-wide. Is Form Default is scoped to the enclosing Form and submits it on Enter. These are distinct — the exam asks which submits a Form on Enter (Is Form Default, not Is Default).
Widget Hierarchy and Reactive Refresh
All widgets live in a tree rooted at the Screen. Containers can nest Containers; If branches are Containers; List widgets iterate a source per row. The tree matters because events fire on the owning widget, data flows down (Input Parameters and local variables are available to children), and refresh is automatic in Reactive.
The highest-yield distinction: Reactive apps do not use Ajax Refresh. The runtime re-renders widgets automatically when dependent data changes. Ajax Refresh is Traditional Web only. If an exam option mentions Ajax Refresh in a Reactive context, it is wrong.
In a Reactive Web App, what happens when the Boolean expression bound to a Container's Visible property evaluates to false?
A developer sets Escape Content to No on an Expression widget whose Value is bound to a free-text user input field. Which outcome or risk does this create?
Which statement about the If widget in a Reactive app is correct?