diff --git a/docs/DataStructure.md b/docs/DataStructure.md
index 52b793110..909706f04 100644
--- a/docs/DataStructure.md
+++ b/docs/DataStructure.md
@@ -308,6 +308,9 @@ Supported trigger types for conditional questions:
| `multiple_unique` | `option_selected` | Radio buttons - the selected option |
| `dropdown` | `option_selected` | Dropdown - the selected option |
| `multiple` | `options_combination` | Checkboxes - all options of a combination |
+| `date` | `date_range` | Date - range including its bounds (`YYYY-MM-DD`) |
+| `datetime` | `date_range` | Deprecated date and time (`YYYY-MM-DD HH:mm`) |
+| `time` | `date_range` | Time - range including its bounds (`HH:mm`) |
A branch is shown when any of its conditions matches. Several branches can be shown at once.
@@ -357,6 +360,18 @@ Conditions determine when a branch is activated. The structure depends on the tr
All options in `optionIds` must be selected for the condition to match.
+#### date_range (for date, datetime, time)
+
+```json
+{ "type": "date_range", "min": "2024-01-01", "max": "2024-12-31" }
+```
+
+```json
+{ "type": "date_range", "min": "09:00", "max": "17:00" }
+```
+
+`min` and `max` use the answer format of the trigger type and are optional.
+
### Conditional Question Example
A complete conditional question structure:
diff --git a/lib/Constants.php b/lib/Constants.php
index bd7ee9c77..e4352a230 100644
--- a/lib/Constants.php
+++ b/lib/Constants.php
@@ -261,6 +261,7 @@ class Constants {
*/
public const CONDITION_TYPE_OPTION_SELECTED = 'option_selected';
public const CONDITION_TYPE_OPTIONS_COMBINATION = 'options_combination';
+ public const CONDITION_TYPE_DATE_RANGE = 'date_range';
/**
* Trigger types allowed for conditional questions
@@ -270,6 +271,9 @@ class Constants {
self::ANSWER_TYPE_MULTIPLEUNIQUE => [self::CONDITION_TYPE_OPTION_SELECTED],
self::ANSWER_TYPE_DROPDOWN => [self::CONDITION_TYPE_OPTION_SELECTED],
self::ANSWER_TYPE_MULTIPLE => [self::CONDITION_TYPE_OPTIONS_COMBINATION],
+ self::ANSWER_TYPE_DATE => [self::CONDITION_TYPE_DATE_RANGE],
+ self::ANSWER_TYPE_DATETIME => [self::CONDITION_TYPE_DATE_RANGE],
+ self::ANSWER_TYPE_TIME => [self::CONDITION_TYPE_DATE_RANGE],
];
/**
diff --git a/lib/Service/SubmissionService.php b/lib/Service/SubmissionService.php
index f4fa13358..56623edfe 100644
--- a/lib/Service/SubmissionService.php
+++ b/lib/Service/SubmissionService.php
@@ -1159,6 +1159,36 @@ private function evaluateBranchConditions(string $triggerType, array $triggerAns
}
}
return false;
+ case Constants::ANSWER_TYPE_DATE:
+ case Constants::ANSWER_TYPE_DATETIME:
+ case Constants::ANSWER_TYPE_TIME:
+ // Date range conditions
+ $dateValue = $triggerAnswer[0] ?? '';
+ if (empty($dateValue)) {
+ return false;
+ }
+ $format = Constants::ANSWER_PHPDATETIME_FORMAT[$triggerType] ?? 'Y-m-d';
+ $date = \DateTime::createFromFormat('!' . $format, $dateValue);
+ if (!$date) {
+ return false;
+ }
+
+ foreach ($conditions as $condition) {
+ $min = isset($condition['min']) ? \DateTime::createFromFormat('!' . $format, $condition['min']) : null;
+ $max = isset($condition['max']) ? \DateTime::createFromFormat('!' . $format, $condition['max']) : null;
+
+ $inRange = true;
+ if ($min && $date < $min) {
+ $inRange = false;
+ }
+ if ($max && $date > $max) {
+ $inRange = false;
+ }
+ if ($inRange) {
+ return true;
+ }
+ }
+ return false;
default:
return false;
}
diff --git a/src/components/Conditional/BranchConditionEditor.vue b/src/components/Conditional/BranchConditionEditor.vue
index eb74f74b0..9b3b938a7 100644
--- a/src/components/Conditional/BranchConditionEditor.vue
+++ b/src/components/Conditional/BranchConditionEditor.vue
@@ -31,17 +31,39 @@
@update:modelValue="onMultipleOptionsSelect" />
+
+
+
+
+
+ -
+
+
+