TypeDialog/docs/FIELD_TYPES.md
Jesús Pérez 6d045d62c9
feat(repeating-groups): implement duplicate detection across all backends
- Fix has_unique flag reading from field definition (was scanning fragment fields)
- Implement duplicate validation in CLI and TUI backends
- Add item counter update in Web backend after add/delete operations
- Refactor Web JavaScript: remove global constants, use closure-based state per group
- Store repeating group config in data-* attributes instead of global variables
- Update documentation and examples with unique = true attribute
- All backends now enforce unique items validation consistently
2025-12-21 11:38:14 +00:00

11 KiB
Raw Blame History

TypeDialog Logo

Field Types Reference

Complete reference for all supported field types in TypeDialog forms.

Overview

TypeDialog supports multiple field types for different input scenarios. Each backend (CLI, TUI, Web) renders these types appropriately for its interface.

Supported Field Types

Text

Single-line text input.

[[elements]]
name = "username"
type = "text"
prompt = "Enter username"
placeholder = "john_doe"
default = "admin"
required = true

Attributes:

  • prompt: Display label
  • placeholder: Example text
  • default: Pre-filled value
  • required: Validation flag

Backend rendering:

  • CLI: Inline text prompt with validation
  • TUI: Text input field in input panel
  • Web: HTML <input type="text">

Password

Secure password input (masked characters).

[[elements]]
name = "api_token"
type = "password"
prompt = "API Token"
required = true
help = "Your secret authentication token"

Attributes:

  • prompt: Display label
  • required: Validation flag
  • help: Additional guidance

Backend rendering:

  • CLI: Hidden input with asterisks
  • TUI: Masked input field
  • Web: HTML <input type="password">

Confirm

Boolean yes/no selection.

[[elements]]
name = "enable_feature"
type = "confirm"
prompt = "Enable experimental features?"
default = false

Attributes:

  • prompt: Question to display
  • default: Initial value (true/false)

Backend rendering:

  • CLI: Yes/No buttons
  • TUI: Radio buttons (Yes/No)
  • Web: Radio buttons or toggle switch

Select

Single selection from predefined options.

[[elements]]
name = "database_driver"
type = "select"
prompt = "Database type"
required = true

[[elements.options]]
value = "sqlite3"
label = "SQLite (embedded)"

[[elements.options]]
value = "mysql"
label = "MySQL (server)"

[[elements.options]]
value = "postgresql"
label = "PostgreSQL (server)"

Attributes:

  • prompt: Display label
  • options: Array of value/label pairs
  • required: Validation flag
  • default: Pre-selected value

Backend rendering:

  • CLI: Arrow-key navigation list
  • TUI: Dropdown or scrollable list
  • Web: HTML <select> dropdown

MultiSelect

Multiple selections from predefined options.

[[elements]]
name = "features"
type = "multiselect"
prompt = "Enable features"
page_size = 10
vim_mode = false

[[elements.options]]
value = "prometheus"
label = "Prometheus Metrics"

[[elements.options]]
value = "grafana"
label = "Grafana Dashboard"

[[elements.options]]
value = "auth"
label = "Authentication"

Attributes:

  • prompt: Display label
  • options: Array of value/label pairs
  • page_size: Number of visible items
  • vim_mode: Enable vim navigation

Backend rendering:

  • CLI: Checkbox list with space to toggle
  • TUI: Multi-selection list with checkboxes
  • Web: HTML checkboxes in group

Date

Date selection with validation.

[[elements]]
name = "start_date"
type = "date"
prompt = "Project start date"
min_date = "2024-01-01"
max_date = "2025-12-31"
week_start = "Mon"
required = true

Attributes:

  • prompt: Display label
  • min_date: Earliest allowed date (ISO 8601)
  • max_date: Latest allowed date (ISO 8601)
  • week_start: Calendar week start day
  • default: Pre-filled date

Backend rendering:

  • CLI: Date input with format validation
  • TUI: Calendar picker widget
  • Web: HTML <input type="date">

Editor

Multi-line text editor for code/configuration.

[[elements]]
name = "config_file"
type = "editor"
prompt = "Configuration content"
file_extension = "toml"
prefix_text = "[settings]\n"
required = true

Attributes:

  • prompt: Display label
  • file_extension: File type for syntax highlighting
  • prefix_text: Pre-filled content
  • required: Validation flag

Backend rendering:

  • CLI: Opens external editor ($EDITOR)
  • TUI: Built-in multi-line editor
  • Web: HTML <textarea> with monospace font

Custom

Custom type with external validation.

[[elements]]
name = "port"
type = "custom"
custom_type = "Port"
prompt = "Server port"
placeholder = "8080"
required = true

Attributes:

  • custom_type: Type name for validation
  • prompt: Display label
  • placeholder: Example value
  • required: Validation flag

Backend rendering:

  • All backends: Text input with custom validator
  • Validation delegated to Nickel contracts

RepeatingGroup

Dynamic array of structured items (add/edit/delete).

[[elements]]
name = "udp_trackers"
type = "repeatinggroup"
prompt = "UDP Tracker Listeners"
fragment = "fragments/udp_trackers_item.toml"
min_items = 0
max_items = 10
default_items = 1
unique = true
required = false
help = "Configure UDP tracker bind addresses"

