Flask 使用从上一个字段中选择的值填充WTForms select字段
新的,尝试建立一个应用程序后,一个众所周知的烧瓶教程,使用烧瓶引导,烧瓶wtforms,Jinja等 我有一个表单,有两个选择字段和一个按钮Flask 使用从上一个字段中选择的值填充WTForms select字段,flask,flask-wtforms,flask-bootstrap,Flask,Flask Wtforms,Flask Bootstrap,新的,尝试建立一个应用程序后,一个众所周知的烧瓶教程,使用烧瓶引导,烧瓶wtforms,Jinja等 我有一个表单,有两个选择字段和一个按钮 class Form(FlaskForm): school_year = SelectField('School year', choices=some_tuples_list) category = SelectField('Category', choices=[]) submit = SubmitField('submit
class Form(FlaskForm):
school_year = SelectField('School year', choices=some_tuples_list)
category = SelectField('Category', choices=[])
submit = SubmitField('submit')
我只想预填充第一个字段,而在客户端填充另一个字段?基于上一个字段的选定值
在模板中,我尝试了以下内容
{{ form.school_year(**{"onchange":"getCategories()"}) }}
如果我返回元组列表来填充下一个字段,使用适当的javascript和路由,那么它可以正常工作,但我需要如下内容
{{ wtf.form_field(form.school_year(**{"onchange":"getCategories()"})) }}
这不起作用错误:wtforms.widgets.core.HTMLString对象“”没有属性“flags”
所以,我想我的问题是:如何在这个wtf表单字段上实现onChange事件?这就是我必须要做的,还是从视图函数中有方法
提前感谢。这里是使用WTForms本机功能实现此逻辑的示例。这里的诀窍是,如果要使用WTForms验证,则需要使用每个可能的值实例化表单,然后修改Javascript中的可用选项,以显示基于其他选择的过滤值 对于这个例子,我将使用州和县的概念,我处理大量的地理数据,所以这是我构建的一个通用实现 这是我的表单,我为重要元素分配了唯一的ID,以便从Javascript访问它们:
class PickCounty(Form):
form_name = HiddenField('Form Name')
state = SelectField('State:', validators=[DataRequired()], id='select_state')
county = SelectField('County:', validators=[DataRequired()], id='select_county')
submit = SubmitField('Select County!')
现在,使用Flask视图实例化和处理表单:
@app.route('/pick_county/', methods=['GET', 'POST'])
def pick_county():
form = PickCounty(form_name='PickCounty')
form.state.choices = [(row.ID, row.Name) for row in State.query.all()]
form.county.choices = [(row.ID, row.Name) for row in County.query.all()]
if request.method == 'GET':
return render_template('pick_county.html', form=form)
if form.validate_on_submit() and request.form['form_name'] == 'PickCounty':
# code to process form
flash('state: %s, county: %s' % (form.state.data, form.county.data))
return redirect(url_for('pick_county'))
用于响应县XHR请求的烧瓶视图:
@app.route('/_get_counties/')
def _get_counties():
state = request.args.get('state', '01', type=str)
counties = [(row.ID, row.Name) for row in County.query.filter_by(state=state).all()]
return jsonify(counties)
最后,要放在Jinja模板底部的Javascript。因为您提到了Bootstrap,所以我假设您正在使用jQuery。我还假设这是一行javascript,所以我使用Jinja返回端点的正确URL
<script charset="utf-8" type="text/javascript">
$(function() {
// jQuery selection for the 2 select boxes
var dropdown = {
state: $('#select_state'),
county: $('#select_county')
};
// call to update on load
updateCounties();
// function to call XHR and update county dropdown
function updateCounties() {
var send = {
state: dropdown.state.val()
};
dropdown.county.attr('disabled', 'disabled');
dropdown.county.empty();
$.getJSON("{{ url_for('_get_counties') }}", send, function(data) {
data.forEach(function(item) {
dropdown.county.append(
$('<option>', {
value: item[0],
text: item[1]
})
);
});
dropdown.county.removeAttr('disabled');
});
}
// event listener to state dropdown change
dropdown.state.on('change', function() {
updateCounties();
});
});
</script>
PJ Santoro的回答很好。已调用加载时更新,但事件侦听器起初不适用于我。事实证明,我没有用“状态”替换我自己的字段ID,因为我认为它是一个引用字段状态的关键字!哦!因此,在寻找其他选择时,我发现这也很有效,可能对其他人有用:
// event listener to state dropdown change
$('#state').change(function() {
updateCounties();
});
阿比格珀森的回答最终让我明白了这一点 唯一需要补充的是,他们网站上当前的引导代码片段使用了一个精简版的JQuery,这会让我在屏幕上尖叫几个小时。slim版本不包含abigperson在其代码中使用的一些函数 在jQuery的完整版本中滑动可以立即修复我的问题
进一步的阅读表明,Bootstrap在jQuery的完整版本中仍然可以正常工作 我用Javascript来管理它。有兴趣看看是否有人有不同的解决方案。请记住,如果您计划在视图函数中使用form.validate\u on\u submit,则“选择选项”列表必须加载所有可能的值,否则WTForms验证将失败。@PJ Santoro Yes,但是我如何在模板的wtf字段中调用Javascript呢?我将在下面分享一个我如何实现它的示例。似乎可以完成这项工作,并且为我提供了一个非常实用的jQuery介绍。非常感谢。+1用所有可能的值实例化选择。我花了很多时间试图弄明白为什么表单在用Javascript更新选项后无法验证。谢谢我正在使用这个例子,我得到了错误NameError:name'State'不是defined@bms9nmhState和County是别处定义的SQLAlchemy模型的表示形式,但是您可以用您正在使用的任何分层数据源替换它们。使用生成器表达式,我正在从SQLAlchemy生成元组列表。。['01'、'Alabama'、'02'、'Alaska'…]将在渲染视图中填充wtforms,并为这些字段选择选项。在XHR端点中,它将jsonify化为javascript中的嵌套列表,例如:[[01',Alabama'],[02',Alaska']…]是的,这是绑定到更改事件的JQuery方法,上面是“pure”JS方法。