Add case collection update functionality with form handling and template (move from CaseCollection form)
This commit is contained in:
+18
-1
@@ -992,4 +992,21 @@ class CaseDisplaySetForm(forms.ModelForm):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# Optionally, you can filter queryset for findings/structures/conditions here if needed
|
||||
# Optionally, you can filter queryset for findings/structures/conditions here if needed
|
||||
|
||||
|
||||
class CaseCollectionUpdateCaseForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.user = kwargs.pop("user")
|
||||
self.collection = kwargs.pop("collection", None)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_id = "id-case-form"
|
||||
self.helper.form_class = "case-form"
|
||||
self.helper.form_method = "post"
|
||||
self.helper.form_action = "submit"
|
||||
self.helper.form_tag = False
|
||||
self.helper.layout = Layout()
|
||||
class Meta:
|
||||
model = CaseCollection
|
||||
fields = [] # No fields, just for compatibility with UpdateView
|
||||
@@ -37,7 +37,7 @@
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form }}
|
||||
<h3>Cases:</h3>
|
||||
{% comment %} <h3>Cases:</h3>
|
||||
Add cases here. These can only be added once created (they can also be added to cases on creation). Click and drag to change order.
|
||||
<input type="button" value="Add More Cases" id="add_more_case">
|
||||
<input type=button id="case-order-button" title="click and drag to update case order" value="Update case order" />
|
||||
@@ -54,13 +54,14 @@
|
||||
|
||||
</div>
|
||||
{{ case_formset.management_form }}
|
||||
<input type="submit" class="submit-button" value="Submit" name="submit">
|
||||
</form>
|
||||
<div id="empty_case_form" style="display:none">
|
||||
<li class='no_error case-formset'>
|
||||
{{ case_formset.empty_form }}
|
||||
</li>
|
||||
</div>
|
||||
</div> {% endcomment %}
|
||||
<input type="submit" class="submit-button" value="Submit" name="submit">
|
||||
</form>
|
||||
<script>
|
||||
$(document).ready(() => {
|
||||
sortable('.sortable');
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
{% extends "atlas/exams.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load static %}
|
||||
{% block content %}
|
||||
<h2>Update Cases for Case: {{ object.title }}</h2>
|
||||
<form method="post" enctype="multipart/form-data" data-bs-theme="dark">
|
||||
{% csrf_token %}
|
||||
{% crispy form form.helper %}
|
||||
{{ case_formset.management_form }}
|
||||
<div id="case_formset">
|
||||
{% for form in case_formset %}
|
||||
<div class="card mb-3 case-form">
|
||||
<div class="card-body">
|
||||
{{ form.non_field_errors }}
|
||||
{{ form.errors }}
|
||||
{{ form|crispy }}
|
||||
{% if form.can_delete %}
|
||||
<div class="form-check mt-2">
|
||||
{{ form.DELETE }} <label for="{{ form.DELETE.id_for_label }}">Delete</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<!-- Empty form template for JS -->
|
||||
<div id="empty-form" style="display:none;">
|
||||
<div class="card mb-3 case-form">
|
||||
<div class="card-body">
|
||||
{{ case_formset.empty_form|crispy }}
|
||||
{% if case_formset.empty_form.can_delete %}
|
||||
<div class="form-check mt-2">
|
||||
{{ case_formset.empty_form.DELETE }} <label for="{{ case_formset.empty_form.DELETE.id_for_label }}">Delete</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" id="add-case" class="btn btn-secondary mt-2">Add Case</button>
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
{% comment %} <input type=button id="case-order-button" title="click and drag to update case order" value="Update case order" /> {% endcomment %}
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const addBtn = document.getElementById("add-case");
|
||||
const formsetDiv = document.getElementById("case_formset");
|
||||
const emptyFormDiv = document.getElementById("empty-form");
|
||||
let totalForms = document.getElementById("id_casedetail_set-TOTAL_FORMS");
|
||||
|
||||
addBtn.addEventListener("click", function() {
|
||||
let formIdx = parseInt(totalForms.value);
|
||||
let newFormHtml = emptyFormDiv.innerHTML.replace(/__prefix__/g, formIdx);
|
||||
let tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = newFormHtml;
|
||||
// Clear the id field value for the new form
|
||||
let idInput = tempDiv.querySelector('input[name$="-id"]');
|
||||
if (idInput) {
|
||||
idInput.value = "";
|
||||
}
|
||||
formsetDiv.appendChild(tempDiv.firstElementChild);
|
||||
totalForms.value = formIdx + 1;
|
||||
});
|
||||
|
||||
document.getElementById("case-order-button").addEventListener("click", function(e) {
|
||||
const cases = document.querySelectorAll("#case_formset ul");
|
||||
cases.forEach((el, n) => {
|
||||
const inputEl = el.querySelector("input[name$='sort_order']");
|
||||
if (inputEl) {
|
||||
inputEl.value = n + 1;
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -1,5 +1,6 @@
|
||||
{% if request.user.is_authenticated %}
|
||||
Collection: {{collection.name}}-> <a href="{% url 'atlas:collection_detail' pk=collection.pk %}">Overview</a> /
|
||||
<a href="{% url 'atlas:collection_case_update' collection.pk %}">Cases</a> /
|
||||
<a href="{% url 'atlas:collection_history' collection.pk %}">History</a> /
|
||||
<a href="{% url 'atlas:collection_mark_overview' collection.pk %}">Mark</a> /
|
||||
<a href="{% url 'atlas:collection_scores_cid' collection.pk %}">Scores</a> /
|
||||
|
||||
@@ -101,6 +101,11 @@ urlpatterns = [
|
||||
views.collection_history,
|
||||
name="collection_history",
|
||||
),
|
||||
path(
|
||||
"collection/<int:pk>/cases/update",
|
||||
views.CollectionCaseUpdate.as_view(),
|
||||
name="collection_case_update",
|
||||
),
|
||||
path(
|
||||
"collection/add_cases",
|
||||
views.add_cases_to_collection,
|
||||
|
||||
+56
-13
@@ -48,6 +48,7 @@ from .forms import (
|
||||
CaseCollectionAuthorForm,
|
||||
CaseCollectionCaseFormSet,
|
||||
CaseCollectionForm,
|
||||
CaseCollectionUpdateCaseForm,
|
||||
CaseDetailForm,
|
||||
CaseDisplaySetForm,
|
||||
CaseForm,
|
||||
@@ -1023,19 +1024,19 @@ class CaseCollectionUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateVi
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CaseCollectionUpdate, self).get_context_data(**kwargs)
|
||||
if self.request.POST:
|
||||
context["case_formset"] = CaseCollectionCaseFormSet(
|
||||
self.request.POST,
|
||||
self.request.FILES,
|
||||
instance=self.object,
|
||||
form_kwargs={"user": self.request.user, "collection": self.object},
|
||||
)
|
||||
context["case_formset"].full_clean()
|
||||
else:
|
||||
context["case_formset"] = CaseCollectionCaseFormSet(
|
||||
instance=self.object,
|
||||
form_kwargs={"user": self.request.user, "collection": self.object},
|
||||
)
|
||||
#if self.request.POST:
|
||||
# context["case_formset"] = CaseCollectionCaseFormSet(
|
||||
# self.request.POST,
|
||||
# self.request.FILES,
|
||||
# instance=self.object,
|
||||
# form_kwargs={"user": self.request.user, "collection": self.object},
|
||||
# )
|
||||
# context["case_formset"].full_clean()
|
||||
#else:
|
||||
# context["case_formset"] = CaseCollectionCaseFormSet(
|
||||
# instance=self.object,
|
||||
# form_kwargs={"user": self.request.user, "collection": self.object},
|
||||
# )
|
||||
|
||||
context["collection"] = context["casecollection"]
|
||||
return context
|
||||
@@ -1046,6 +1047,7 @@ class CaseCollectionUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateVi
|
||||
|
||||
form.instance.author.add(self.request.user.id)
|
||||
|
||||
return super().form_valid(form)
|
||||
context = self.get_context_data(form=form)
|
||||
case_formset = context["case_formset"]
|
||||
# logger.debug(formset.is_valid())
|
||||
@@ -1363,6 +1365,47 @@ class AtlasUpdate(
|
||||
else:
|
||||
return super().form_invalid(form)
|
||||
|
||||
class CollectionCaseUpdate(
|
||||
RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin, UpdateView):
|
||||
model = CaseCollection
|
||||
form_class = CaseCollectionUpdateCaseForm
|
||||
template_name = "atlas/casecollection_update_case.html"
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs.update({"user": self.request.user, "collection": self.object})
|
||||
|
||||
return kwargs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
if self.request.POST:
|
||||
context["case_formset"] = CaseCollectionCaseFormSet(
|
||||
self.request.POST,
|
||||
self.request.FILES,
|
||||
instance=self.object,
|
||||
form_kwargs={"user": self.request.user, "collection": self.object},
|
||||
)
|
||||
context["case_formset"].full_clean()
|
||||
else:
|
||||
context["case_formset"] = CaseCollectionCaseFormSet(
|
||||
instance=self.object,
|
||||
form_kwargs={"user": self.request.user, "collection": self.object},
|
||||
)
|
||||
context["collection"] = context["casecollection"]
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
context = self.get_context_data(form=form)
|
||||
case_formset = context["case_formset"]
|
||||
if case_formset.is_valid():
|
||||
case_formset.instance = self.object
|
||||
case_formset.save()
|
||||
return super().form_valid(form)
|
||||
else:
|
||||
return self.form_invalid(form)
|
||||
|
||||
|
||||
class AtlasSeriesUpdate(
|
||||
RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin, UpdateView
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user