2025-12-28 18:28:34 +00:00

5.8 KiB

Conditional Logic Examples

This directory demonstrates all supported conditional operators in TypeDialog forms.

Overview

TypeDialog supports rich conditional logic for dynamic form behavior. Fields can be shown/hidden based on previous answers using the when attribute.

Running the Examples

CLI Backend

cargo run --bin typedialog -- examples/13-conditional-logic/conditional-demo.toml

TUI Backend

cargo run --bin typedialog-tui -- examples/13-conditional-logic/conditional-demo.toml

Web Backend

cargo run --bin typedialog-web -- examples/13-conditional-logic/conditional-demo.toml

Supported Operators

Comparison Operators

Equality and Inequality

  • ==: Equal to
  • !=: Not equal to
[[elements]]
name = "mysql_config"
when = "database_driver == mysql"

[[elements]]
name = "server_warning"
when = "database_driver != sqlite"

Numeric Comparisons

  • >: Greater than
  • <: Less than
  • >=: Greater than or equal
  • <=: Less than or equal
[[elements]]
name = "privileged_port_warning"
when = "server_port < 1024"

[[elements]]
name = "high_port_warning"
when = "server_port > 10000"

String Operators

  • contains: Check if field contains substring
  • startswith: Check if field starts with prefix
  • endswith: Check if field ends with suffix
[[elements]]
name = "https_notice"
when = "project_url startswith https"

[[elements]]
name = "github_specific"
when = "project_url endswith github.com"

[[elements]]
name = "gitlab_ci"
when = "project_url contains gitlab"

Array Membership

  • in: Check if value exists in array field
[[elements]]
name = "rust_toolchain"
when = "rust in detected_languages"

[[elements]]
name = "python_venv"
when = "python in detected_languages"

Works with:

  • MultiSelect fields (JSON array or comma-separated string)
  • Array values from JSON output

File System Conditions

  • file_exists(path): Check if file or directory exists
  • !file_exists(path): Check if file does NOT exist (negation)
[[elements]]
name = "dockerfile_exists_notice"
when = "file_exists(Dockerfile)"

[[elements]]
name = "create_dockerfile"
when = "!file_exists(Dockerfile)"

[[elements]]
name = "env_setup"
type = "group"
includes = ["fragments/environment-setup.toml"]
when = "!file_exists(.env)"

Path resolution:

  • Absolute paths: /etc/config.toml
  • Relative paths: Dockerfile, .env, config/settings.toml
  • Works with both files and directories

Form Flow Example

  1. Select database → Shows driver-specific fields
  2. Enter port number → Shows warnings based on port range
  3. Enter project URL → Shows platform-specific options
  4. Select languages → Shows language-specific tooling
  5. Check for files → Conditionally load setup fragments

Key Features

Dynamic Field Visibility

Fields appear/disappear based on user input:

# Only shows if user selects MySQL
[[elements]]
name = "mysql_password"
type = "password"
when = "database_driver == mysql"

Conditional Fragment Loading

Load entire form sections conditionally:

[[elements]]
name = "docker_setup"
type = "group"
includes = ["fragments/docker-init.toml"]
when = "!file_exists(Dockerfile)"

Multi-Condition Fields

Same field can have complex logic (future: && and ||):

# Current: Single condition per field
when = "rust in detected_languages"

# Future: Compound conditions
when = "(rust in detected_languages) && (server_port >= 1024)"

Testing Scenarios

Scenario 1: Database Configuration

  1. Select mysql → See MySQL-specific fields
  2. Select postgresql → See PostgreSQL-specific fields
  3. Select sqlite → No extra server fields

Scenario 2: Port Validation

  1. Enter 80 → See privileged port warning (< 1024)
  2. Enter 8080 → See standard port notice (>= 1024)
  3. Enter 15000 → See high port warning (> 10000)

Scenario 3: Language Detection

  1. Select rust + python → See both Rust and Python config fields
  2. Select only javascript → See only Node.js version selector
  3. Select none → No language-specific fields appear

Scenario 4: File System Checks

  1. With Dockerfile present:

    • Shows "Dockerfile found" notice
    • Skips Docker setup wizard
  2. Without Dockerfile:

    • Asks to create Dockerfile
    • Shows Docker setup group
  3. With .env file:

    • Asks to use existing config
    • Skips environment setup
  4. Without .env file:

    • Loads environment setup fragment
    • Prompts for all env variables

Implementation Details

Condition Evaluation

Conditions are evaluated at runtime during form execution:

  1. User answers a field
  2. System checks all pending fields for when conditions
  3. Fields with satisfied conditions become visible
  4. Fields with unsatisfied conditions remain hidden

Fragment Loading

Conditional groups with includes load fragments only when condition is true:

[[elements]]
name = "advanced_config"
type = "group"
includes = ["fragments/advanced-settings.toml"]
when = "enable_advanced == true"

This prevents loading unnecessary form definitions until needed.

Type Conversion

TypeDialog automatically handles type conversions in conditions:

  • String "8080" compared to number 1024 → converted to number
  • Boolean true compared to string "true" → compared as boolean
  • Number compared to string number → compared numerically

Source Code

Condition evaluation logic: crates/typedialog-core/src/form_parser/conditions.rs