Flask 使用从上一个字段中选择的值填充WTForms select字段

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

新的,尝试建立一个应用程序后,一个众所周知的烧瓶教程,使用烧瓶引导,烧瓶wtforms,Jinja等

我有一个表单,有两个选择字段和一个按钮

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方法。