Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Selectively Apply CSS Styles to Quiz Radio Buttons

I have users take a quiz. After each question, I want to show them whether their answer was correct or incorrect. The correct answer should be highlighted in green, and their answer (if incorrect) should be highlighted in red (using Twitter Bootstrap styles).

I am currently rendering the quiz results page in Django and HTML like so:

{{ player.question }}
<div class="myradio">
    <label for="choice_1"><input id="id_1" type="radio" value="q1" disabled /> {{q1}}</label>
</div>
<div class="myradio">
    <label for="choice_2"><input id="id_2" type="radio" value="q2" disabled /> {{q2}}</label>
</div>
<div class="myradio">
    <label for="choice_3"><input id="id_3" type="radio" value="q3" disabled /> {{q3}}</label>
</div>
<div class="myradio">
    <label for="choice_4"><input id="id_4" type="radio" value="q4" disabled /> {{q4}}</label>
</div>


<p><b>Correct Answer: {{solution}}<b></p>

Total Score: {{total_score}}

I am storing the solution to the question in {{solution}}. I have been trying to figure out how to selectively apply CSS filters if, for example, {{q1}} == {{solution}} that should be highlighted green. I can grab the participant's answer with {{player.submitted_answer}}, and so want to highlight a div element red if {{player.submitted_answer}} != {{solution}}.

I have tried messing around with if statement blocks, but can't seem to get it right. Any ideas?

@cezar, a snippet of pages.py and models.py

In pages.py I have the following class

class Question(Page):
    timeout_seconds = 120

    template_name = 'quiz/Question.html'
    form_model = 'player'
    form_fields = ['submitted_answer', 'confidence']


    def submitted_answer_choices(self):
        qd = self.player.current_question()
        return [
            qd['choice1'],
            qd['choice2'],
            qd['choice3'],
            qd['choice4'],
        ]

    def confidence_error_message(self, value):

        if value == 50:
            return 'Please indicate your confidence in your answer.  It is important you answer accurately.'


    def before_next_page(self):
        self.player.check_correct()

In models.py, the relevant class is Player and Subsession:

class Player(BasePlayer):

trial_counter = models.IntegerField(initial=0)


question_id = models.IntegerField()
confidence = models.FloatField(widget=widgets.Slider(attrs={'step': '0.01'}))
confidence_private = models.FloatField(widget=widgets.Slider(attrs={'step': '0.01'}))

question = models.StringField()
solution = models.StringField()
submitted_answer = models.StringField(widget=widgets.RadioSelect)
submitted_answer_private = models.StringField(widget=widgets.RadioSelect)

is_correct = models.BooleanField()
total_score = models.IntegerField(initial = 0)

def other_player(self):
    return self.get_others_in_group()[0]

def current_question(self):
    return self.session.vars['questions'][self.round_number - 1]

def check_correct(self):
    self.is_correct = self.submitted_answer == self.solution

def check_partner_correspondence(self):
    self.submitted_answer == self.get_others_in_group()[0].submitted_answer

def check_partner_correct(self):
    self.get_others_in_group()[0].submitted_answer == self.solution

def check_if_awarded_points(self):
    self.get_others_in_group()[0].submitted_answer == self.submitted_answer == self.solution

def score_points(self):
    if self.get_others_in_group()[0].submitted_answer == self.submitted_answer == self.solution:
        self.total_score +=1
    else:
        self.total_score -=1


def set_payoff(self):
    if(self.check_if_awarded_points()):
        self.total_score +=1

class Subsession(BaseSubsession):

def creating_session(self):
    if self.round_number == 1:
        self.session.vars['questions'] = Constants.questions
        ## ALTERNATIVE DESIGN:
        ## to randomize the order of the questions, you could instead do:

        # import random
        # randomized_questions = random.sample(Constants.questions, len(Constants.questions))
        # self.session.vars['questions'] = randomized_questions

        ## and to randomize differently for each participant, you could use
        ## the random.sample technique, but assign into participant.vars
        ## instead of session.vars.

    for p in self.get_players():
        question_data = p.current_question()
        p.question_id = question_data['id']
        p.question = question_data['question']
        p.solution = question_data['solution']
like image 200
Parseltongue Avatar asked Jan 01 '26 00:01

Parseltongue


2 Answers

You can accmoplish this with some CSS and minimal templating.

Consider the following HTML template

The key here is class="answer{% if answer == solution %} solution{% endif %}"

<h2>{{ question }}</h2>
<form>
{% for answer in answers %}
    <label for="answer{{ forloop.counter }}">{{ answer }}</label>
    <input id="answer{{ forloop.counter }}" type="radio" name="answer" class="answer{% if answer == solution %} solution{% endif %}" value="{{ answer }}">
    <br/>
{% endfor %}

<p class="result incorrect">Sorry, that was not correct. The solution was {{ solution }}</p>
<p class="result correct">Correct! Answer: {{ solution }}</p>
</form>

With the Following CSS

.result {
    display: none;
}
.answer:checked ~ .result.incorrect{
    display: block;
    color: red;
}
.answer.solution:checked ~ p.result.correct {
    display: block;
    color: green;
}

.answer.solution:checked ~ p.result.incorrect {
    display: none;
}

And the following route

def quiz(request):
    question = "What is 2 + 2?"
    solution = "4"
    answers = [solution, "22", "NaN", "0"]
    random.shuffle(answers)
    return render(request, 'foobar/quiz.html', context=locals())

You would get a result like this jsfiddle

like image 115
sytech Avatar answered Jan 03 '26 14:01

sytech


I agree with @Sapna-Sharma and @albar comment.

You may use a simple CSS class to set the color to green and use a {% if [...] %} template filter to add the the CSS class only to the good answer

You may refer to Django official documentation to know how to handle template filter.

like image 44
A STEFANI Avatar answered Jan 03 '26 15:01

A STEFANI



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!