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

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

问题描述

我目前正在使用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提取数据取决于先前的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.

例如,用户在国家/地区"中选择澳大利亚",那么第二个州"选择字段应仅包含澳大利亚的州.

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的具有动态选择值的选择字段",这也是不可取的,因为它仅根据以前选择字段的默认值提取一次数据.例如:如果国家/地区的默认选择字段是澳大利亚,则州选择字段将仅包含澳大利亚内的州.当您将国家/地区选择字段更改为美国"时,州/地区选择字段仍将仅包含澳大利亚内的州.以下是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')]

从上面的研究中,我认为令人满意的解决方案应该介于两者之间,并且肯定应该包含一些Java脚本来监视客户端活动,而不向服务器发送请求.有没有人对烧瓶框架有满意的解决方案?

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

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

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