Attributes:

  • prompt: Display label for the array
  • fragment: Path to fragment file defining array element structure
  • min_items: Minimum required items (0 = optional)
  • max_items: Maximum allowed items
  • default_items: Initial number of items to show
  • unique: Enforce uniqueness constraint (all fields must differ between items)
  • required: Whether array is required
  • help: Additional guidance text

Uniqueness Constraints (Web/TUI/CLI):

  • When unique = true: ALL fields in each item must be different from all other items
    • Example: Cannot add {bind_address: "0.0.0.0:6969"} twice
    • Triggers validation alert: "This item already exists"
  • Within a fragment, individual fields can be marked with unique_key = true to enforce uniqueness on that field only
    • Example: Port numbers must be unique, but bind addresses can repeat

Fragment structure (udp_trackers_item.toml):

name = "udp_trackers_item"
description = "UDP Tracker configuration"
display_mode = "complete"

[[elements]]
name = "bind_address"
type = "text"
prompt = "UDP Bind Address"
placeholder = "0.0.0.0:6969"
default = "0.0.0.0:6969"
required = true
order = 0

Backend rendering:

  • CLI: Interactive menu system ✓

    • [A] Add new item - Open fragment form for new item
    • [E] Edit item - Select and edit existing item
    • [D] Delete item - Select and remove item
    • [C] Continue - Validate min_items and proceed
    • Duplicate detection enforced if unique = true
    • max_items limit enforced with clear feedback
  • TUI: Split-pane interface ✓

    • Left pane: List of items with navigation
    • Right pane: Preview or edit form
    • Keyboard: A=add, E=edit, D=delete, Enter=continue
    • Duplicate detection enforced if unique = true
    • max_items limit enforced with error overlay
    • Item counter showing progress
  • Web: Inline expandable cards (no modal nesting) ✓

    • Item cards showing summary of field values
    • Add Item button expands inline form
    • ✏️ Edit button expands item for inline editing
    • 🗑️ Delete button with confirmation
    • Live counter: Items: X / max_items
    • Duplicate detection enforced if unique = true
    • max_items limit enforced with alert message
    • Independent state per repeating group

JSON output:

{
  "udp_trackers": [
    { "bind_address": "0.0.0.0:6969" },
    { "bind_address": "0.0.0.0:6970" }
  ]
}

Nickel schema mapping:

{
  TrackerUdp = { bind_address | String },
  Config = {
    udp_trackers | Array TrackerUdp | optional
  },
}

Use cases:

  • Multiple listeners (UDP/HTTP servers)
  • Array of database connections
  • List of API endpoints
  • Collection of users/accounts
  • Multiple environment variables
  • Array of network interfaces

Display Elements (Non-Input)

These are not input fields but display-only elements for form organization.

Section Header

Visual separator with title.

[[elements]]
name = "database_header"
type = "section_header"
title = "📊 Database Configuration"
border_top = true
border_bottom = true

Section

Informational text block.

[[elements]]
name = "info"
type = "section"
content = "Configure your database connection settings below."

Group

Container for loading fragments.

[[elements]]
name = "mysql_group"
type = "group"
when = "database_driver == mysql"
includes = ["fragments/database-mysql-section.toml"]

Conditional Display

All field types support conditional visibility via when attribute:

[[elements]]
name = "mysql_password"
type = "password"
prompt = "MySQL Password"
when = "database_driver == mysql"
required = true

Supported operators:

  • ==: Equality
  • !=: Inequality
  • Parentheses for grouping (future)
  • Logical AND/OR (future)

i18n Support

All fields support internationalization via i18n = true:

[[elements]]
name = "username"
type = "text"
prompt = "form.username.prompt"
placeholder = "form.username.placeholder"
i18n = true

Translations resolved from Fluent .ftl files in locales/ directory.


Nickel Integration

Fields automatically map to Nickel contracts:

Field Type Nickel Contract
Text String
Password String
Confirm Bool
Select String (enum)
MultiSelect Array String
Date String (ISO 8601)
Editor String
Custom Custom contract
RepeatingGroup Array Record

Example Nickel schema:

{
  Config = {
    username | String,
    password | String,
    enable_feature | Bool,
    database_driver | [| 'sqlite3, 'mysql, 'postgresql |],
    features | Array String,
    start_date | String,
    udp_trackers | Array { bind_address | String },
  }
}

Backend-Specific Features

CLI Backend

  • Inline validation with immediate feedback
  • Arrow key navigation for Select/MultiSelect
  • External editor support for Editor type
  • Interactive menu for RepeatingGroup

TUI Backend

  • 3-panel layout (fields, input, preview)
  • Mouse and keyboard navigation
  • Real-time form updates
  • Split-pane UI for RepeatingGroup

Web Backend

  • HTML5 input types for validation
  • CSS styling for consistent appearance
  • HTMX for reactive updates
  • Modal overlays for RepeatingGroup

Field Validation

Validation occurs at multiple levels:

  1. Client-side (TypeDialog):

    • Required fields
    • Field type constraints
    • Min/max values (dates, numbers)
    • Array min/max items (RepeatingGroup)
  2. Schema validation (Nickel):

    • Contract enforcement
    • Custom predicates
    • Business logic rules
  3. Server-side (Application):

    • Final validation before processing
    • Database constraints
    • External API verification