I am currently trying to implement a piece of code in which first I ask a question and after this question is answered I want another question to appear. The problem is that the second question that needs to appear has dynamic fields, which means that the answer of the first question need to be stored in order for the correct choices to appear for the second question. I managed to make the second question appear after the first one receives an answer but it seems that the answer is not stored, so the wrong choices appear for the second question. Does anyone know how to solve this issue?
Here is what I have done up to now:
gossip receiver is the first question and gossip target is the second one.
class Player(BasePlayer):
gossip_receiver = models.IntegerField(
label='To whom do you want to send the information?'
)
gossip_target = models.IntegerField(
label='About whom do you want to send the information?',
)
def gossip_receiver_choices(player):
if player.id_in_group == 1:
choices = [
[2, 'Player 2'],
[3, 'Player 3'],
[4, 'Player 4']]
elif player.id_in_group == 2:
choices = [
[1, 'Player 1'],
[3, 'Player 3'],
[4, 'Player 4']]
elif player.id_in_group == 3:
choices = [
[1, 'Player 1'],
[2, 'Player 2'],
[4, 'Player 4']]
elif player.id_in_group == 4:
choices = [
[1, 'Player 1'],
[2, 'Player 2'],
[3, 'Player 3']]
return choices
def gossip_target_choices(player):
if player.id_in_group == 1 and player.gossip_receiver == 2:
choices = [
[3, 'Player 3'],
[4, 'Player 4']]
elif player.id_in_group == 1 and player.gossip_receiver == 3:
choices = [
[2, 'Player 2'],
[4, 'Player 4']]
elif player.id_in_group == 1 and player.gossip_receiver == 4:
choices = [
[2, 'Player 2'],
[3, 'Player 3']]
elif player.id_in_group == 2 and player.gossip_receiver == 1:
choices = [
[3, 'Player 3'],
[4, 'Player 4']]
elif player.id_in_group == 2 and player.gossip_receiver == 3:
choices = [
[1, 'Player 1'],
[4, 'Player 4']]
elif player.id_in_group == 2 and player.gossip_receiver == 4:
choices = [
[1, 'Player 1'],
[3, 'Player 3']]
elif player.id_in_group == 3 and player.gossip_receiver == 1:
choices = [
[2, 'Player 2'],
[4, 'Player 4']]
elif player.id_in_group == 3 and player.gossip_receiver == 2:
choices = [
[1, 'Player 1'],
[4, 'Player 4']]
elif player.id_in_group == 3 and player.gossip_receiver == 4:
choices = [
[1, 'Player 1'],
[2, 'Player 2']]
elif player.id_in_group == 4 and player.gossip_receiver == 1:
choices = [
[2, 'Player 2'],
[3, 'Player 3']]
elif player.id_in_group == 4 and player.gossip_receiver == 3:
choices = [
[1, 'Player 1'],
[2, 'Player 2']]
elif player.id_in_group == 4 and player.gossip_receiver == 2:
choices = [
[1, 'Player 1'],
[3, 'Player 3']]
else:
choices = [
[1, 'Player 1'],
[2, 'Player 2'],
[3, 'Player 3'],
[4, 'Player 4']]
return choices
HTML:
{% extends "global/Page.html" %}
{% load otree %}
{% block title %}
Information Sharing
{% endblock %}
{% block styles %}
<style>
.otree-timer {
display: none;
}
</style>
<style>
.do-not-show {
display: none;
}
</style>
{% endblock %}
{% block content %}
<div class="card bg-light m-3">
<div class="card-body">
<p>
Which information would you like to share with
{{ formfield 'gossip_receiver' }}
</p>
<div id="industry-box" class="do-not-show">
{{ formfield 'gossip_target' }}
</div>
</div>
</div>
{{ next_button }}
{{ endblock }}
{{ block scripts }}
<script>
let industry_box = document.getElementById("industry-box");
let gossip_receiver_select = document.getElementById("id_gossip_receiver");
let gossip_target_select = document.getElementById("id_gossip_target");
gossip_receiver_select.addEventListener("change", function() {
if (gossip_receiver_select.value != "0") {
industry_box.classList.remove("do-not-show");
gossip_target_select.required = true;
} else {
industry_box.classList.add("do-not-show");
gossip_target_select.required = false;
}
});
</script>
{{ endblock }}
The python code is only executed once when the page is loaded. To respond to player input, you must use javascript.
So you can do this in two steps.
Step 1 (python): Show the player only the other players (and not himself) in the selection list of the second question. For example as follows:
Step 2 (javascript): Hide the answer option that the player has already selected in the first question. For example as follows: