问题
I just started using Flask WTF forms. I can do everything that I need with them except I can't seem to figure out one thing. I have a multiple choice field presenting various options to the user, and if the user selects "other", I want them to describe what they mean. Like this:
impact = wtforms.SelectMultipleField('What is the expected impact?',
choices=[('Sales', 'Sales'),
('Lift', 'Lift'),
('Other', 'Other')]
I don't know if it's even possible when it's not an independent field with its own ID but just a member within an array. Could you please help?
EDIT
here's what I tried following the suggestion below - it didn't work in the sense that selecting or unselecting "Other" makes no difference :
app.py:
app.route('/', methods=['GET', 'POST'])
def home():
form = MyForm()
other_enable = False
if form.validate_on_submit():
name = form.name.data
email = form.email.data
impact1 = form.impact.data
impact = ''.join(str(e) for e in impact1)
if ("Other" in impact):
other_enable = True
impact_other = form.impact_other.data
return redirect(url_for('home'))
return(render_template('home.html', form=form, other_enable=other_enable))
and templates/home.html contains
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
<center>
<div id="someid" onchange='myFunction(other_enable)'>{{ wtf.quick_form(form) }}</div>
</center>
{% endblock %}
<script>
function myFunction(other_enable) {
var theother = document.getElementById("otherField");
if (other_enable == true){
theother.style.display = "block";
} else {
theother.style.display = "none";
}
}
</script>
回答1:
You have to add another field in your form like TextField()
and make it validator.Optional()
.
Then with simple javascript and onchange
event you can display:none
this field by default and if user select Other
show it.
At the end if you want force user to "describe what they mean" you could add in YourForm class this method :
def validate(self):
""" Add custom validators after default validate
"""
success = super(YourFormClass, self).validate()
if 'Other' in self.impact.data and len(self.impact_other.data) < 1:
success = False
self.impact.errors.append(gettext('Please fill impact_other field if you had selected "Other"'))
return success
(assuming other field you created is named impact_other
)
EDIT : I modified slightly my validate() function for working with SelectMultilpleField instead of SelectField
Next, you don't have to pass other_enable
variable to your template, by default if nothing is selected you should hide otherField
, so you need to run your js not only onchange but also after page loaded.
You just have to check into your js function if 'Other' is selected in your field impact
, if yes then show your field. You can look this question for more help at detecting selected values in JS : here
Additionally you have to do form = MyForm(request.form)
to save user input if form validate fail.
来源:https://stackoverflow.com/questions/50511324/flask-wtf-forms-can-a-new-field-be-shown-if-a-user-selects-a-specific-choice-in