Refactor exam date handling to use start_date instead of date in bulk update functionality

This commit is contained in:
Ross
2025-11-06 22:01:57 +00:00
parent 54afa6e6bd
commit ebad9c6bd9
2 changed files with 62 additions and 31 deletions
+61 -30
View File
@@ -1,33 +1,42 @@
{% extends app_name|add:'/base.html' %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-3">
<div id="exam-list-wrapper">
<div class="d-flex justify-content-between align-items-center mb-3">
<div>
<button type="button" class="btn btn-sm btn-outline-primary" id="select-all-btn">Select all</button>
<button type="button" class="btn btn-sm btn-outline-secondary" id="clear-selection-btn">Clear</button>
<button type="button" class="btn btn-sm btn-outline-secondary" id="bulk-toggle-btn">Bulk edit</button>
</div>
<div class="d-flex align-items-center">
<form id="bulk-date-form" hx-post="{% url app_name|add:':exam_bulk_update' %}" hx-target="#exam-list-container" hx-include="#exam-list-container input[name='exam_ids']">
{% for k, v in request.GET.items %}
<input type="hidden" name="{{ k }}" value="{{ v }}" />
{% endfor %}
{% csrf_token %}
<div class="input-group input-group-sm">
<input type="date" class="form-control" name="date" aria-label="Set date">
<button class="btn btn-sm btn-primary" type="submit">Update date</button>
<div id="bulk-controls" class="d-none">
<div>
<button type="button" class="btn btn-sm btn-outline-primary" id="select-all-btn">Select all</button>
<button type="button" class="btn btn-sm btn-outline-secondary" id="clear-selection-btn">Clear</button>
</div>
</form>
<form id="bulk-delete-form" class="ms-2" hx-post="{% url app_name|add:':exam_bulk_delete' %}" hx-target="#exam-list-container" hx-include="#exam-list-container input[name='exam_ids']">
{% for k, v in request.GET.items %}
<input type="hidden" name="{{ k }}" value="{{ v }}" />
{% endfor %}
{% csrf_token %}
<button class="btn btn-sm btn-danger" type="submit" onclick="return confirm('Delete selected exams? This action is irreversible.')">Delete selected</button>
</form>
</div>
</div>
{% include 'generic/partials/_exam_list.html' with filter=filter app_name=app_name %}
<form id="bulk-date-form" class="mt-2" hx-post="{% url app_name|add:':exam_bulk_update' %}" hx-target="#exam-list-container" hx-include="#exam-list-container input[name='exam_ids']">
{% for k, v in request.GET.items %}
<input type="hidden" name="{{ k }}" value="{{ v }}" />
{% endfor %}
{% csrf_token %}
<div class="input-group input-group-sm">
<input type="date" class="form-control" name="date" aria-label="Set date">
<button class="btn btn-sm btn-primary" type="submit">Update date</button>
</div>
</form>
<form id="bulk-delete-form" class="mt-2" hx-post="{% url app_name|add:':exam_bulk_delete' %}" hx-target="#exam-list-container" hx-include="#exam-list-container input[name='exam_ids']">
{% for k, v in request.GET.items %}
<input type="hidden" name="{{ k }}" value="{{ v }}" />
{% endfor %}
{% csrf_token %}
<button class="btn btn-sm btn-danger" type="submit" onclick="return confirm('Delete selected exams? This action is irreversible.')">Delete selected</button>
</form>
</div>
</div>
</div>
{% include 'generic/partials/_exam_list.html' with filter=filter app_name=app_name %}
</div>
{% include "generic/partials/filter_bar.html" with filter=filter app_name=app_name collapse_id="bottom-filter-body" %}
{% endblock %}
@@ -40,25 +49,47 @@
float: right;
opacity: 50%;}
/* Hide selection checkboxes unless bulk-mode is enabled on the wrapper */
#exam-list-wrapper input.exam-select-checkbox { display: none; }
#exam-list-wrapper.bulk-mode input.exam-select-checkbox { display: inline-block; }
/* Show bulk controls area only when not d-none (toggled by JS) */
</style>
{% endblock css %}
{% block extra_js %}
{% block js %}
<script>
document.addEventListener('DOMContentLoaded', function(){
const selectAllBtn = document.getElementById('select-all-btn');
const clearBtn = document.getElementById('clear-selection-btn');
const bulkToggleBtn = document.getElementById('bulk-toggle-btn');
const bulkControls = document.getElementById('bulk-controls');
const examListWrapper = document.getElementById('exam-list-wrapper');
function setAllCheckboxes(checked){
document.querySelectorAll('#exam-list-container input.exam-select-checkbox').forEach(cb => cb.checked = checked);
}
if(selectAllBtn){
selectAllBtn.addEventListener('click', function(){ setAllCheckboxes(true); });
}
if(clearBtn){
clearBtn.addEventListener('click', function(){ setAllCheckboxes(false); });
// Attach select/clear handlers delegated (elements may be hidden initially)
document.addEventListener('click', function(e){
if(e.target && e.target.id === 'select-all-btn'){
setAllCheckboxes(true);
}
if(e.target && e.target.id === 'clear-selection-btn'){
setAllCheckboxes(false);
}
});
if(bulkToggleBtn){
bulkToggleBtn.addEventListener('click', function(){
const enabled = examListWrapper.classList.toggle('bulk-mode');
if(enabled){
bulkControls.classList.remove('d-none');
} else {
bulkControls.classList.add('d-none');
setAllCheckboxes(false);
}
});
}
});
</script>
+1 -1
View File
@@ -1045,7 +1045,7 @@ class ExamViews(View, LoginRequiredMixin):
continue
if new_date is not None:
exam.date = new_date
exam.start_date = new_date
exam.save()
return render(request, "generic/partials/_exam_list.html", {"filter": filter, "app_name": self.app_name})