如何在不刷新页面的情况下在烧瓶中创建链式选择字段? [英] How to create chained selectfield in flask without refreshing the page?

查看:20
本文介绍了如何在不刷新页面的情况下在烧瓶中创建链式选择字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用 wtf 制作地址表,其中包含国家、州、城市等.数据库全部用FK设置.

I am currently working on an address form using wtf, which contains Country, State, City..etc. The database is all set with FK.

class Country(db.Model):
    __tablename__ = 'countries'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    users = db.relationship('User', backref='countries', lazy='dynamic')
class City(db.Model):
    __tablename__ = 'cities'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    countries_id = db.Column(db.Integer, db.ForeignKey('countries.id')) 

现在我正在尝试实现链式选择字段排序效果来优化用户体验.想要的效果是不用离开或刷新页面就可以让selectfield根据之前的selectfield拉取数据.

Now I am trying to achieve a chained selectfield sort effect to optimize user experience. The desired effect is that without leaving or refreshing the page to have the selectfield pull data depending on the previous selectfield.

例如,User在Country中选择Australia,那么State的第二个selectfield应该只包含Australia的州.

For example, User selects Australia in Country, then the second selectfield of State should contain only the states in Australia.

我对此主题进行了一些研究,但无法提出令人满意的解决方案.这是我找到的两种可能但不令人满意的解决方案.

I've done some research on this topic, and couldn't come up with an satisfying solution. Here is the two possible yet unsatifying solution that I find.

1.使用 jQuery 插件,例如链式.但是,此插件需要逐行编码.如果我采用这个解决方案,至少还有 400 多行,这不是很 Pythonic.例如:

1.Use jQuery-plugin e.g. Chained. However, this plugin requires line-by-line coding. If I adopt this solution, there would be at least another 400+ lines, and that's not very pythonic. For example:

<select id="series" name="series">
  <option value="">--</option>
  <option value="series-3" class="bmw">3 series</option>
  <option value="series-5" class="bmw">5 series</option>
  <option value="series-6" class="bmw">6 series</option>
  <option value="a3" class="audi">A3</option>
  <option value="a4" class="audi">A4</option>
  <option value="a5" class="audi">A5</option>
</select>

2.使用Wtf的Select fields with dynamic selection values",这也是不可取的,因为它根据前一个selectfield的默认值只拉取一次数据.例如:如果国家/地区的默认选择字段是澳大利亚,则州选择字段将仅包含澳大利亚境内的州.当您将国家选择字段更改为美国时,州选择字段仍将仅包含澳大利亚境内的州.下面是 wtf 文档中列出的此方法的教程:

2.Use Wtf's "Select fields with dynamic choice values", which is also undesirable as it only pulls the data once depending on the default value of the previous selectfield. For example: If the default selectfield for country is Australia, then the state selectfield would only contain states within Australia. When you change the country selectfield say to America, the state selectfield would still only contains states within Australia. Below, is the tutorial for this method listed in wtf documentation:

class UserDetails(Form):
    group_id = SelectField(u'Group', coerce=int)

def edit_user(request, id):
    user = User.query.get(id)
    form = UserDetails(request.POST, obj=user)
    form.group_id.choices = [(g.id, g.name) for g in Group.query.order_by('name')]

从上面的研究来看,我认为令人满意的解决方案应该介于两者之间,并且肯定应该涉及一些 Javascript 来监视客户端活动,而无需向服务器发送请求.有人对flask框架有满意的解决方案吗?

From the above research, I assume the satisfying solution should be somewhere between the two and it definitely should involve some Javascript to monitor the client side activities without sending request to the server. Has anyone got a satisying solution for the flask framework?

推荐答案

如果您想在客户端上实现动态,那么编写一些 JavaScript 是没有办法的.幸运的是,这不是您估计的 400 多行.此示例不使用 WTForms,但这并不重要.关键部分是将可用选项作为 JSON 发送,并动态更改可用选项.这是一个可运行的单文件 Flask 应用程序,它演示了基本思想.

If you want something dynamic on the client, there's no way around writing some JavaScript. Luckily it's not the 400+ lines you estimate. This example doesn't use WTForms, but that's not really important. The key part is sending the available choices as JSON, and dynamically changing the available options. Here's a single file runnable Flask app that demonstrates the basic idea.

from flask import Flask, render_template_string

app = Flask(__name__)

@app.route('/')
def index():
    systems = {
        'PlayStation': ['Spyro', 'Crash', 'Ico'],
        'N64': ['Mario', 'Superman']
    }

    return render_template_string(template, systems=systems)

template = """

<!doctype html>
<form>
    <select id="system">
        <option></option>
    </select>
    <select id="game"></select>
    <button type="submit">Play</button>
</form>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
    "use strict";

    var systems = {{ systems|tojson }};

    var form = $('form');
    var system = $('select#system');
    var game = $('select#game');

    for (var key in systems) {
        system.append($('<option/>', {'value': key, 'text': key}));
    }

    system.change(function(ev) {
        game.empty();
        game.append($('<option/>'));

        var games = systems[system.val()];

        for (var i in games) {
            game.append($('<option/>', {'value': games[i], 'text': games[i]}));
        }
    });

    form.submit(function(ev) {
        ev.preventDefault();
        alert("playing " + game.val() + " on " + system.val());
    });
</script>

"""

app.run()

这篇关于如何在不刷新页面的情况下在烧瓶中创建链式选择字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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