I have a SelectField
in a form made with Flask and WTFforms.
The SelectField
is created with choices in a dictionary, {label:list}
.
The problem is: because in some of the lists within this dictionary there are identical strings, I need a way to access the label to which the user's choice belongs to.
The following is paired down version within the views.py of my flask app, and doesn't include some things necessary for functionality.
from userClass import UserForm
@ bp.route('/', methods['GET', 'POST'])
def index():
# initializing the form
form1 = UserForm()
# if selectProfile clicked
if form1.selectProfile.data and form1.validate():
data = form1.displayUserAge.data
return data
The following is from my form.py.
userAge = {"Male": ["19-30y", "31-50y"], "Female": ["19-30y", "31-50y"]}
class UserForm(FlaskForm):
displayUserAge = SelectField(u"Age", choices = userAge)
And here is the relevant section within the index.html using Jinjia:
{{ form1.hidden_tag() }}
{{ form1.displayUserAge.label }}
{{ form1.displayUserAge }}
{{ form1.selectProfile }}
Using form1.displayUserAge.data
returns (for example) "19-30y", but does not indicate whether the user chooses Male or Female.
Using form1.displayUserAge.choices
returns the all the choices but obviously does not indicate what the user chose.
One hack could be to make the choices more detailed and make a list of choices rather than a dictionary, i.e. ["Male 19-30y", "Male 31-50y", "Female 19-30y", "Female 31-50y"]. But this cluttered the dropdown menu.
In order to create a structure within the select field, <optgroup>
elements are used whose labels cannot be accessed via the form object.
It is possible to use two arguments for the embedded <option>
elements, the first of which sets the value attribute and the second appears as text. To achieve this, it is necessary to assign lists of tuples within the dict. The gender can then be defined in the first value separated from the age by a separator.
class UserForm(FlaskForm):
age = SelectField(
'Age',
choices={
'': [('', 'Please select your age')],
'Female': [('f_19-30y', '19-30y'), ('f_31-50y', '31-50y')],
'Male': [('m_19-30y', '19-30y'), ('m_31-50y', '31-50y')],
},
validators=[DataRequired()]
)
@app.route('/', methods=['GET', 'POST'])
def index():
form = UserForm(request.form)
if form.validate_on_submit():
gender, age = form.age.data.split('_', 1)
print(gender, ' - ', age)
return render_template('index.html', **locals())