Conditional Visibility Patterns
Conditional visibility in Report Forge controls whether a page or component renders in the output based on edition data or parameter values. It is configured in the Output Designer and evaluated at render time.
This page covers the most common design patterns — when to use them, how to configure them, and their trade-offs.
Visibility rule basics
Visibility rules can be applied to:
| Element | Where to configure | Effect |
|---|---|---|
| Page | Right-click page tab → Set Visibility Rule… | Entire page is included or excluded from the output |
| Component | Component settings → Visibility | Component is shown or hidden within its page |
| Section in a table | Row group settings → Visibility | Row group is shown or hidden |
Visibility rules use the same expression engine as computed fields. Reference edition fields, parameters, and variables.
Pattern 1 — Data-driven page inclusion
Goal: A "Critical Risks" page only renders when at least one Red-rated risk exists in the edition.
Configuration:
- Select the Critical Risks page in the page panel.
- Open Page settings → Visibility.
- Set rule:
COUNTIF([sections.RiskRegister.rows.RAGStatus], "Red") > 0
Behaviour:
- Page renders → when there is 1 or more Red risk.
- Page is excluded → when there are no Red risks (all risks are Amber or Green, or the register is empty).
Use this pattern for:
- Issue escalation pages that are only relevant when problems exist
- Appendices that only appear when supporting data is present
- "Variations" pages that only render when variation rows exist in a register
Combine with a cover page that lists the included sections — this way the reader is not confused by "missing" pages that simply had no qualifying data.
Pattern 2 — RAG-triggered narrative component
Goal: A "Recovery plan required" notice appears in the Executive Summary only when the overall schedule RAG is Red.
Configuration:
- Create a text component with the recovery plan notice text.
- Open Component settings → Visibility.
- Set rule:
[sections.ExecutiveSummary.ScheduleRAG] = "Red"
Behaviour:
- Component renders → when ScheduleRAG = Red.
- Component is hidden → when ScheduleRAG is Amber or Green.
Variation: Amber or Red trigger:
OR([sections.ExecutiveSummary.ScheduleRAG] = "Red", [sections.ExecutiveSummary.ScheduleRAG] = "Amber")
Use this pattern for:
- Conditional warnings or callout boxes
- Status-dependent commentary
- Conditional signature blocks (only show when approval is required)
Pattern 3 — Milestone achievement disclosure
Goal: A "Key Achievements" section only renders when at least one milestone has been marked "Complete" in the current edition.
Configuration:
COUNTIF([sections.MilestoneRegister.rows.Status], "Complete") > 0
This is more nuanced than Pattern 1 — it can be combined with a second component for the "No milestones completed this period" case:
- Component A (achievements table): visible when count > 0
- Component B (placeholder text "No milestones were completed this reporting period"): visible when count = 0
This ensures the section always has meaningful content regardless of data state.
Pattern 4 — Parameter-driven format variants
Goal: The template produces two variants — an Executive Summary (4 pages) and a Full Detail version (15 pages) — selected by the user at render time via a parameter.
Setup:
- Create a parameter
ReportFormat→ Select options: "Executive", "Full Detail".
Executive-only pages (hide in Full Detail):
param.ReportFormat = "Executive"
Full Detail-only pages (hide in Executive):
param.ReportFormat = "Full Detail"
Pages visible in both variants:
- No visibility rule → always visible.
Use this pattern for:
- Client vs. internal report variants from one blueprint
- Board pack vs. operational report
- Summary vs. supporting data appendices
Pattern 5 — Progressive disclosure based on completion
Goal: A "Final Accounts" section only renders when the project status field is set to "Practical Completion" or "Final Completion".
Configuration:
OR([sections.ProjectStatus.ProjectPhase] = "Practical Completion",
[sections.ProjectStatus.ProjectPhase] = "Final Completion")
This prevents the final accounts section from cluttering progress reports during construction — it only appears when the project reaches a stage where final accounting is relevant.
Use this pattern for:
- Phase-gated content that is premature in earlier project stages
- Sections that depend on specific milestones being reached
- End-of-project reporting sections
Pattern 6 — Contributor-controlled optional sections
Goal: A "Lessons Learned" section is optional — a toggle in the edition controls whether it appears in the output.
Blueprint setup:
- Add a Toggle field to the Executive Summary section:
IncludeLessonsLearned(label: "Include Lessons Learned section in this report?").
Output Designer:
- Create the Lessons Learned page.
- Set visibility rule:
[sections.ExecutiveSummary.IncludeLessonsLearned] = true
Use this pattern for:
- Optional appendices (lessons learned, look-ahead attachments, supplementary data)
- Confidential sections that the contributor decides to include or exclude
- Sections that are only relevant at certain project stages, decided by the contributor per edition
Pattern 7 — Empty state handling
Goal: A table normally shows a risk register. When the register has no rows, show a "No risks identified this period" message instead.
Setup:
- Risk table component: visible when
COUNT([sections.RiskRegister.rows]) > 0 - Empty state text component:
"No risks have been recorded for this reporting period."— visible whenCOUNT([sections.RiskRegister.rows]) = 0
This prevents a blank space in the output when a section has no data — replacing it with informative placeholder text.
Visibility rule expression tips
Referencing row counts
COUNT([sections.SectionName.rows])
Returns the total number of rows in a repeating section.
Referencing a filtered row count
COUNTIF([sections.SectionName.rows.FieldName], "Value")
Returns the count of rows where a field equals a specific value.
Referencing a non-repeating field
[sections.SectionName.FieldName]
Returns the field value from a single-entry (form mode) section.
Combining conditions
AND([sections.Status.Phase] = "Construction", [sections.Risk.RedCount] > 0)
OR([sections.Status.RAG] = "Red", [sections.Status.RAG] = "Amber")
Negation
NOT([sections.Status.IsComplete] = true)
Performance and output size
Visibility rules are evaluated at render time. Excluded pages and components are not included in the output file — they do not add to PDF page count or file size.
For templates with many conditional pages (>10 visibility rules), test the output with:
- All conditions true (maximum output)
- All conditions false (minimum output)
- Mixed states (typical output)
This ensures the output looks correct across all plausible data states.
Related
- Parameter Strategy — choosing between parameters, filters, slicers, and variables
- Parameters and Calculated Fields — parameter configuration reference
- Report Variables — template-level variables for visibility expressions
- Conditional Page Inclusion tutorial — step-by-step walkthrough