Reihenfolge_Fragetyp(und Lizenzenz_Dateien)

This commit is contained in:
ben8
2025-07-20 14:06:52 +02:00
parent f778107c30
commit 9397da4cfd
19 changed files with 1364 additions and 114 deletions

View File

@@ -97,20 +97,24 @@
class=" mt-1 bg-green-100 text-green-800 px-4 py-2 rounded-md text-xs lg:text-lg hover:border-blue-600 border-2">
Eingabe
</a>
{% endif %}
{% if quiz.user_id == request.user %}
<a href="{% url 'library:new_question' %}?type=multiple_choice&quiz_id={{ quiz.id }}"
class=" mt-1 bg-blue-100 text-blue-800 px-4 py-2 rounded-md text-xs lg:text-lg hover:border-blue-600 border-2">
Multiple Choice
</a>
{% endif %}
{% if quiz.user_id == request.user %}
<a href="{% url 'library:new_question' %}?type=true_false&quiz_id={{ quiz.id }}"
class=" mt-1 bg-purple-100 text-purple-800 px-4 py-2 rounded-md text-xs lg:text-lg hover:border-blue-600 border-2">
Wahr/Falsch
</a>
<a href="{% url 'library:new_question' %}?type=order&quiz_id={{ quiz.id }}"
class=" mt-1 bg-yellow-100 text-yellow-800 px-4 py-2 rounded-md text-xs lg:text-lg hover:border-blue-600 border-2">
Reihenfolge
</a>
{% endif %}
</div>
</div>
@@ -131,8 +135,8 @@
<div class="flex-grow">
<p class="font-medium">{{ question.data.question }}</p>
<div class="mt-1">
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium {% if question.data.type == 'multiple_choice' %}bg-blue-100 text-blue-800 {% elif question.data.type == 'input' %} bg-green-100 text-green-800 {% else %}bg-purple-100 text-purple-800{% endif %}">
{% if question.data.type == 'multiple_choice' %}Multiple Choice{% elif question.data.type == 'input' %}Eingabe{% else %}Wahr/Falsch{% endif %}
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium {% if question.data.type == 'multiple_choice' %}bg-blue-100 text-blue-800 {% elif question.data.type == 'input' %} bg-green-100 text-green-800 {% elif question.data.type == 'true_false' %}bg-purple-100 text-purple-800{% else %}bg-yellow-100 text-yellow-800{% endif %}">
{% if question.data.type == 'multiple_choice' %}Multiple Choice{% elif question.data.type == 'input' %}Eingabe{% elif question.data.type == 'true_false' %}Wahr/Falsch{% else %}Reihenfolge{% endif %}
</span>
</div>
<div class="mt-2">
@@ -141,7 +145,7 @@
{% if question.data.type == 'multiple_choice' %}
<div class="w-full gap-4 md:flex justify-between ">
<ul class="space-y-1 ">
{% for option in question.data.options %}
{% for option in question.data.options|dictsort:"order" %}
<li class="flex items-center text-sm ">
@@ -164,6 +168,21 @@
<img src="{{ question.image.image.url }}" alt="Bild der Frage" class="w-[200px] rounded-lg shadow-md border-blue-600 border-2 rounded-xl shadow-md object-contain mt-4 md:mt-0" />
{% endif %}
</div>
{% elif question.data.type == 'order' %}
<div class="w-full gap-4 md:flex justify-between ">
<ul class="space-y-1 ">
{% for option in question.data.options|dictsort:"order" %}
<li class="flex items-center text-sm">
{{ forloop.counter }}. &nbsp;
<span class="font-medium text-green-700 dark:text-white">{{ option.value }}</span>
</li>
{% endfor %}
</ul>
{% if question.image.image.url %}
<img src="{{ question.image.image.url }}" alt="Bild der Frage" class="w-[200px] rounded-lg shadow-md border-blue-600 border-2 rounded-xl shadow-md object-contain mt-4 md:mt-0" />
{% endif %}
</div>
{% elif question.data.type == 'input' %}
<div class="w-full gap-4 md:flex justify-between ">
@@ -253,12 +272,13 @@
{% endif %}
</div>
<!-- Links müssen wieder ergänzt werden!
{% if questions %}
<div class="flex flex-col sm:flex-row gap-4 items-start sm:items-center my-6">
<!-- Aufgabenblatt herunterladen Button -->
<a href="{% url 'library:quiz_task' pk=quiz.pk %}?show_answers=true"
<a href=""
target="_blank"
class=" inline-flex items-center gap-2 px-2 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white shadow-md transition">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none"
@@ -269,8 +289,8 @@
als Aufgabenblatt herunterladen (PDF)
</a>
<!-- Lösung herunterladen Button -->
<a href="{% url 'library:quiz_solution' pk=quiz.pk %}?show_answers=true"
<a href=""
target="_blank"
class="inline-flex items-center gap-2 px-2 py-2 rounded-lg bg-green-600 hover:bg-green-700 text-white shadow-md transition">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none"
@@ -285,6 +305,7 @@
</div>
{% endif %}
-->
<div class="flex flex-col max-w-full">
<p class="text-gray-600 mt-2 dark:text-white ">Credits: </p>
{% if quiz.credits %}

