1

I am working on a Django views based on the following form:

class MyForm(forms.Form):
    def __init__(self, data, examen, *args, **kwargs):
        super(MyForm, self).__init__(data, *args, **kwargs)

        self.fields['q1'] = forms.MultipleChoiceField(
                label=mark_safe("Label question 1"),
                required=True,
                widget=forms.CheckboxSelectMultiple,
                choices=(('1', 'answer 1'), ('2', 'answer 2'), ('3', 'answer 3'))
                )
        self.fields['q2'] = forms.MultipleChoiceField(
                label=mark_safe("Label question 2"),
                required=True,
                widget=forms.CheckboxSelectMultiple,
                choices=(('1', 'answer 4'), ('2', 'answer 5'), ('3', 'answer 6'))
                )
        ... #TODO : add questions q3 to q9
        self.fields['q10'] = forms.MultipleChoiceField(
                label=mark_safe("Label question 10"),
                required=True,
                widget=forms.CheckboxSelectMultiple,
                choices=(('1', 'answer 28'), ('2', 'answer 29'), ('3', 'answer 30'))
                )

Il would like to display on a single view self.fields['q1'] with a [submit] button. The idea is for the user to select the answer he considers as correct and the hit the [submit] button. Following that self.fields['q1'] will turn into read-only and self.fields['q2'] will display just below with again a [submit] button... and son on until self.fields['q10'].

I do believe that the only way to achieve that is to use Javascript (and even JQuery or any other library). The problem is that I'm not very familiar with Javascript and would gladly appreciate hints on how to tackle that issue.

Thank you for what you can do!

PS: I'm happy to change my Django design if you think this is not the proper way to achieve my goal.

EDIT 29/11/2019: my current template looks like:

<form action="{% url 'quizz' my_exam %}" method="post">

    {% csrf_token %}
    {% for field in form %}

        {% ifequal forloop.counter0 0 %}
        <div class="card text-white bg-primary mb-3">
            <div class="card-body">
                <h6 class="card-title">{{ field.label|linebreaksbr }}</h6>
            </div>
        </div>
        {% else %}
            <div class="card">
                <h5 class="card-header">{{field.name}}</h5>
                <div class="card-body">
                    <h6 class="card-title">{{ field.label|linebreaksbr }}</h6>
                    <p class="card-text">{{ field }}</p>
                </div>
            </div>
        {% endifequal %}


    {% endfor %}

    <input type="submit" value="Submit" class="btn btn-primary"/>

</form>

EDIT 30/11/2019: new template based on @Phanti suggestions:

<script>
{% block jquery %}

    $("#submit_2").click(function() {
        $("#questions_container").find(":hidden").show().next();
    }

{% endblock %}
</script>


{% block content %}
<form action="{% url 'quizz' exam %}" method="post">

    {% csrf_token %}

    <div id="questions_container">
    {% for field in form %}

        {% ifequal forloop.counter 1 %}
        <div class="card text-white bg-primary mb-3">
            <div class="card-body">
                <h6 class="card-title">{{ field.label|linebreaksbr }}</h6>
            </div>
        </div>
        {% else %}              
                {% ifequal forloop.counter 2 %}
                    <div id="question_{{ forloop.counter }}" class="card" style="display: block;">
                        <h5 class="card-header">{{field.name}}</h5>
                        <div class="card-body">
                            <h6 class="card-title">{{ field.label|linebreaksbr }}</h6>
                            <p class="card-text">{{ field }}</p>
                        </div>
                    </div>

                    <input id="submit_{{ forloop.counter }}" value="Valider" class="btn btn-primary" style="display: block;"/>
                {% else %}

                    <div id="question_{{ forloop.counter }}" class="card" style="display: none;">
                        <h5 class="card-header">{{field.name}}</h5>
                        <div class="card-body">
                            <h6 class="card-title">{{ field.label|linebreaksbr }}</h6>
                            <p class="card-text">{{ field }}</p>
                        </div>
                    </div>


                    {% if not forloop.last %}
                        <input id="submit_{{ forloop.counter }}" value="Submit" class="btn btn-primary" style="display: none;"/>
                    {% else %}
                        <input id="submit_{{ forloop.counter }}" type="submit" value="Submit" class="btn btn-primary" style="display: none;"/>
                    {% endif %}

                {% endifequal %}

        {% endifequal %}      

    {% endfor %}
    </div>

</form>
{% endblock %}
eric.p999
  • 33
  • 5
  • How does your template look like? Using JS you could hide q2-q10 elements by default unless the user selects/replies to q1 so on and so forth. – JSRB Nov 29 '19 at 18:19
  • @Phanti Thanks for your answer. I just added my html template. It probably is a dummy question but how would you do the hidding? – eric.p999 Nov 29 '19 at 18:39
  • You could assign unique html IDs to each of your forms. Then use JS/jQuery to further manipulate the logic of how to display the forms. This includes several different techniques/languages though. – JSRB Nov 29 '19 at 18:47
  • @Phanti Am I right to believe that it only holds if I have fields only up to 'q10'? For instance, if I want to upgrade my Form to 'q12', I would need to update my html, right? Would you have a snippet or a link to a tutorial doing these kinds of manipulations so I can try to adapt it to my target? Thanks. – eric.p999 Nov 29 '19 at 18:57
  • No worries, you can use loops in JS as well. https://stackoverflow.com/questions/11226489/show-hide-forms-using-buttons-and-javascript – JSRB Nov 29 '19 at 19:50
  • @Phanti Thanks for your guidance. I updated my template to something closer to the solution... I guess. That being I still have few issues: (1) the jquery code does not seem to work as when I click the button, the second form does not display. (2) once it works, how can I turn the first form into read-only? (3) I need to check that with this new code django keeps track of what the user picked. – eric.p999 Nov 30 '19 at 14:34
  • did you include the jQuery library as script into your template? For read-only forms you might check this out: https://stackoverflow.com/questions/368813/html-form-readonly-select-tag-input – JSRB Dec 01 '19 at 08:11
  • @Phanti Thanks. It turns out I had two base.html and the one with the jquery lib was not called. That being said, when I click the button nothing happens. Is there something oviously wrong in: $("#questions_container").find(":hidden").show().next()? – eric.p999 Dec 03 '19 at 20:11
  • It seems it misses a .onclick() function? – JSRB Dec 03 '19 at 20:17
  • @Phanti Is it not the role of the "$("#submit_2").click(function() {"? Sorry, if comment is dum, I know almost nothing to javascript. – eric.p999 Dec 03 '19 at 20:58

0 Answers0