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



新的,尝试按照众所周知的烧瓶教程构建应用程序,使用烧瓶bootstrap,Blask-wtforms,Jinja等

我有一个带有2个选择字段和一个按钮的表单。

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!')

现在,烧瓶视图实例化和处理表格:

@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();
});

最新更新