Represents a form question (input field) using SurveyJS-compatible format.
SurveyJS Question Types
Supported types:
"text"- Single-line text input (useinputTypefor email, number, etc.)"comment"- Multi-line text area"dropdown"- Select dropdown"radiogroup"- Radio button group"boolean"- Checkbox/toggle"file"- File upload"paneldynamic"- Repeating child form (templateElementsholds the template; the value is a list of maps, one per entry)
Read-Only Questions
Questions can be marked as readOnly: true to prevent user editing while still
displaying the value. This is commonly used in edit forms where certain
fields (like IDs, creation timestamps, or verified emails) should be visible
but immutable.
Important: Read-only HTML fields are not submitted by browsers. The
DynamicForm.RendererLive component automatically preserves read-only field
values by merging the initial params with form submissions.
Example
%Question{
name: "user_id",
type: "text",
title: "User ID",
readOnly: true
}Conditional Visibility
Questions can be conditionally shown based on the value of another question using the
visibleIf expression. When visibleIf is nil, the question is always visible.
Expression Syntax
"{field} = 'value'"- Show when field equals value"{field} notempty"- Show when field has a value"{field} empty"- Show when field is empty
Examples
# Show when payment_method equals "credit_card"
%Question{
name: "credit_card_number",
type: "text",
title: "Credit Card Number",
visibleIf: "{payment_method} = 'credit_card'"
}
# Show when email has a value
%Question{
name: "email_preferences",
type: "dropdown",
title: "Email Preferences",
visibleIf: "{email} notempty"
}
Summary
Types
@type t() :: %DynamicForm.Instance.Question{ addPanelText: String.t() | nil, allowAddPanel: boolean() | nil, allowRemovePanel: boolean() | nil, choices: list() | nil, confirmDelete: boolean() | nil, confirmDeleteText: String.t() | nil, defaultPanelValue: map() | nil, defaultValue: any(), description: String.t() | nil, enableIf: String.t() | nil, inputType: String.t() | nil, isRequired: boolean() | nil, keyDuplicationError: String.t() | nil, keyName: String.t() | nil, maxPanelCount: integer() | nil, metadata: map() | nil, minPanelCount: integer() | nil, name: String.t(), noEntriesText: String.t() | nil, panelCount: integer() | nil, placeholder: String.t() | nil, rateMax: integer() | nil, rateMin: integer() | nil, rateStep: integer() | nil, readOnly: boolean() | nil, removePanelText: String.t() | nil, requiredIf: String.t() | nil, slot: map() | nil, templateElements: [t() | Element.t()] | nil, templateTitle: String.t() | nil, title: String.t() | nil, type: String.t(), validators: [Validator.t()] | nil, visibleIf: String.t() | nil }