diff --git a/sbas/forms.py b/sbas/forms.py index a5dfdb3c..9ac45f04 100755 --- a/sbas/forms.py +++ b/sbas/forms.py @@ -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) diff --git a/sbas/templates/sbas/question_form.html b/sbas/templates/sbas/question_form.html index 380b16d3..b49e7155 100644 --- a/sbas/templates/sbas/question_form.html +++ b/sbas/templates/sbas/question_form.html @@ -2,6 +2,7 @@ {% load static %} {% load partials %} +{% load crispy_forms_tags %} {% block js %} @@ -11,19 +12,33 @@ {{ form.media }} {% endblock %} {% block content %} -
-
-

Submit Question

+
+
+
+

Submit Question

+
+ {% if question %} + {% include 'sbas/question_detail.html#links-partial' %} + {% endif %} +
+ +
+
+
+ {% csrf_token %} + + {{ form.media }} + +
+ {% crispy form %} +
+ +
+ + Cancel +
+
+
- {% if question %} - {% include 'sbas/question_detail.html#links-partial' %} - {% endif %}
- -
- {% csrf_token %} - - {{ form.as_table }}
- -
{% endblock %} diff --git a/templates/base.html b/templates/base.html index f1e788aa..3f3d4bf4 100644 --- a/templates/base.html +++ b/templates/base.html @@ -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) {