如何根据 Flask WTForm 中 select 字段的先前 selection 动态生成不同的字段
How to dynamically generate different fields based on previous selection of select field in Flask WTForm
我想实现一个表单,根据之前在下拉 select 字段中输入的值 select 生成不同的文本区域字段。上下文正在创建不同类别的项目:例如,如果用户 select 的“教育”,则实时生成的下一个字段可能是“quarter/semester?”的 select 字段,并且“描述您的主题”的文本区域字段。我知道完成这样的功能需要 javascript/jquery 但我不知道从哪里开始。我也不确定将其与我的模型和数据库相关联的最佳方式。
在我的 HTML 模板中,我实现了 if 语句,但这些当然不起作用。
我的表单 class 看起来像这样:
class ProjectForm(FlaskForm):
"""Create a new project, on /index"""
categories = ['Education','Software development', ...]
langs = ['Python', 'Java', ...]
name = TextAreaField('Give your project a name', validators=[
DataRequired(), Length(min=1, max=60)])
category = SelectField('Category', choices=categories, default=1)
#Education case
academic_pace = SelectField('Quarter or semester?', choices=['quarter', 'semester'],
default=1)
subject = TextAreaField('Describe your subject matter', validators=[
DataRequired(), Length(min=10, max=100)])
#Software development case
software_language = SelectField('What programming language??', choices=langs, default=1)
submit = SubmitField('Submit')
这样的路线:
from app.models import User, Project
from app.forms import LoginForm, ProjectForm ...
@app.route('/', methods=['GET', 'POST'])
@login_required
def index():
form = ProjectForm()
if form.validate_on_submit():
project = Project(name = form.name.data, category = form.category.data,
academic_pace = form.academic_pace.data,
subject = form.subject.data,
software_language = form.software_language.data,
creator=current_user)
db.session.add(project)
db.session.commit()
flash('Your project is now live!')
return redirect(url_for('index'))
return render_template('index.html', title='Home', form = form)
index.html:
...
{{ form.category.label }}<br>
{{ form.category(cols=32, rows=4) }}<br>
{% for error in form.category.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
{% if form.category == "Education" %}
{{ form.academic_pace.label }}<br>
{{ form.academic_pace(cols=32, rows=4) }}<br>
{% for error in form.academic_pace.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
{{ form.subject.label }}<br>
{{ form.subject(cols=32, rows=4) }}<br>
{% for error in form.subject.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
{% endif %}
...
我想我知道如何使用 jquery 来做到这一点。本质上,对于每个类别的独特形式,我将它们包装在 div 中。这些div先是隐藏的,跟style="display:none;"
。然后我使用 jquery 来识别从 SelectField 中选择了哪些选项,并相应地显示或隐藏其他表单 div。下面是一个案例的javascript。
$(document).ready(function() {
$("#category").change(function () {
var val = $(this).val();
if (val == "learning") {
$("#learning").show();
}
else {
$("#learning").hide();
}
});
});
我想实现一个表单,根据之前在下拉 select 字段中输入的值 select 生成不同的文本区域字段。上下文正在创建不同类别的项目:例如,如果用户 select 的“教育”,则实时生成的下一个字段可能是“quarter/semester?”的 select 字段,并且“描述您的主题”的文本区域字段。我知道完成这样的功能需要 javascript/jquery 但我不知道从哪里开始。我也不确定将其与我的模型和数据库相关联的最佳方式。
在我的 HTML 模板中,我实现了 if 语句,但这些当然不起作用。
我的表单 class 看起来像这样:
class ProjectForm(FlaskForm):
"""Create a new project, on /index"""
categories = ['Education','Software development', ...]
langs = ['Python', 'Java', ...]
name = TextAreaField('Give your project a name', validators=[
DataRequired(), Length(min=1, max=60)])
category = SelectField('Category', choices=categories, default=1)
#Education case
academic_pace = SelectField('Quarter or semester?', choices=['quarter', 'semester'],
default=1)
subject = TextAreaField('Describe your subject matter', validators=[
DataRequired(), Length(min=10, max=100)])
#Software development case
software_language = SelectField('What programming language??', choices=langs, default=1)
submit = SubmitField('Submit')
这样的路线:
from app.models import User, Project
from app.forms import LoginForm, ProjectForm ...
@app.route('/', methods=['GET', 'POST'])
@login_required
def index():
form = ProjectForm()
if form.validate_on_submit():
project = Project(name = form.name.data, category = form.category.data,
academic_pace = form.academic_pace.data,
subject = form.subject.data,
software_language = form.software_language.data,
creator=current_user)
db.session.add(project)
db.session.commit()
flash('Your project is now live!')
return redirect(url_for('index'))
return render_template('index.html', title='Home', form = form)
index.html:
...
{{ form.category.label }}<br>
{{ form.category(cols=32, rows=4) }}<br>
{% for error in form.category.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
{% if form.category == "Education" %}
{{ form.academic_pace.label }}<br>
{{ form.academic_pace(cols=32, rows=4) }}<br>
{% for error in form.academic_pace.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
{{ form.subject.label }}<br>
{{ form.subject(cols=32, rows=4) }}<br>
{% for error in form.subject.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
{% endif %}
...
我想我知道如何使用 jquery 来做到这一点。本质上,对于每个类别的独特形式,我将它们包装在 div 中。这些div先是隐藏的,跟style="display:none;"
。然后我使用 jquery 来识别从 SelectField 中选择了哪些选项,并相应地显示或隐藏其他表单 div。下面是一个案例的javascript。
$(document).ready(function() {
$("#category").change(function () {
var val = $(this).val();
if (val == "learning") {
$("#learning").show();
}
else {
$("#learning").hide();
}
});
});