create.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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="Geben Sie hier Ihre Frage ein">
  43. </div>
  44. `;
  45. if (needsOptions) {
  46. html += `
  47. <div class="form-group mt-2 mb-0">
  48. <label>Optionen (eine pro Zeile)</label>
  49. <textarea class="question-options" rows="3" required placeholder="Option 1\nOption 2\nOption 3"></textarea>
  50. </div>
  51. `;
  52. if (supportsFreeText) {
  53. html += `
  54. <div class="form-group mt-1 mb-0" style="flex-direction:row; align-items:center;">
  55. <input type="checkbox" class="question-freetext" id="freetext_${id}" style="width:auto; margin-right:8px;">
  56. <label for="freetext_${id}" style="margin:0; font-weight:normal;">Freitext erlauben ("Sonstiges")</label>
  57. </div>
  58. `;
  59. }
  60. }
  61. div.innerHTML = html;
  62. canvas.appendChild(div);
  63. }
  64. function removeQuestion(btn) {
  65. btn.closest('.builder-item').remove();
  66. const canvas = document.getElementById('builder-canvas');
  67. if (canvas.children.length === 0) {
  68. canvas.innerHTML = '<div class="alert alert-info" id="empty-state">Noch keine Fragen hinzugefügt. Verwenden Sie die Schaltflächen oben.</div>';
  69. }
  70. }
  71. function prepareSubmission(e) {
  72. const questions = [];
  73. const items = document.querySelectorAll('.builder-item');
  74. if (items.length === 0) {
  75. e.preventDefault();
  76. alert("Bitte fügen Sie mindestens eine Frage hinzu.");
  77. return;
  78. }
  79. let hasEmptyLabel = false;
  80. let hasEmptyOptions = false;
  81. items.forEach((item) => {
  82. let labelInput = item.querySelector('.question-label');
  83. let optionsInput = item.querySelector('.question-options');
  84. let freetextInput = item.querySelector('.question-freetext');
  85. let label = labelInput ? labelInput.value.trim() : '';
  86. if (!label) {
  87. hasEmptyLabel = true;
  88. }
  89. let options = [];
  90. if (optionsInput) {
  91. options = optionsInput.value.split('\n').map(o => o.trim()).filter(o => o);
  92. if (options.length === 0) {
  93. hasEmptyOptions = true;
  94. }
  95. }
  96. let allowFreeText = false;
  97. if (freetextInput && freetextInput.checked) {
  98. allowFreeText = true;
  99. }
  100. questions.push({
  101. id: item.dataset.id,
  102. type: item.dataset.type,
  103. label: label,
  104. options: options,
  105. allow_free_text: allowFreeText
  106. });
  107. });
  108. if (hasEmptyLabel) {
  109. e.preventDefault();
  110. alert("Bitte füllen Sie alle Fragetexte aus.");
  111. return;
  112. }
  113. if (hasEmptyOptions) {
  114. e.preventDefault();
  115. alert("Bitte geben Sie mindestens eine Option für Ihre Auswahlfragen an.");
  116. return;
  117. }
  118. document.getElementById('questions_input').value = JSON.stringify(questions);
  119. }