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 tinymce.widgets import TinyMCE
|
||||||
|
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
|
from crispy_forms.helper import FormHelper
|
||||||
|
from crispy_forms.layout import Layout, Fieldset, Row, Column, Submit
|
||||||
|
|
||||||
|
|
||||||
class UserAnswerForm(ModelForm):
|
class UserAnswerForm(ModelForm):
|
||||||
@@ -105,6 +107,38 @@ class QuestionForm(ModelForm):
|
|||||||
widget=FilteredSelectMultiple(verbose_name="Exams", is_stacked=False),
|
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):
|
def save(self, commit=True):
|
||||||
# Get the unsaved Pizza instance
|
# Get the unsaved Pizza instance
|
||||||
instance = ModelForm.save(self, False)
|
instance = ModelForm.save(self, False)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load partials %}
|
{% load partials %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<!-- <script type="text/javascript" src="/admin/jsi18n/"></script> -->
|
<!-- <script type="text/javascript" src="/admin/jsi18n/"></script> -->
|
||||||
@@ -11,19 +12,33 @@
|
|||||||
{{ form.media }}
|
{{ form.media }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="d-flex justify-content-between align-items-start mb-3 flex-column flex-md-row">
|
<div class="container py-3">
|
||||||
<div>
|
<div class="d-flex justify-content-between align-items-start mb-3 flex-column flex-md-row">
|
||||||
<h2>Submit Question</h2>
|
<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>
|
</div>
|
||||||
{% if question %}
|
|
||||||
{% include 'sbas/question_detail.html#links-partial' %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</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 %}
|
{% endblock %}
|
||||||
|
|||||||
+7
-6
@@ -334,6 +334,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
//}
|
//}
|
||||||
// fallback to any table on the page that looks like it has selection
|
// 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"]')); });
|
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;
|
return any || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,12 +375,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
container.parentNode.insertBefore(wrapper, container);
|
container.parentNode.insertBefore(wrapper, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create controls for any table that looks selectable but lacks a control block
|
//// Create controls for any table that looks selectable but lacks a control block
|
||||||
Array.from(document.querySelectorAll('table')).forEach(function(t){
|
//Array.from(document.querySelectorAll('table')).forEach(function(t){
|
||||||
if (t.querySelector && (t.querySelector('input[name="selection"]') || t.querySelector('input[type="checkbox"]'))) {
|
// if (t.querySelector && (t.querySelector('input[name="selection"]') || t.querySelector('input[type="checkbox"]'))) {
|
||||||
ensureControlsForTable(t);
|
// ensureControlsForTable(t);
|
||||||
}
|
// }
|
||||||
});
|
//});
|
||||||
|
|
||||||
// For every toggle button (supports both unsuffixed and suffixed IDs)
|
// For every toggle button (supports both unsuffixed and suffixed IDs)
|
||||||
document.querySelectorAll('button[id^="toggle-row-selection"]').forEach(function(toggleBtn) {
|
document.querySelectorAll('button[id^="toggle-row-selection"]').forEach(function(toggleBtn) {
|
||||||
|
|||||||
Reference in New Issue
Block a user