Flask WTF forms: can a new field be shown if a user selects a specific choice in SelectMultipleField?

断了今生、忘了曾经 提交于 2021-01-28 19:16:17

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!