View File

@@ -41,7 +41,7 @@
<label class="block text-sm font-medium text-gray-700 mb-2 dark:text-white">Antwortmöglichkeiten</label>
<div id="options-container" class="space-y-3">
{% if question and question.data.options %}
{% for option in question.data.options %}
{% for option in question.data.options|dictsort:"order" %}
<div class="flex items-center space-x-3">
<textarea name="option_{{ forloop.counter }}" rows="2"
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 flex-grow sm:text-sm border-gray-300 rounded-md"

View File

@@ -0,0 +1,189 @@
{% extends 'base.html' %}
{% block content %}
<div class="container mx-auto px-4">
<div class="flex justify-between items-center mb-6">
<h1 class="text-2xl font-bold dark:text-white">{% if question %}Frage bearbeiten{% else %}Reihenfolge Frage{% endif %}</h1>
<a href="{% url 'library:detail_quiz' quiz.id %}"
class="bg-gray-100 text-gray-700 px-4 py-2 rounded-md hover:bg-gray-200 transition-colors">
Zurück zum Quiz
</a>
</div>
<div class="bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md dark:bg-transparent dark:text-white">
<form method="post" class="space-y-6" enctype="multipart/form-data">
{% csrf_token %}
<!-- Question Text -->
<div>
<label for="question" class="block text-sm font-medium text-gray-700 dark:text-white">Frage</label>
<div class="mt-1">
<textarea name="question" id="question" rows="4"
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md"
required>{{ question.data.question|default:'' }}</textarea>
</div>
</div>
{% if image %}
<img src="{{ image.image.url }}" style="max-width: 100px;" alt="Bild der Frage">
<label for="reset_image">
<input type="checkbox" name="reset_ques_image" id="reset_ques_image">
Bild zurücksetzen
</label>
{% endif %}
<div>
<label class="font-bold" for="question_image">Bild:</label>
<input value="image.url" class="max-w-full bg-blue-200 p-2 m-2 rounded-lg border-2 border-blue-400 dark:bg-transparent" type="file" name="question_image" id="question_image">
</div>
<!-- Options -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2 dark:text-white">richtige Reihenfolge</label>
<div id="options-container" class="space-y-3">
{% if question and question.data.options %}
{% for option in question.data.options|dictsort:"order" %}
<div class="flex items-center space-x-3">
<span class="number bg-blue-500 p-2 rounded-lg text-white">{{ forloop.counter }}.</span>
<textarea name="option_{{ forloop.counter }}" rows="2"
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 flex-grow sm:text-sm border-gray-300 rounded-md"
required>{{ option.value }}</textarea>
<label class="inline-flex items-center">
</label>
<button type="button" onclick="removeOption(this)"
class="text-red-600 hover:text-red-800 transition-colors">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
</button>
</div>
{% endfor %}
{% else %}
{% for i in "1234" %}
<div class="flex items-center space-x-3">
<span class="number bg-blue-500 p-2 rounded-lg text-white">{{ forloop.counter }}.</span>
<textarea name="option_{{ forloop.counter }}" rows="2"
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 flex-grow sm:text-sm border-gray-300 rounded-md"
required></textarea>
<label class="inline-flex items-center">
</label>
<button type="button" onclick="removeOption(this)"
class="text-red-600 hover:text-red-800 transition-colors">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
</button>
</div>
{% endfor %}
{% endif %}
</div>
<button type="button" onclick="addOption()"
class="mt-3 inline-flex items-center px-3 py-1.5 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
<svg class="h-4 w-4 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
</svg>
Option hinzufügen
</button>
</div>
<div class="p-4">
<label class="font-bold" for="time_per_question">Zeit pro Frage:</label>
<select name="time_per_question" id="time_per_question" class="dark:text-white dark:bg-[#2a2f3a] focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="10" {% if standard_time_per_question == "10" or time_per_question == "10" %}selected{% endif %}>10 Sekunden</option>
<option value="20" {% if standard_time_per_question == "20" or time_per_question == "20" %}selected{% endif %}>20 Sekunden</option>
<option value="30" {% if standard_time_per_question == "30" or time_per_question == "30" %}selected{% endif %}>30 Sekunden</option>
<option value="45" {% if standard_time_per_question == "45" or time_per_question == "45" %}selected{% endif %}>45 Sekunden</option>
<option value="60" {% if standard_time_per_question == "60" or time_per_question == "60" %}selected{% endif %}>1 Minute</option>
<option value="120" {% if standard_time_per_question == "120" or time_per_question == "120" %}selected{% endif %}>2 Minuten</option>
<option value="300" {% if standard_time_per_question == "300" or time_per_question == "300" %}selected{% endif %}>5 Minuten</option>
</select>
</div>
<label for="credits" class="block text-sm font-medium text-gray-700 dark:text-white">Credits</label>
<div class="mt-1">
<textarea name="credits" rows="4"
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md "
>{{ credits }}</textarea>
</div>
<div class="flex justify-end space-x-3">
<a href="{% url 'library:detail_quiz' quiz.id %}"
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Abbrechen
</a>
<button type="submit"
class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
{% if question %}Speichern{% else %}Erstellen{% endif %}
</button>
</div>
</form>
</div>
</div>
<script>
function addOption() {
const container = document.getElementById('options-container');
const optionCount = container.children.length + 1;
if (optionCount > 6) {
alert('Maximal 6 Optionen sind erlaubt.');
return;
}
const div = document.createElement('div');
div.className = 'flex items-center space-x-3';
div.innerHTML = `
<span class="number bg-blue-500 p-2 rounded-lg text-white">${optionCount}.</span>
<textarea name="option_${optionCount}" rows="2"
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 flex-grow sm:text-sm border-gray-300 rounded-md"
required></textarea>
<label class="inline-flex items-center">
</label>
<button type="button" onclick="removeOption(this)"
class="text-red-600 hover:text-red-800 transition-colors">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
</button>
`;
container.appendChild(div);
}
function removeOption(button) {
const container = document.getElementById('options-container');
if (container.children.length > 2) {
button.parentElement.remove();
updateOptionNumbers();
} else {
alert('Mindestens zwei Optionen müssen vorhanden sein.');
}
}
function updateOptionNumbers() {
const container = document.getElementById('options-container');
const options = container.children;
Array.from(options).forEach((option, index) => {
const number = index + 1;
const textInput = option.querySelector('textarea');
textInput.name = `option_${number}`;
const numberSpan = option.querySelector('span.number');
if (numberSpan) {
numberSpan.textContent = `${number}.`;
}
});
}
</script>
{% endblock %}

