create.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. let questionIndex = 0;
  2. // Initialize SortableJS
  3. document.addEventListener("DOMContentLoaded", function() {
  4. var canvas = document.getElementById('builder-canvas');
  5. if (canvas) {
  6. new Sortable(canvas, {
  7. animation: 150,
  8. handle: '.builder-handle',
  9. ghostClass: 'sortable-ghost',
  10. });
  11. }
  12. });
  13. function addQuestion(type) {
  14. const canvas = document.getElementById('builder-canvas');
  15. const emptyState = document.getElementById('empty-state');
  16. if (emptyState) {
  17. emptyState.remove();
  18. }
  19. questionIndex++;
  20. const id = 'q_' + Date.now() + '_' + questionIndex;
  21. let typeLabel = '';
  22. const needsOptions = ['single_choice', 'multiple_choice', 'dropdown'].includes(type);
  23. const supportsFreeText = ['single_choice', 'multiple_choice'].includes(type);
  24. switch(type) {
  25. case 'text': typeLabel = 'Textfeld'; break;
  26. case 'textarea': typeLabel = 'Textbereich'; break;
  27. case 'single_choice': typeLabel = 'Einzelauswahl'; break;
  28. case 'multiple_choice': typeLabel = 'Mehrfachauswahl'; break;
  29. case 'dropdown': typeLabel = 'Dropdown'; break;
  30. }
  31. const div = document.createElement('div');
  32. div.className = 'builder-item';
  33. div.dataset.id = id;
  34. div.dataset.type = type;
  35. let html = `
  36. <div class="builder-handle">
  37. <span>☰ ${typeLabel}</span>
  38. <button type="button" class="modal-close" style="position:relative; top:0; right:0;" onclick="removeQuestion(this)">&times;</button>
  39. </div>
  40. <div class="form-group" style="margin-bottom:0;">
  41. <label>Fragetext</label>
  42. <input type="text" class="question-label" required placeholder="Gib hier deine Frage ein">
  43. </div>
  44. <div class="form-group mt-1 mb-0" style="flex-direction:row; align-items:center;">
  45. <input type="checkbox" class="question-required" id="req_${id}" checked style="width:auto; margin-right:8px;">
  46. <label for="req_${id}" style="margin:0; font-weight:normal;">Pflichtfrage</label>
  47. </div>
  48. `;
  49. if (needsOptions) {
  50. html += `
  51. <div class="form-group mt-2 mb-0">
  52. <label>Optionen (eine pro Zeile)</label>
  53. <textarea class="question-options" rows="3" required placeholder="Option 1\nOption 2\nOption 3"></textarea>
  54. </div>
  55. `;
  56. if (supportsFreeText) {
  57. html += `
  58. <div class="form-group mt-1 mb-0" style="flex-direction:row; align-items:center;">
  59. <input type="checkbox" class="question-freetext" id="freetext_${id}" style="width:auto; margin-right:8px;">
  60. <label for="freetext_${id}" style="margin:0; font-weight:normal;">Freitext erlauben ("Sonstiges")</label>
  61. </div>
  62. `;
  63. }
  64. }
  65. div.innerHTML = html;
  66. canvas.appendChild(div);
  67. }
  68. function removeQuestion(btn) {
  69. btn.closest('.builder-item').remove();
  70. const canvas = document.getElementById('builder-canvas');
  71. if (canvas.children.length === 0) {
  72. canvas.innerHTML = '<div class="alert alert-info" id="empty-state">Noch keine Fragen hinzugefügt. Verwende die Schaltflächen oben.</div>';
  73. }
  74. }
  75. function prepareSubmission(e) {
  76. const questions = [];
  77. const items = document.querySelectorAll('.builder-item');
  78. if (items.length === 0) {
  79. e.preventDefault();
  80. alert("Bitte füge mindestens eine Frage hinzu.");
  81. return;
  82. }
  83. let hasEmptyLabel = false;
  84. let hasEmptyOptions = false;
  85. items.forEach((item) => {
  86. let labelInput = item.querySelector('.question-label');
  87. let optionsInput = item.querySelector('.question-options');
  88. let freetextInput = item.querySelector('.question-freetext');
  89. let requiredInput = item.querySelector('.question-required');
  90. let label = labelInput ? labelInput.value.trim() : '';
  91. if (!label) {
  92. hasEmptyLabel = true;
  93. }
  94. let options = [];
  95. if (optionsInput) {
  96. options = optionsInput.value.split('\n').map(o => o.trim()).filter(o => o);
  97. if (options.length === 0) {
  98. hasEmptyOptions = true;
  99. }
  100. }
  101. let allowFreeText = false;
  102. if (freetextInput && freetextInput.checked) {
  103. allowFreeText = true;
  104. }
  105. let isRequired = true;
  106. if (requiredInput && !requiredInput.checked) {
  107. isRequired = false;
  108. }
  109. questions.push({
  110. id: item.dataset.id,
  111. type: item.dataset.type,
  112. label: label,
  113. options: options,
  114. allow_free_text: allowFreeText,
  115. required: isRequired
  116. });
  117. });
  118. if (hasEmptyLabel) {
  119. e.preventDefault();
  120. alert("Bitte fülle alle Fragetexte aus.");
  121. return;
  122. }
  123. if (hasEmptyOptions) {
  124. e.preventDefault();
  125. alert("Bitte gib mindestens eine Option für deine Auswahlfragen an.");
  126. return;
  127. }
  128. document.getElementById('questions_input').value = JSON.stringify(questions);
  129. }