<main class="flex-grow w-full max-w-4xl mx-auto p-6 bg-white shadow-lg rounded-lg mt-6"> {{ title|safe }} <div class="mb-6"> <p class="text-lg font-medium">{{ user.display_name }}</p> <p class="text-gray-600"> Berichtsheft <span class="font-semibold">{{ year }}</span> / <span class="font-semibold">{{ week }}</span> </p> <p class="text-gray-600"> Von: <span class="font-semibold">{{ start_date|date:"d.m.Y" }}</span> bis: <span class="font-semibold">{{ end_date|date:"d.m.Y" }}</span> </p> </div> <form method="post" class="space-y-4" enctype="multipart/form-data"> {% load access set_content %} {% for field in form %} <div class="mb-4"> <label for="{{ field.id_for_label }}"> {{ field.label|safe }} </label> {% if field.id_for_label == "id_department" %} {% if draft is not None %} {{ field|set_content:draft.department }} {% else %} {{ field }} {% endif %} {% else %} {% with content=draft.content|access:field.id_for_label %} {{ field|set_content:content }} {% endwith %} {% endif %} {% if field.errors %} <p class="text-red-500 text-sm">{{ field.errors|join:", " }}</p> {% endif %} </div> {% endfor %} {% csrf_token %} <button type="submit" class="w-full bg-red-600 text-white py-2 px-4 rounded-lg shadow hover:bg-red-700 focus:ring focus:ring-red-400"> Submit </button> </form> <script> function updateDraft() { const formData = {}; {% for field in form %} var field = document.getElementById("{{ field.id_for_label }}"); formData["{{ field.id_for_label }}"] = field.value; {% endfor %} fetch("/draft", { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCSRFToken(), }, body: JSON.stringify(formData), }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } return response.json(); }) .then(data => { console.log('Updated Draft:', data); }) .catch(error => { console.error('Error:', error); }); } function debounce(func, delay) { let timeout; return function (...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), delay); }; } function getCSRFToken() { const name = 'csrftoken'; const cookies = document.cookie.split(';'); for (let cookie of cookies) { cookie = cookie.trim(); if (cookie.startsWith(name + '=')) { return cookie.substring(name.length + 1); } } return null; } function setupListeners() { const textareas = document.querySelectorAll('textarea'); const inputs = document.querySelectorAll('input'); const debouncedSend = debounce(() => updateDraft(), 500); textareas.forEach(textarea => { textarea.addEventListener('input', () => debouncedSend()); }); inputs.forEach(input => { if (input.type === 'text' || input.type === 'email' || input.type === 'password' || input.type === 'hidden') { input.addEventListener('input', () => debouncedSend()); } }); } setupListeners(); </script> </main>