.
This commit is contained in:
@@ -72,29 +72,6 @@
|
||||
{% csrf_token %}
|
||||
|
||||
{% crispy form form.helper %}
|
||||
{% 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" />
|
||||
<div id="case_formset" class="sortable list_formset">
|
||||
<ol>
|
||||
{% for form in case_formset %}
|
||||
<li class="no-error case-formset">
|
||||
{{form.non_field_errors}}
|
||||
{{form.errors}}
|
||||
{{ form }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
{{ case_formset.management_form }}
|
||||
</form>
|
||||
<div id="empty_case_form" style="display:none">
|
||||
<li class='no_error case-formset'>
|
||||
{{ case_formset.empty_form }}
|
||||
</li>
|
||||
</div> {% endcomment %}
|
||||
{% comment %} <input type="submit" class="submit-button" value="Submit" name="submit"> {% endcomment %}
|
||||
</form>
|
||||
<script>
|
||||
|
||||
+17
-10
@@ -1568,8 +1568,10 @@ class CaseCollectionCreate(RevisionMixin, LoginRequiredMixin, CreateView):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CaseCollectionCreate, self).get_context_data(**kwargs)
|
||||
|
||||
if self.request.POST:
|
||||
# Only bind the case formset when the POST actually contains formset data.
|
||||
# We don't require adding cases on create, so if the template doesn't
|
||||
# include the casedetail management fields we should skip validation.
|
||||
if self.request.POST and "casedetail_set-TOTAL_FORMS" in self.request.POST:
|
||||
context["case_formset"] = CaseCollectionCaseFormSet(
|
||||
self.request.POST,
|
||||
self.request.FILES,
|
||||
@@ -1589,14 +1591,19 @@ class CaseCollectionCreate(RevisionMixin, LoginRequiredMixin, CreateView):
|
||||
|
||||
context = self.get_context_data(form=form)
|
||||
case_formset = context["case_formset"]
|
||||
if case_formset.is_valid():
|
||||
response = super().form_valid(form)
|
||||
case_formset.instance = self.object
|
||||
case_formset.save()
|
||||
return response
|
||||
|
||||
else:
|
||||
return super().form_invalid(form)
|
||||
# If the POST included case formset data, validate and save it. Otherwise
|
||||
# skip formset processing so creating a collection without cases redirects
|
||||
# normally to the detail view.
|
||||
if self.request.POST and "casedetail_set-TOTAL_FORMS" in self.request.POST:
|
||||
if case_formset.is_valid():
|
||||
response = super().form_valid(form)
|
||||
case_formset.instance = self.object
|
||||
case_formset.save()
|
||||
return response
|
||||
else:
|
||||
return super().form_invalid(form)
|
||||
# No formset data present: proceed with normal create redirect.
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
"""Redirect to the collection detail page after successful creation."""
|
||||
|
||||
+11
-19
@@ -623,36 +623,32 @@ class UserGroupExamForm(ModelForm):
|
||||
self.fields["anatomy_user_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=AnatomyExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(
|
||||
verbose_name="Anatomy Exams", is_stacked=False
|
||||
),
|
||||
widget=ExamSearchWidget(exam_model=AnatomyExam),
|
||||
)
|
||||
self.fields["rapid_user_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=RapidsExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(verbose_name="Rapid Exams", is_stacked=False),
|
||||
widget=ExamSearchWidget(exam_model=RapidsExam),
|
||||
)
|
||||
self.fields["shorts_user_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=ShortsExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(verbose_name="Shorts Exams", is_stacked=False),
|
||||
widget=ExamSearchWidget(exam_model=ShortsExam),
|
||||
)
|
||||
self.fields["longs_user_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=LongsExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(verbose_name="Longs Exams", is_stacked=False),
|
||||
widget=ExamSearchWidget(exam_model=LongsExam),
|
||||
)
|
||||
self.fields["physics_user_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=PhysicsExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(
|
||||
verbose_name="Physics Exams", is_stacked=False
|
||||
),
|
||||
widget=ExamSearchWidget(exam_model=PhysicsExam),
|
||||
)
|
||||
self.fields["sba_user_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=SbasExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(verbose_name="Sbas Exams", is_stacked=False),
|
||||
widget=ExamSearchWidget(exam_model=SbasExam),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -720,31 +716,27 @@ class CidGroupExamForm(ModelForm):
|
||||
self.fields["anatomy_cid_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=AnatomyExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(
|
||||
verbose_name="Anatomy Exams", is_stacked=False
|
||||
),
|
||||
widget=ExamSearchWidget(exam_model=AnatomyExam),
|
||||
)
|
||||
self.fields["rapid_cid_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=RapidsExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(verbose_name="Rapid Exams", is_stacked=False),
|
||||
widget=ExamSearchWidget(exam_model=RapidsExam),
|
||||
)
|
||||
self.fields["longs_cid_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=LongsExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(verbose_name="Longs Exams", is_stacked=False),
|
||||
widget=ExamSearchWidget(exam_model=LongsExam),
|
||||
)
|
||||
self.fields["physics_cid_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=PhysicsExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(
|
||||
verbose_name="Physics Exams", is_stacked=False
|
||||
),
|
||||
widget=ExamSearchWidget(exam_model=PhysicsExam),
|
||||
)
|
||||
self.fields["sba_cid_user_groups"] = ModelMultipleChoiceField(
|
||||
required=False,
|
||||
queryset=SbasExam.objects.filter(archive=False),
|
||||
widget=FilteredSelectMultiple(verbose_name="Sbas Exams", is_stacked=False),
|
||||
widget=ExamSearchWidget(exam_model=SbasExam),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
||||
@@ -483,6 +483,9 @@ class ExamSearchSelectMultipleWidget:
|
||||
<ul id="{selected_list_id}" class="list-group list-group-flush">
|
||||
{selected_html}
|
||||
</ul>
|
||||
<div class="mt-2 text-end">
|
||||
<button type="button" id="exam_remove_all_{self.name}" class="btn btn-sm btn-outline-danger exam-remove-all-btn d-none" data-field="{self.name}">Remove all</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -583,6 +586,15 @@ class ExamSearchSelectMultipleWidget:
|
||||
}});
|
||||
}}
|
||||
|
||||
// Wire up "Remove all" button for this widget instance
|
||||
const removeAllBtn = document.getElementById('exam_remove_all_' + widgetFieldName);
|
||||
if (removeAllBtn) {{
|
||||
removeAllBtn.addEventListener('click', function(e) {{
|
||||
e.preventDefault();
|
||||
removeAllExamsFromField(widgetFieldName);
|
||||
}});
|
||||
}}
|
||||
|
||||
window.addExamToField = function(fieldName, id, text) {{
|
||||
const sel = document.getElementById('id_' + fieldName);
|
||||
if (!sel) return;
|
||||
@@ -598,6 +610,9 @@ class ExamSearchSelectMultipleWidget:
|
||||
const btn = document.createElement('button'); btn.type = 'button'; btn.className = 'btn btn-sm btn-outline-danger ms-2'; btn.innerText = 'Remove';
|
||||
btn.addEventListener('click', function() {{ removeExamFromField(fieldName, id); }});
|
||||
li.appendChild(span); li.appendChild(btn); listEl.appendChild(li);
|
||||
// update the remove-all button visibility
|
||||
var remBtn = document.getElementById('exam_remove_all_' + fieldName);
|
||||
if (remBtn) {{ remBtn.classList.toggle('d-none', listEl.querySelectorAll('li').length < 2); }}
|
||||
}}
|
||||
|
||||
window.removeExamFromField = function(fieldName, id) {{
|
||||
@@ -606,6 +621,10 @@ class ExamSearchSelectMultipleWidget:
|
||||
for (let i=sel.options.length-1;i>=0;i--) {{ if (sel.options[i].value == id) sel.remove(i); }}
|
||||
const li = document.getElementById('selected_exam_' + fieldName + '_' + id);
|
||||
if (li && li.parentNode) li.parentNode.removeChild(li);
|
||||
// update the remove-all button visibility
|
||||
var remBtn = document.getElementById('exam_remove_all_' + fieldName);
|
||||
var listEl = document.getElementById('selected_exams_' + fieldName);
|
||||
if (remBtn && listEl) {{ remBtn.classList.toggle('d-none', listEl.querySelectorAll('li').length < 2); }}
|
||||
}}
|
||||
|
||||
window.addAllExamsFromResults = function(fieldName) {{
|
||||
@@ -617,6 +636,23 @@ class ExamSearchSelectMultipleWidget:
|
||||
const text = it.getAttribute('data-exam-text') || it.textContent.trim();
|
||||
addExamToField(fieldName, id, text);
|
||||
}});
|
||||
// ensure remove-all button is visible if more than one
|
||||
var remBtn = document.getElementById('exam_remove_all_' + fieldName);
|
||||
var listEl = document.getElementById('selected_exams_' + fieldName);
|
||||
if (remBtn && listEl) {{ remBtn.classList.toggle('d-none', listEl.querySelectorAll('li').length < 2); }}
|
||||
}}
|
||||
|
||||
window.removeAllExamsFromField = function(fieldName) {{
|
||||
const sel = document.getElementById('id_' + fieldName);
|
||||
if (!sel) return;
|
||||
// remove all options
|
||||
for (let i=sel.options.length-1;i>=0;i--) {{ sel.remove(i); }}
|
||||
// clear visible list
|
||||
const listEl = document.getElementById('selected_exams_' + fieldName);
|
||||
if (listEl) {{ listEl.innerHTML = ''; }}
|
||||
// hide remove-all button
|
||||
const remBtn = document.getElementById('exam_remove_all_' + fieldName);
|
||||
if (remBtn) {{ remBtn.classList.add('d-none'); }}
|
||||
}}
|
||||
}})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user