View File

@@ -1,6 +1,8 @@
{% extends 'base.html' %}
{% block content %}
{% load static %}
<script src="{% static 'js/sortablejs/Sortable.min.js' %}"></script>
<div class="container mx-auto px-4">
@@ -48,7 +50,8 @@
</div>
{% if question_data.type != "input" %}
{% if question_data.type == "multiple_choice" or question_data.type == "true_false" %}
<div class="grid grid-cols-2 gap-4" id="options-container">
{% for option in question_data.options %}
<button
@@ -81,8 +84,70 @@
onclick="submitAnswer({{ forloop.counter0 }});" {% endif %}>
<p class="text-lg">{{ option.value }}</p>
</button>
{% endfor %}
{% endfor %}
</div>
{% elif question_data.type == "order" %}
<div id="sortable-options" class=" mb-4 flex flex-col items-center">
{% for option in question_data.options %}
<button data-index="{{ forloop.counter0 }}"
data-value="{{ option.value }}"
class=" my-2 w-3/4 max-w-xl
{% if forloop.counter0 == 0 %}
bg-green-500
hover:bg-green-600
{% elif forloop.counter0 == 1 %}
bg-red-500
hover:bg-red-600
{% elif forloop.counter0 == 2 %}
bg-blue-500
hover:bg-blue-600
{% elif forloop.counter0 == 3 %}
bg-purple-500
hover:bg-purple-600
{% elif forloop.counter0 == 4 %}
bg-orange-500
hover:bg-orange-600
{% elif forloop.counter0 == 5 %}
bg-yellow-500
hover:bg-yellow-600
{% else %}
bg-gray-500
hover:bg-gray-600
{% endif %}
p-4 rounded-lg text-white transition-colors duration-200 answer-option overflow-auto break-words hyphens-auto "
data-index="{{ forloop.counter0 }}"
>
<p class="text-lg flex items-center">
<span class="order-number inline-block w-8 h-8 rounded-full bg-white text-gray-800 font-bold text-center leading-8 mr-3">1</span>
{{ option.value }}
</p>
</button>
{% endfor %}
</div>
<div class="flex gap-2">
{% if request.session.mode == "learn" %}
<button
onclick="submitOrderAnswer()"
id="send_order" class="mt-2 text-center p-2 bg-gray-100 hover:bg-blue-100 rounded-lg transition-colors duration-200 answer-option dark:bg-transparent dark:text-white dark:hover:bg-[#2a2f3a] ">
abschicken
</button>
{% endif %}
{% else %}
{% if request.session.mode == "learn" %}
<form action="">
@@ -131,8 +196,12 @@
} else if (data.type === 'game_state_update' &&
data.action === 'show_scores' &&
data.redirect_url) {
window.location.href = data.redirect_url;
submitAnswer( -1 );
setTimeout(() => {
submitAnswer( -1 );
window.location.href = data.redirect_url;
}, 1000);
}
};
@@ -180,7 +249,7 @@
'type': 'advance_to_scores',
'host_id': hostId
}));
}, 2000);
}, 0);
}
// Timer
@@ -199,6 +268,7 @@
if (remaining === 0) {
advanceToScores();
} else {
requestAnimationFrame(updateTimer);
}
@@ -281,5 +351,74 @@
}));
}
}
let initialOrder = [];
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('sortable-options');
if (container) {
initialOrder = Array.from(container.children).map(div => div.dataset.index);
Sortable.create(container, {
animation: 150,
onUpdate: updateOrderNumbers // <--- Nummern aktualisieren nach Sortieren
});
updateOrderNumbers(); // initial setzen
}
});
function updateOrderNumbers() {
const container = document.getElementById('sortable-options');
const children = container.children;
for (let i = 0; i < children.length; i++) {
const label = children[i].querySelector('.order-number');
if (label) {
label.textContent = `${i + 1}.`;
}
}
}
function submitOrderAnswer() {
const order_button=document.getElementById("send_order")
order_button.disabled=true;
order_button.classList.add('opacity-50');
const orderedDivs = document.querySelectorAll('#sortable-options button');
const selectedOrder = Array.from(orderedDivs).map(div => div.dataset.value);
const now = Date.now();
let timeRemaining = Math.max(0, questionDuration - (now - questionStartTime));
{% if request.session.mode == "learn" %}
timeRemaining = questionDuration;
{% endif %}
gameSocket.send(JSON.stringify({
type: 'submit_answer',
participant_id: '{{ host_id }}',
answer: selectedOrder,
time_remaining: timeRemaining
}));
hasAnswered = true;
}
function resetOrderSelection() {
const container = document.getElementById('sortable-options');
const divs = Array.from(container.children);
const indexMap = {};
divs.forEach(div => {
indexMap[div.dataset.index] = div;
});
// Sort children back to initial order
container.innerHTML = '';
initialOrder.forEach(i => {
container.appendChild(indexMap[i]);
});
}
</script>
{% endblock %}

