feat(#13): Show form elements depending on other form element values

This commit is contained in:
2025-11-30 18:10:51 +01:00
parent 79fbf7ce1b
commit 9dc690715b
19 changed files with 1187 additions and 116 deletions

View File

@@ -97,12 +97,19 @@ Application Form
└── SubSection (FormElementSubSection)
├── title, subtitle
└── Form Elements (FormElement)
├── id (UUID - generated by backend)
├── reference (string - custom key like "art_der_massnahme")
├── type (SELECT, CHECKBOX, RADIOBUTTON, TEXTFIELD, SWITCH, TITLE_BODY_TEXTFIELDS)
├── title, description
── options (FormOption[])
├── value, label
├── processingPurpose
└── employeeDataCategory
── options (FormOption[])
├── value, label
├── processingPurpose
└── employeeDataCategory
└── visibilityCondition (FormElementVisibilityCondition)
├── conditionType (SHOW, HIDE)
├── sourceFormElementReference (string - reference key of source element)
├── expectedValue (string - value to compare against)
└── operator (EQUALS, NOT_EQUALS, IS_EMPTY, IS_NOT_EMPTY)
```
**Dynamic Addition**: Users can add new form elements to any subsection at runtime via the API endpoint:
@@ -185,6 +192,83 @@ User roles in the system:
Roles are managed via Keycloak and enforced using Spring Security's `@PreAuthorize` annotations.
### 10. Conditional Form Element Visibility
Form elements can be conditionally shown or hidden based on the values of other form elements. This enables dynamic forms that adapt to user input.
**Key Concepts**:
- **Visibility Conditions**: Rules attached to form elements that determine when they should be visible
- **Source Element**: The form element whose value is being evaluated
- **Target Element**: The form element with visibility conditions (the one being shown/hidden)
- **Condition Types**:
- `SHOW`: Element is visible only if the condition is met
- `HIDE`: Element is hidden if the condition is met
- **Operators**:
- `EQUALS`: Source value exactly matches expected value (case-insensitive)
- `NOT_EQUALS`: Source value does not match expected value
- `IS_EMPTY`: Source value is empty string
- `IS_NOT_EMPTY`: Source value is not empty
**Implementation Details**:
- Visibility conditions reference other form elements by their **reference key** (custom string identifier)
- Reference keys are stable and meaningful (e.g., "art_der_massnahme", "testphase_findet_statt")
- Each form element can have one visibility condition (single object, not array)
- Hidden fields are automatically excluded from validation
- PDF/HTML exports only include currently visible fields based on form state
- Versioning system captures visibility conditions in snapshots
- Conditions check the **value** property of form options, not labels
**Example Configuration**:
```json
{
"reference": "testphase_zeitraum",
"title": "Testphase Zeitraum",
"description": "Zeitraum der Testphase",
"type": "TEXTFIELD",
"options": [
{
"value": "",
"label": "Testphase Zeitraum",
"processingPurpose": "SYSTEM_OPERATION",
"employeeDataCategory": "NON_CRITICAL"
}
],
"visibilityCondition": {
"conditionType": "SHOW",
"sourceFormElementReference": "testphase_findet_statt",
"expectedValue": "Ja",
"operator": "EQUALS"
}
}
```
In this example, the "Testphase Zeitraum" field is only visible when the form element with reference `testphase_findet_statt` has the value "Ja" selected.
**Frontend Behavior**:
- Visibility is evaluated client-side using the `useFormElementVisibility` composable
- Form elements smoothly appear/disappear as conditions change
- Hidden elements are excluded from the form submission
**Backend Behavior**:
- Visibility is evaluated server-side when generating PDF/HTML exports
- Backend filters form elements before rendering to Thymeleaf templates
- Hidden elements are not included in exported documents
**Best Practices**:
- Avoid circular dependencies (A depends on B, B depends on A)
- Use meaningful reference keys (snake_case recommended, e.g., "art_der_massnahme", "testphase_findet_statt")
- Reference keys should be unique within a form
- Keep visibility logic simple for better user experience
- For radio buttons and selects, use the actual label text as the value
- For checkboxes, checked = "true", unchecked = "false"
- Test visibility conditions thoroughly before deployment
---
## Project Structure