#1 by Mike_Zhiren_Wu
Dear Chirs and all, I'm currently struggling with revising the content of the error message. I have several raw html formfields to be checked and it seems that both error_message() and {field_name}_error_message() does not work for raw html formfields... I just wonder am I doing anything wrong here, or I should try other methods? Best, Mike Zhiren Wu
#2 by BonnEconLab
Since you don’t provide any code — neither of your __init__.py nor your HTML template — it is hard to diagnose your issue. Have you included {{ formfield_errors 'field_name' }} in your HTML template? See https://otree.readthedocs.io/en/latest/forms.html#customizing-a-field-s-appearance. The following works for me: In the __init__.py, I include class Player(BasePlayer): code_to_continue = models.StringField() class Instructions(Page): form_model = 'player' form_fields = ['code_to_continue'] @staticmethod def error_message(player, values): if values['code_to_continue'] != "4711": return dict( code_to_continue = 'Code incorrect. Please enter the code exactly as given to you by the experimenter.' ) @staticmethod def is_displayed(player): return player.round_number == 1 And in Instructions.html, I include: <div class="mb-3 _formfield"> <label class="col-form-label" for="id_code_to_continue">In order to continue, please enter the code given to you by the experimenter.</label> <div class="controls"> <input type="text" class="form-control" id="id_code_to_continue" name="code_to_continue" required value=""> {{ formfield_errors 'code_to_continue' }} </div> </div>
#3 by Mike_Zhiren_Wu
Many thanks for sharing your sample code! I made changes accordingly and now I have pop out messages in the required field instead mentioning "please select an item in the list". Now it's much better, while I still wonder how to revise the pop out messages since the content in the error message is not working. Here's my code: class Player(BasePlayer): Message_StageIII_E_R1_part1 = models.StringField(initial="None") Message_StageIII_E_R1_part2 = models.StringField(initial="None") class Results_StageIII_easy_R1(Page): form_model = 'player' form_fields = ['Message_StageIII_E_R1_part1', 'Message_StageIII_E_R1_part2'] @staticmethod def error_message(player, values): if values['Message_StageIII_E_R1_part1'] == "None": return dict( Message_StageIII_E_R1_part1='Please fill in the required fields' ) if values['Message_StageIII_E_R1_part2'] == "None": return dict( Message_StageIII_E_R1_part2='Please fill in the required fields' ) And in my html file I include: <body onload="test()"> <select id="Message_StageIII_E_R1_part1" name="Message_StageIII_E_R1_part1" style="font-size: 16px; border-radius: 5px; border: 1.75px solid #ccc; height:35px; width:600px" required value=""> <option value="{{ Message1a }}">{{ Message1a }}</option> <option value="{{ Message1b }}">{{ Message1b }}</option> <option value="{{ Message1b }}">{{ Message1c }}</option> </select> <p></p> <select id="Message_StageIII_E_R1_part2" name="Message_StageIII_E_R1_part2" style="font-size: 16px; border-radius: 5px; border: 1.75px solid #ccc; height:35px; width:450px" required value=""> <option value="{{ Message2a }}">{{ Message2a }}</option> <option value="{{ Message2b }}">{{ Message2b }}</option> <option value="{{ Message2c }}">{{ Message2c }}</option> </select> <script> function test() { var x1 = document.getElementById("Message_StageIII_E_R1_part1"); var x2 = document.getElementById("Message_StageIII_E_R1_part2"); x1.selectedIndex = -1; x2.selectedIndex = -1; } </script> {{ formfield_errors 'Message_StageIII_E_R1_part1' }} {{ formfield_errors 'Message_StageIII_E_R1_part2' }} </body>
#4 by BonnEconLab
Your HTML template includes an error: It includes {{ Message1b } twice: <option value="{{ Message1b }}">{{ Message1b }}</option> <option value="{{ Message1b }}">{{ Message1c }}</option> should be <option value="{{ Message1b }}">{{ Message1b }}</option> <option value="{{ Message1c }}">{{ Message1c }}</option>
#5 by BonnEconLab
If I understand you correctly, the “pop-out message” is the message produced by your browser in response to leaving a required field empty. It appears because you include the “required” attribute in <select>. Since the message is produced by your browser, you cannot influence it — apart from its language — via oTree.
#6 by BonnEconLab
I think the following does what you desire: In the __init__.py file, include class Results_StageIII_easy_R1(Page): form_model = 'player' form_fields = ['Message_StageIII_E_R1_part1', 'Message_StageIII_E_R1_part2'] @staticmethod def error_message(player, values): if values['Message_StageIII_E_R1_part1'] == "-1": Message_StageIII_E_R1_part1 = 'Please select the first message that you would like to send!' else: Message_StageIII_E_R1_part1 = '' if values['Message_StageIII_E_R1_part2'] == "-1": Message_StageIII_E_R1_part2 = 'Please select the second message that you would like to send!' else: Message_StageIII_E_R1_part2 = '' if values['Message_StageIII_E_R1_part1'] == "-1" or values['Message_StageIII_E_R1_part2'] == "-1": return dict( Message_StageIII_E_R1_part1 = Message_StageIII_E_R1_part1, Message_StageIII_E_R1_part2 = Message_StageIII_E_R1_part2, ) @staticmethod def vars_for_template(player): return dict( Message1a = "Message1a", Message1b = "Message1b", Message1c = "Message1c", Message2a = "Message2a", Message2b = "Message2b", Message2c = "Message2c", ) In the HTML template, include <p> <select id="Message_StageIII_E_R1_part1" name="Message_StageIII_E_R1_part1" class="form-select" style="width: 500px;"> <option value="-1">[Select the first message to be sent.]</option> <option value="{{ Message1a }}">{{ Message1a }}</option> <option value="{{ Message1b }}">{{ Message1b }}</option> <option value="{{ Message1b }}">{{ Message1c }}</option> </select> {{ formfield_errors 'Message_StageIII_E_R1_part1' }} </p> <p> <select id="Message_StageIII_E_R1_part2" name="Message_StageIII_E_R1_part2" class="form-select" style="width: 500px;"> <option value="-1">[Select the second message to be sent.]</option> <option value="{{ Message2a }}">{{ Message2a }}</option> <option value="{{ Message2b }}">{{ Message2b }}</option> <option value="{{ Message2c }}">{{ Message2c }}</option> </select> {{ formfield_errors 'Message_StageIII_E_R1_part2' }} </p> This, however, has the (severe) drawback that if you forget to select one of the two messages to be sent, once the error message appears, also the selection of the second message is ignored, and you have to make a selection for *both* messages again. This is confusing for the participant. Thus, as a participant, I would actually prefer to see the browser’s message that I missed to fill in a required field because this prevents the form from being submitted and the values from being sent to oTree in the first place.
#7 by Mike_Zhiren_Wu
Hi, many thanks for your correction and suggested solutions! I made up my mind to follow the code in #3 by using the default reminder message from the browser, since there will be pop out messages once you miss one of the boxes, which can be more friendly to participants, especially when I am targeting an online experiment on Prolific. Thanks again for your great help!