Add Crispy Forms integration to QuestionForm and update question_form template for improved layout and usability
This commit is contained in:
@@ -24,6 +24,8 @@ from django.forms.widgets import RadioSelect, TextInput, Textarea
|
||||
from tinymce.widgets import TinyMCE
|
||||
|
||||
from dal import autocomplete
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, Fieldset, Row, Column, Submit
|
||||
|
||||
|
||||
class UserAnswerForm(ModelForm):
|
||||
@@ -105,6 +107,38 @@ class QuestionForm(ModelForm):
|
||||
widget=FilteredSelectMultiple(verbose_name="Exams", is_stacked=False),
|
||||
)
|
||||
|
||||
# Crispy Forms helper and layout
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_method = "post"
|
||||
self.helper.form_enctype = "multipart/form-data"
|
||||
self.helper.template_pack = "bootstrap5"
|
||||
self.helper.layout = Layout(
|
||||
Fieldset(
|
||||
"Question",
|
||||
"title",
|
||||
"stem",
|
||||
),
|
||||
Fieldset(
|
||||
"Answers",
|
||||
Row(Column("a_answer", css_class="col-6"), Column("a_feedback", css_class="col-6")),
|
||||
Row(Column("b_answer", css_class="col-6"), Column("b_feedback", css_class="col-6")),
|
||||
Row(Column("c_answer", css_class="col-6"), Column("c_feedback", css_class="col-6")),
|
||||
Row(Column("d_answer", css_class="col-6"), Column("d_feedback", css_class="col-6")),
|
||||
Row(Column("e_answer", css_class="col-6"), Column("e_feedback", css_class="col-6")),
|
||||
"best_answer",
|
||||
),
|
||||
Fieldset(
|
||||
"Feedback",
|
||||
"feedback",
|
||||
),
|
||||
Fieldset(
|
||||
"Metadata",
|
||||
Row(Column("category", css_class="col-6"), Column("exams", css_class="col-6")),
|
||||
Row(Column("open_access", css_class="col-4"), Column("frcr_appropriate", css_class="col-4")),
|
||||
),
|
||||
)
|
||||
self.helper.add_input(Submit("submit", "Submit", css_class="btn btn-primary"))
|
||||
|
||||
def save(self, commit=True):
|
||||
# Get the unsaved Pizza instance
|
||||
instance = ModelForm.save(self, False)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
{% load static %}
|
||||
{% load partials %}
|
||||
{% load crispy_forms_tags %}
|
||||
|
||||
{% block js %}
|
||||
<!-- <script type="text/javascript" src="/admin/jsi18n/"></script> -->
|
||||
@@ -11,19 +12,33 @@
|
||||
{{ form.media }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-start mb-3 flex-column flex-md-row">
|
||||
<div>
|
||||
<h2>Submit Question</h2>
|
||||
<div class="container py-3">
|
||||
<div class="d-flex justify-content-between align-items-start mb-3 flex-column flex-md-row">
|
||||
<div>
|
||||
<h2 class="h4 mb-2">Submit Question</h2>
|
||||
</div>
|
||||
{% if question %}
|
||||
{% include 'sbas/question_detail.html#links-partial' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form action="" method="post" enctype="multipart/form-data" id="anatomyquestion-form">
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form.media }}
|
||||
|
||||
<div class="mb-3">
|
||||
{% crispy form %}
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
<a href="{% url 'sbas:index' %}" class="btn btn-outline-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% if question %}
|
||||
{% include 'sbas/question_detail.html#links-partial' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<form action="" method="post" enctype="multipart/form-data" id="anatomyquestion-form">
|
||||
{% csrf_token %}
|
||||
|
||||
<table>{{ form.as_table }}</table>
|
||||
<input type="submit" class="submit-button" value="Submit" name="submit" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
+7
-6
@@ -334,6 +334,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
//}
|
||||
// fallback to any table on the page that looks like it has selection
|
||||
var any = document.querySelector('table.js-row-selectable') //|| Array.from(document.querySelectorAll('table')).find(function(t){ return t.querySelector && (t.querySelector('input[name="selection"]') || t.querySelector('input[type="checkbox"]')); });
|
||||
console.log('findTableForControl fallback', any);
|
||||
return any || null;
|
||||
}
|
||||
|
||||
@@ -374,12 +375,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
container.parentNode.insertBefore(wrapper, container);
|
||||
}
|
||||
|
||||
// Create controls for any table that looks selectable but lacks a control block
|
||||
Array.from(document.querySelectorAll('table')).forEach(function(t){
|
||||
if (t.querySelector && (t.querySelector('input[name="selection"]') || t.querySelector('input[type="checkbox"]'))) {
|
||||
ensureControlsForTable(t);
|
||||
}
|
||||
});
|
||||
//// Create controls for any table that looks selectable but lacks a control block
|
||||
//Array.from(document.querySelectorAll('table')).forEach(function(t){
|
||||
// if (t.querySelector && (t.querySelector('input[name="selection"]') || t.querySelector('input[type="checkbox"]'))) {
|
||||
// ensureControlsForTable(t);
|
||||
// }
|
||||
//});
|
||||
|
||||
// For every toggle button (supports both unsuffixed and suffixed IDs)
|
||||
document.querySelectorAll('button[id^="toggle-row-selection"]').forEach(function(toggleBtn) {
|
||||
|
||||
Reference in New Issue
Block a user