فهرست منبع

feat: add support for making questions optional

AI 2 روز پیش
والد
کامیت
6926577231
5فایلهای تغییر یافته به همراه62 افزوده شده و 8 حذف شده
  1. 10 6
      answer.php
  2. 12 1
      assets/js/create.js
  3. 11 0
      data/answers/form_69d588f45f7ad_ans_69d588fee710d.json
  4. 27 0
      data/forms/form_69d588f45f7ad.json
  5. 2 1
      docs/ai_spec.md

+ 10 - 6
answer.php

@@ -76,7 +76,11 @@ if ($edit_id) {
                 
                 <?php foreach ($form_data['questions'] as $q): ?>
                     <div class="form-group">
-                        <label><?= htmlspecialchars($q['label']) ?> *</label>
+                        <?php 
+                        $is_required = !isset($q['required']) || $q['required'] === true;
+                        $req_attr = $is_required ? 'required' : '';
+                        ?>
+                        <label><?= htmlspecialchars($q['label']) ?><?= $is_required ? ' *' : '' ?></label>
                         <?php 
                         $val = $existing_answers[$q['id']] ?? ''; 
                         $is_array_val = is_array($val);
@@ -101,7 +105,7 @@ if ($edit_id) {
                         }
 
                         if ($q['type'] === 'textarea'): ?>
-                            <textarea id="<?= htmlspecialchars($q['id']) ?>" name="answers[<?= htmlspecialchars($q['id']) ?>]" rows="4" required><?= htmlspecialchars(is_string($val) ? $val : '') ?></textarea>
+                            <textarea id="<?= htmlspecialchars($q['id']) ?>" name="answers[<?= htmlspecialchars($q['id']) ?>]" rows="4" <?= $req_attr ?>><?= htmlspecialchars(is_string($val) ? $val : '') ?></textarea>
                         
                         <?php elseif ($q['type'] === 'single_choice'): ?>
                             <div class="options-container" style="display:flex; flex-direction:column; gap:0.5rem; margin-top:0.5rem;">
@@ -109,13 +113,13 @@ if ($edit_id) {
                                     $checked = (is_string($val) && $val === $opt) ? 'checked' : '';
                                 ?>
                                     <label style="font-weight:normal; display:flex; align-items:center; gap:0.5rem;">
-                                        <input type="radio" name="answers[<?= htmlspecialchars($q['id']) ?>]" value="<?= htmlspecialchars($opt) ?>" required <?= $checked ?> style="width:auto; margin:0;">
+                                        <input type="radio" name="answers[<?= htmlspecialchars($q['id']) ?>]" value="<?= htmlspecialchars($opt) ?>" <?= $req_attr ?> <?= $checked ?> style="width:auto; margin:0;">
                                         <?= htmlspecialchars($opt) ?>
                                     </label>
                                 <?php endforeach; ?>
                                 <?php if (!empty($q['allow_free_text'])): ?>
                                     <label style="font-weight:normal; display:flex; align-items:center; gap:0.5rem;">
-                                        <input type="radio" name="answers[<?= htmlspecialchars($q['id']) ?>]" value="__freetext__" required <?= $is_freetext_val ? 'checked' : '' ?> style="width:auto; margin:0;">
+                                        <input type="radio" name="answers[<?= htmlspecialchars($q['id']) ?>]" value="__freetext__" <?= $req_attr ?> <?= $is_freetext_val ? 'checked' : '' ?> style="width:auto; margin:0;">
                                         Sonstiges:
                                         <input type="text" name="answers_freetext[<?= htmlspecialchars($q['id']) ?>]" value="<?= htmlspecialchars($freetext_content) ?>" style="margin-left: 0.5rem; flex:1;">
                                     </label>
@@ -142,7 +146,7 @@ if ($edit_id) {
                             </div>
 
                         <?php elseif ($q['type'] === 'dropdown'): ?>
-                            <select id="<?= htmlspecialchars($q['id']) ?>" name="answers[<?= htmlspecialchars($q['id']) ?>]" required>
+                            <select id="<?= htmlspecialchars($q['id']) ?>" name="answers[<?= htmlspecialchars($q['id']) ?>]" <?= $req_attr ?>>
                                 <option value="">-- Bitte auswählen --</option>
                                 <?php foreach ($q['options'] as $opt): 
                                     $selected = (is_string($val) && $val === $opt) ? 'selected' : '';
@@ -152,7 +156,7 @@ if ($edit_id) {
                             </select>
 
                         <?php else: ?>
-                            <input type="text" id="<?= htmlspecialchars($q['id']) ?>" name="answers[<?= htmlspecialchars($q['id']) ?>]" required value="<?= htmlspecialchars(is_string($val) ? $val : '') ?>">
+                            <input type="text" id="<?= htmlspecialchars($q['id']) ?>" name="answers[<?= htmlspecialchars($q['id']) ?>]" <?= $req_attr ?> value="<?= htmlspecialchars(is_string($val) ? $val : '') ?>">
                         <?php endif; ?>
                     </div>
                 <?php endforeach; ?>

+ 12 - 1
assets/js/create.js

@@ -48,6 +48,10 @@ function addQuestion(type) {
             <label>Fragetext</label>
             <input type="text" class="question-label" required placeholder="Gib hier deine Frage ein">
         </div>
+        <div class="form-group mt-1 mb-0" style="flex-direction:row; align-items:center;">
+            <input type="checkbox" class="question-required" id="req_${id}" checked style="width:auto; margin-right:8px;">
+            <label for="req_${id}" style="margin:0; font-weight:normal;">Pflichtfrage</label>
+        </div>
     `;
 
     if (needsOptions) {
@@ -96,6 +100,7 @@ function prepareSubmission(e) {
         let labelInput = item.querySelector('.question-label');
         let optionsInput = item.querySelector('.question-options');
         let freetextInput = item.querySelector('.question-freetext');
+        let requiredInput = item.querySelector('.question-required');
         
         let label = labelInput ? labelInput.value.trim() : '';
         if (!label) {
@@ -114,13 +119,19 @@ function prepareSubmission(e) {
         if (freetextInput && freetextInput.checked) {
             allowFreeText = true;
         }
+        
+        let isRequired = true;
+        if (requiredInput && !requiredInput.checked) {
+            isRequired = false;
+        }
 
         questions.push({
             id: item.dataset.id,
             type: item.dataset.type,
             label: label,
             options: options,
-            allow_free_text: allowFreeText
+            allow_free_text: allowFreeText,
+            required: isRequired
         });
     });
 

+ 11 - 0
data/answers/form_69d588f45f7ad_ans_69d588fee710d.json

@@ -0,0 +1,11 @@
+{
+    "answer_id": "ans_69d588fee710d",
+    "form_id": "form_69d588f45f7ad",
+    "respondent_name": "Josef",
+    "respondent_email": "jsoef@mailpit.medowar.de",
+    "submitted_at": "2026-04-07T22:45:18+00:00",
+    "answers": {
+        "q_1775601892539_1": "kk",
+        "q_1775601894901_2": "test1"
+    }
+}

+ 27 - 0
data/forms/form_69d588f45f7ad.json

@@ -0,0 +1,27 @@
+{
+    "id": "form_69d588f45f7ad",
+    "title": "dfgsdfg",
+    "description": "",
+    "admin_email": "",
+    "admin_token": "f7b6071c291b8fce5492786fd1b20753",
+    "created_at": "2026-04-07T22:45:08+00:00",
+    "questions": [
+        {
+            "id": "q_1775601892539_1",
+            "type": "text",
+            "label": "ggg",
+            "options": [],
+            "allow_free_text": false
+        },
+        {
+            "id": "q_1775601894901_2",
+            "type": "single_choice",
+            "label": "Test",
+            "options": [
+                "test1",
+                "Test2"
+            ],
+            "allow_free_text": false
+        }
+    ]
+}

+ 2 - 1
docs/ai_spec.md

@@ -31,7 +31,8 @@ Structure Schema:
       "type": "text | textarea | single_choice | multiple_choice | dropdown",
       "label": "String",
       "options": ["Array of Strings if applicable"],
-      "allow_free_text": "Boolean (true/false) - for choice configurations"
+      "allow_free_text": "Boolean (true/false) - for choice configurations",
+      "required": "Boolean (true/false) - dictates if answering is mandatory"
     }
   ]
 }