Conditional questions#
In this tutorial you will build a form that shows extra questions only when a previous answer matches a specific value.
This is useful for branching forms where some options require additional configuration—for example, enabling a feature and then asking for its settings.
What you will build#
A deployment configuration form that:
Asks which authentication provider to use (
noneoroidc).Shows two extra questions—OIDC server URL and client ID—only when the user selects
oidc.
Prerequisites#
Complete Your first form or be familiar with
create_renderer.
How conditional questions work#
TUI Forms uses the standard JSONSchema allOf / if / then pattern.
"allOf": [
{
"if": { "properties": { "key": { "const": "expected_value" } } },
"then": { "properties": { "extra_field": { <question schema> } } }
}
]
When the user's answer for key equals expected_value, the questions inside
then.properties become active.
Otherwise they are skipped entirely—they will not appear in the returned
answers dict.
The if condition must follow the pattern
{properties: {key: {const: value}}}.
Multiple key–value pairs in a single if block are supported; all conditions
must match for the then questions to become active.
Step 1—Define the base question#
Start with the choice question that controls the branching:
schema = {
"title": "Deployment configuration",
"properties": {
"auth_provider": {
"type": "string",
"title": "Authentication provider",
"default": "none",
"oneOf": [
{"const": "none", "title": "None"},
{"const": "oidc", "title": "OpenID Connect (OIDC)"},
],
},
},
}
Step 2—Add the conditional block#
Append an allOf list at the top level of the schema (alongside properties).
Each item has an if condition and a then block with the extra questions:
schema = {
"title": "Deployment configuration",
"properties": {
"auth_provider": {
"type": "string",
"title": "Authentication provider",
"default": "none",
"oneOf": [
{"const": "none", "title": "None"},
{"const": "oidc", "title": "OpenID Connect (OIDC)"},
],
},
},
"allOf": [
{
"if": {
"properties": {"auth_provider": {"const": "oidc"}}
},
"then": {
"properties": {
"oidc_server_url": {
"type": "string",
"title": "OIDC server URL",
"description": "for example, https://auth.example.com/realms/myrealm",
"default": "",
},
"oidc_client_id": {
"type": "string",
"title": "Client ID",
"default": "my-app",
},
}
},
}
],
}
Step 3—Run the form#
from tui_forms import create_renderer
renderer = create_renderer("stdlib", schema)
answers = renderer.render()
print(answers)
Step 4—Try both branches#
Run the script and select None first:
{'auth_provider': 'none'}
The OIDC questions are skipped; they do not appear in the answers at all.
Run again and select OpenID Connect (OIDC):
{'auth_provider': 'oidc', 'oidc_server_url': 'https://auth.example.com/realms/myrealm', 'oidc_client_id': 'my-app'}
This time both extra questions were asked and their answers are in the dict.
Multiple conditional branches#
You can add more allOf items to handle additional choices.
Each item is evaluated independently:
"allOf": [
{
"if": {"properties": {"auth_provider": {"const": "oidc"}}},
"then": {
"properties": {
"oidc_server_url": {"type": "string", "title": "OIDC server URL"},
"oidc_client_id": {"type": "string", "title": "Client ID"},
}
},
},
{
"if": {"properties": {"auth_provider": {"const": "saml"}}},
"then": {
"properties": {
"saml_metadata_url": {"type": "string", "title": "SAML metadata URL"},
}
},
},
]
Conditionally overriding existing questions#
You can also use allOf to override properties already defined in the base properties block. This is useful for conditionally hiding a field or changing its default value.
Hiding a question#
If you have a question that should only be asked in certain modes, you can define it normally and then override it with format: computed when it should be hidden:
schema = {
"properties": {
"advanced_settings": {
"type": "boolean",
"title": "Enable advanced settings?",
"default": False
},
"expert_mode": {
"type": "boolean",
"title": "Enable expert mode?",
"default": False
}
},
"allOf": [
{
"if": {"properties": {"advanced_settings": {"const": False}}},
"then": {
"properties": {
"expert_mode": {
"format": "computed",
"default": False
}
}
}
}
]
}
In this case, expert_mode is only asked if the user selects Yes for advanced_settings. Otherwise, it is computed as False and skipped.
Relocation behavior#
When you override a property in an allOf block, TUI Forms automatically moves it in the wizard flow to appear right after the question that gates it. This ensures that the user answers dependencies in the correct order.
Next steps#
Computed and constant hidden fields: derive values automatically from what the user answered.
JSONSchema support: full reference for conditional fields and
$refresolution.