使用从前一个字段中选择的值填充 WTForms 选择字段 [英] populate WTForms select field using value selected from previous field

查看:32
本文介绍了使用从前一个字段中选择的值填充 WTForms 选择字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新手,尝试按照著名的 Flask 教程构建应用程序,使用 Flask-bootstrap、Flask-wtforms、Jinja 等

New to this, trying to build an app following a well known Flask tutorial, using Flask-bootstrap, Flask-wtforms, Jinja etc

我有一个包含 2 个选择字段和一个按钮的表单.

I have a form with 2 select fields and a button.

class Form(FlaskForm): 
    school_year = SelectField('School year', choices=some_tuples_list)
    category = SelectField('Category', choices=[]) 
    submit = SubmitField('submit')

我只想预先填充第一个字段,并根据前一个字段的选定值填充另一个字段(在客户端?).

I want only the first field to be pre-populated, and the other to get populated (on the client side?) based on the previous field's selected value.

在模板中我尝试类似

{{ form.school_year(**{"onchange":"getCategories()"}) }}

工作正常(前提是我返回元组列表以填充下一个字段,使用正确的 javascript 和路由)但我想要类似以下的内容

which works ok (provided that I return the tuples list to populate the next field, using the proper javascript and route) but I want something like the following

{{ wtf.form_field(form.school_year(**{"onchange":"getCategories()"})) }}

这不起作用(错误:wtforms.widgets.core.HTMLString object' has no attribute 'flags')

which doesn't work (Error: wtforms.widgets.core.HTMLString object' has no attribute 'flags')

所以,我想我的问题真的是:如何在这个 wtf 表单字段上实现 onChange 事件?(这是我必须做的,还是视图函数有办法?)

So, I guess my question really is: how do I implement an onChange event on this wtf form field? (And is this what I have to do, or is there a way from the view function?)

提前致谢.

推荐答案

这里是使用 WTForms 本机功能的此逻辑的示例实现.这里的技巧是,如果您想使用 WTForms 验证,您需要使用每个可能的值实例化表单,然后修改 Javascript 中的可用选项以显示基于其他选择的过滤值.

Here is an example implementation of this logic to work with WTForms native functionality. The trick here, is if you want to use WTForms validation, you need to instantiate the form with every possible value, then modify the available options in Javascript to show the filtered values based on the other select.

在这个例子中,我将使用州和县的概念(我处理大量地理数据,所以这是我构建的一个常见实现).

For this example I'm going to use the concept of States and Counties (I work with a lot of geo data so this is a common implementation I build).

这是我的表单,我为重要元素分配了唯一 ID,以便从 Javascript 访问它们:

Here's my form, I've assigned unique IDs to the important elements to access them from 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 视图实例化和处理表单:

Now, the Flask view to instantiate and process the form:

@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 请求的 Flask 视图:

A Flask view to respond to XHR requests for Counties:

@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.

And, finally, the Javascript to place at the bottom of your Jinja template. I'm assuming because you mentioned Bootstrap, that you are using jQuery. I'm also assuming this is in line javascript so I'm using Jinja to return the correct URL for the endpoint.

<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>

这篇关于使用从前一个字段中选择的值填充 WTForms 选择字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