0

I'm designing an experiment in oTree which uses points during the main part but in the questionnaires, I'd like it to use currency instead.

The last thing I tried was this, in settings.py:

for app in SESSION_CONFIGS[0]["app_sequence"]:
    if app == "A05_Questionnaires":
        USE_POINTS = False
    else:
        USE_POINTS = True

and then

altruism1 = models.CurrencyField(max=100, label="blabla", blank=True)

Interestingly, this did not lead to any error messages but oTree seemed to choose randomly whether to use currency or points this time.

I also tried using a FloatField for altruism1 instead and restricting it to two decimal places:

altruism1 = models.FloatField(max=100, label="blabla", blank=True)

and then in the Page class

@staticmethod
def error_message(player, values):
  if round(values["altruism1"], 2) % 0.01 != 0:
    return("error message")

but this produces a floating-point error I guess - there's always some deviation from 0.

[EDIT] I also tried some JavaScript in my template, adding an extra confirmation button before submitting the form in order to check the input, but I quickly gave up because a) pressing Enter still evoked the same error messages as before, ignoring my button completely and b) the button did nothing yet:

{{ block title }}
    Page title
{{ endblock }}


{{ block content }}
<p>
    {{ formfield "altruism1" }}
    {{formfield "altruism1_noanswer" }}
{#    <div id="donation-button" style="visibility: hidden;"> <input type="button" value="confirm" onclick="onClickCheck()" onkeypress="onClickCheck()"> </div>
#}
</p>

<div id="next-button" style="visibility: hidden;">  {{ next_button }} </div>

{{ endblock }}

{{ block scripts }}

<script>

let altruism1Select = document.getElementById("id_altruism1")
let altruism1NoanswerSelect = document.getElementById("id_altruism1_noanswer")

altruism1Select.addEventListener("click", function() {
    forminputs.altruism1_noanswer.checked = false;
    document.getElementById("next-button").style.visibility = "visible";

    forminputs.altruism1_noanswer.required = false;
    forminputs.altruism1.required = true;
});

altruism1NoanswerSelect.addEventListener("click", function() {
    altruism1Select.value = "";
    document.getElementById("next-button").style.visibility = "visible";
    document.getElementById("donation-button").style.visibility = "hidden";

    forminputs.altruism1_noanswer.required = true;
    forminputs.altruism1.required = false;
})


function onClickCheck() {
    if(forminputs.altruism1.value.isNaN() = false){
        if(forminputs.altruism1.value % 0.01 != 0) {
            alert("Please enter a number with two decimal places or less.");
        } else {
            document.getElementById("donation-button").style.visibility = "hidden";
            document.getElementById("next-button").style.visibility = "visible";
        }
    } else {
        alert("Please enter a number with two decimal places or less.");
    }
}



</script>

{{ endblock }}
Leni
  • 1
  • 2
  • I decided to set USE_POINTS=False and then used IntegerFields for the part of the experiment where I need points. This way, I was able to use a CurrencyField for the questionnaire like I wanted. However, even with the CurrencyField, participants can still type in any number of decimal places. – Leni Jun 25 '23 at 13:34

0 Answers0