View File

@@ -1,6 +1,10 @@
{% extends 'base.html' %}
{% block content %}
{% load static %}
<script src="{% static 'js/sortablejs/Sortable.min.js' %}"></script>
<div class="container mx-auto px-4">
<div class="flex justify-end mb-4">
<button onclick="leaveGame()" class="bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded">
@@ -22,10 +26,11 @@
<div id="time-bar" class="bg-blue-600 h-4 rounded-full transition-all duration-100 linear" style="width: 100%;"></div>
</div>
{% if question_data.type != "input" %}
{% if question_data.type == "multiple_choice" or question_data.type == "true_false" %}
<div class="grid grid-cols-2 gap-4" id="options-container">
{% for option in question_data.options %}
<button
<button data-index="{{ forloop.counter0 }}"
data-value="{{ option.value }}"
class="
{% if forloop.counter0 == 0 %}
bg-green-500
@@ -56,6 +61,71 @@
</button>
{% endfor %}
</div>
{% elif question_data.type == "order" %}
<div id="sortable-options" class=" mb-4 flex flex-col items-center">
{% for option in question_data.options %}
<button data-index="{{ forloop.counter0 }}"
data-value="{{ option.value }}"
class=" my-2 w-3/4 max-w-xl
{% if forloop.counter0 == 0 %}
bg-green-500
hover:bg-green-600
{% elif forloop.counter0 == 1 %}
bg-red-500
hover:bg-red-600
{% elif forloop.counter0 == 2 %}
bg-blue-500
hover:bg-blue-600
{% elif forloop.counter0 == 3 %}
bg-purple-500
hover:bg-purple-600
{% elif forloop.counter0 == 4 %}
bg-orange-500
hover:bg-orange-600
{% elif forloop.counter0 == 5 %}
bg-yellow-500
hover:bg-yellow-600
{% else %}
bg-gray-500
hover:bg-gray-600
{% endif %}
p-4 rounded-lg text-white transition-colors duration-200 answer-option overflow-auto break-words hyphens-auto "
data-index="{{ forloop.counter0 }}"
>
<p class="text-lg flex items-center">
<span class="order-number inline-block w-8 h-8 rounded-full bg-white text-gray-800 font-bold text-center leading-8 mr-3">1</span>
{{ option.value }}
</p>
</button>
{% endfor %}
</div>
<div class="flex gap-2">
<button id="send_order"
onclick="submitOrderAnswer()"
class="mt-2 text-center p-2 bg-gray-100 hover:bg-blue-100 rounded-lg transition-colors duration-200 answer-option dark:bg-transparent dark:text-white dark:hover:bg-[#2a2f3a] ">
abschicken
</button>
{% else %}
<form action="">
<input id="textanswer" type="text" placeholder="DEINE ANTWORT"
@@ -89,7 +159,11 @@
data.action === 'show_scores' &&
data.redirect_url) {
window.location.href = data.redirect_url;
submitAnswer( -1 );
{% if question_data.type == "order" %}
submitOrderAnswer();
{% else %}
submitAnswer(-1);
{% endif %}
}
};
@@ -159,7 +233,13 @@
if (remaining === 0 && !hasAnswered) {
// Auto-submit timeout answer
{% if question_data.type == "order" %}
submitOrderAnswer();
{% else %}
submitAnswer(-1);
{% endif %}
} else if (remaining > 0) {
requestAnimationFrame(updateTimer);
}
@@ -176,5 +256,74 @@
// Start timer when page loads
updateTimer();
let initialOrder = [];
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('sortable-options');
if (container) {
initialOrder = Array.from(container.children).map(div => div.dataset.index);
Sortable.create(container, {
animation: 150,
onUpdate: updateOrderNumbers // <--- Nummern aktualisieren nach Sortieren
});
updateOrderNumbers(); // initial setzen
}
});
function updateOrderNumbers() {
const container = document.getElementById('sortable-options');
const children = container.children;
for (let i = 0; i < children.length; i++) {
const label = children[i].querySelector('.order-number');
if (label) {
label.textContent = `${i + 1}.`;
}
}
}
function submitOrderAnswer() {
const order_button=document.getElementById("send_order")
order_button.disabled=true;
order_button.classList.add('opacity-50');
const orderedDivs = document.querySelectorAll('#sortable-options button');
const selectedOrder = Array.from(orderedDivs).map(div => div.dataset.value);
const now = Date.now();
let timeRemaining = Math.max(0, questionDuration - (now - questionStartTime));
{% if request.session.mode == "learn" %}
timeRemaining = questionDuration;
{% endif %}
gameSocket.send(JSON.stringify({
type: 'submit_answer',
participant_id: participantId,
answer: selectedOrder,
time_remaining: timeRemaining
}));
hasAnswered = true;
}
function resetOrderSelection() {
const container = document.getElementById('sortable-options');
const divs = Array.from(container.children);
const indexMap = {};
divs.forEach(div => {
indexMap[div.dataset.index] = div;
});
// Sort children back to initial order
container.innerHTML = '';
initialOrder.forEach(i => {
container.appendChild(indexMap[i]);
});
}
</script>
{% endblock %}

View File

@@ -4,11 +4,14 @@
<div class="container mx-auto px-4">
<div class="bg-white rounded-lg shadow-md p-6 mb-6 dark:bg-transparent dark:text-white">
<h1 class="text-3xl font-bold mb-6">Ergebnisse</h1>
<div class="mb-6">
<h2 class="text-xl font-bold mb-4">Aktuelle Frage</h2>
<p class="text-lg mb-2">{{ question_data.question }}</p>
{% if question_data.type != "order" %}
<div class="grid grid-cols-2 gap-4">
{% for option in question_data.options %}
<div id="option-box-{{ forloop.counter0 }}" class=" dark:bg-transparent relative p-4 rounded-lg overflow-auto break-words hyphens-auto {% if option.is_correct %} border-2 border-green-500{% else %}border-2 border-red-500{% endif %}">
@@ -22,6 +25,28 @@
</div>
{% endfor %}
</div>
{% else %}
<div id="option-box-0" class="relative p-4 rounded-lg border-2 border-green-500 overflow-auto">
<div id="option-fill-0" class="absolute left-0 top-0 h-full bg-green-300 opacity-50 z-0 transition-all duration-1500" style="width: 0%;"></div>
<div class="relative z-10">
<p class="text-lg">Richtige Reihenfolge</p>
<ul class="">
{% for option in question_data.options|dictsort:"order" %}
<li class="text-lg"> {{ forloop.counter }}. <span class="">{{ option.value }}</span> </li>
{% endfor %}
</ul>
<p class="text-gray-600" id="option-count-0">0 Antworten</p>
</div>
</div>
<div id="option-box-1" class="relative p-4 rounded-lg border-2 border-red-500 overflow-auto mt-2">
<div id="option-fill-1" class="absolute left-0 top-0 h-full bg-red-300 opacity-50 z-0 transition-all duration-1500" style="width: 0%;"></div>
<div class="relative z-10">
<p class="text-lg">Falsche Reihenfolge</p>
<p class="text-gray-600" id="option-count-1">0 Antworten</p>
</div>
</div>
{% endif %}
</div>
<div class="mb-6">