【问题标题】:Dynamically populate a form field based on a previous user entry根据之前的用户输入动态填充表单域
【发布时间】:2021-07-27 03:51:51
【问题描述】:

我有一个使用 Flask 和 wtforms 的应用程序,部分功能是获取前两个字段的用户输入并填充 SelectMultipleField 类型的其余表单字段(我将参考这些作为选择字段),并根据前两个字段从数据库中进行选择(我将这些字段称为输入字段)。

我现在的问题是让选择字段动态填充。我找到了一个解决方案here,这似乎正是我所需要的。它将选择字段实例化为所有可能的选择,然后当它在输入字段中检测到 JQuery“onchange”事件时,根据输入字段的用户输入将选择字段过滤为选择。例如,用户将特定公司输入到表单中,并且选择字段仅填充该公司的“位置”。

但是,在使该解决方案适应我的问题时,我无法让代码运行,并且我进行了广泛的研究,但无法解决这个问题。我是 JQuery 和 Stack Overflow 的新手,因此我们将不胜感激。下面是我的代码。请注意,我只关注其中一个输入字段并仅动态填充其中一个选择字段,直到我让它工作为止。 test_table 是入口字段,test_join_key 是选择字段。

这是包含相关字段的表单-

class QaForm(FlaskForm):
test_table_in = StringField('Test Table', validators=[DataRequired()], id= 'test_table')
test_join_key = SelectMultipleField("Select Test Fields to Join on", choices=[], coerce=str, id = 'select_test_join_key')

用于实例化所有选择字段的 Flask 视图 -

@app.route('/', methods = ['GET', 'POST'])
@app.route('/home', methods = ['GET', 'POST'])
def home():
    form = QaForm()

    fields_query = f"""select column_name AS Fields from information_schema.columns group by 1;"""
    conn.execute(fields_query)
    result = conn.fetchall()
    select_choices = [(column, column) for column in result]

    form.test_join_key.choices = select_choices

Flask 视图可根据输入字段的用户输入获取选择字段的选项 -

@app.route('/_get_fields/<table>')
def _get_fields(table):
    table = request.args.get(table, type=str)
    fields_query = f"""select column_name AS Fields from information_schema.columns WHERE table_name = '{table}' group by 1;"""
    conn.execute(fields_query)
    result = conn.fetchall()
    select_choices = [(column, column) for column in result]
return jsonify(select_choices)

JQuery 检测输入字段中的输入并过滤选择字段的选择(在 HTML 文件中注入)-

<script charset="utf-8" type="text/javascript">
         $function() {
            var dropdown = {
                test_table: $('#test_table')
                test_join_key: $('#select_test_join_key')
            }
            updateFields();

            function updateFields() {
                var send = {
                    test_table: dropdown.test_table.val()
                };
                dropdown.test_join_key.attr('disabled', 'disabled');
                dropdown.test_join_key.empty();
                $.getJSON("{{url_for('_get_fields') }}", send, function(data) {
                    data.forEach(function(item) {
                        dropdown.test_join_key.append(
                            $('<option>', {
                                value: item[0],
                                text: item[1]
                            })
                        );
                    });
                    dropdown.test_join_key.removeAttr('disabled');
                });
            }
            dropdown.test_table.on('change', function() {
                updateFields();
            });
         });
     </script>

编辑:使用@Ibsn 建议,我能够让 JQuery sn-p 为一个表单字段运行。但是,再次使用函数的参数更新它以对多个字段执行相同的操作会导致代码无法运行。我已经根据 W3 学校的教程以及其他 Stack Overflow 问题检查以确保我的语法正确,但仍然无法让它运行。这是更新的 Jquery,用于检测输入字段中的输入并过滤选择字段的选项 -

<script charset="utf-8" type="text/javascript">
         $(function() {
            var tables = {
                test_table: $('#test_table'),
                prod_table: $('#prod_table')
            };

            var fields = {
                test_join_key: $('#select_test_join_key'),
                prod_join_key: $('#select_prod_join_key'),
                test_dimensions: $('#select_test_dimensions'),
                prod_dimensions: $('#select_prod_dimensions'),
                test_measures: $('#select_test_measures'),
                prod_measures: $('#select_prod_measures')
            };
            updateFields(table, field);

            function updateFields(table, field) {
                var send = {
                    table: tables.table.val()
                };
                fields.field.attr('disabled', 'disabled');
                fields.field.empty();
                $.getJSON("{{url_for('_get_fields') }}", send, function(data) {
                    data.forEach(function(item) {
                        fields.field.append(
                            $('<option>', {
                                value: item[1],
                                text: item[0]
                            })
                        );
                    });
                    fields.field.removeAttr('disabled');
                });
            }
            tables.test_table.on('change', function() {
                updateFields(tables.test_table, fields.test_join_key);
                updateFields(tables.test_table, fields.test_dimensions);
                updateFields(tables.test_table, fields.test_measures);
            });
            tables.prod_table.on('change', function() {
                updateFields(tables.prod_table, fields.prod_join_key);
                updateFields(tables.prod_table, fields.prod_dimensions);
                updateFields(tables.prod_table, fields.prod_measures);
            });
         });

【问题讨论】:

    标签: javascript python jquery wtforms


    【解决方案1】:

    您的代码中有几个语法错误。

    $function() {} 应该是 $(function(){})。而且您缺少var dropdown = {}上的属性之间的逗号

    这是更新版本:

    <script charset="utf-8" type="text/javascript">
         $(function(){
             var dropdown = {
                 test_table: $('#test_table'),
                 test_join_key: $('#select_test_join_key')
             }
             updateFields();
        
             function updateFields() {
                 var send = {
                    test_table: dropdown.test_table.val()
                 };
                 dropdown.test_join_key.attr('disabled', 'disabled');
                 dropdown.test_join_key.empty();
                 $.getJSON("{{url_for('_get_fields') }}", send, function(data) {
                      data.forEach(function(item) {
                         dropdown.test_join_key.append(
                             $('<option>', {
                                 value: item[0],
                                 text: item[1]
                              })
                          );
                      });
                      dropdown.test_join_key.removeAttr('disabled');
                 });
             }
             dropdown.test_table.on('change', function() {
                 updateFields();
             });
       });
    

    OP 用新要求更新了问题

    如果我理解正确,您将尝试在 test_table 更改时更新所有 test_ 字段,并在 prod_table 更改时更新所有 prod_ 字段。 p>

    所以这段代码应该这样做:

    $(function () {
        var tables = {
            test_table: $('#test_table'),
            prod_table: $('#prod_table')
        };
    
        // I'm organizing fields in two arrays, test and prod, for simplyfing iterate over each group
        var fields = {
            test: [$('#select_test_join_key'), $('#select_test_dimensions'), $('#select_test_measures')],
            prod: [$('#select_prod_join_key'), $('#select_prod_dimensions'), $('#select_prod_measures')]
        };
    
        // This is for updating fields the first time
        fields.test.forEach(item => updateFields(tables.test_table, item));
        fields.prod.forEach(item => updateFields(tables.prod_table, item));
    
        function updateFields(table, field) {
            var send = {
                table: table.val()
            };
            field.attr('disabled', 'disabled');
            field.empty();
            $.getJSON("{{url_for('_get_fields') }}", send, function (data) {
                data.forEach(function (item) {
                    field.append(
                        $('<option>', {
                            value: item[0],
                            text: item[1]
                        })
                    );
                });
                field.removeAttr('disabled');
            });
        }
    
        // Test fields and prod fields are two arrays now, so I can simply iterate through them
        tables.test_table.on('change', function () {
            fields.test.forEach(item => updateFields(tables.test_table, item));
        });
        tables.prod_table.on('change', function () {
            fields.prod.forEach(item => updateFields(tables.prod_table, item));
        });
    });
    

    【讨论】:

    • @Ibsn 非常感谢!它实际上让我的代码运行。但是,当我更新 JQuery 位以处理多个字段而不是一个字段时,它再次失败。我已将函数更新为具有参数,然后将要更新的字段作为参数传递给函数。我已经用这个新代码编辑了问题。有什么想法吗?
    • 我不完全清楚您的新要求是什么。 tablesfields 如何相互关联?我强烈建议你发布一个关于这个的新问题,可能是一个简单的堆栈闪电战。
    • 无论如何,你的语法又不正确了。您在updateFields() 上定义了两个参数:tablefield。但是你根本没有在函数体中使用它们。第一次这样调用函数:updateFields(table, filed)。您试图传递给函数的这两个参数在哪里定义?
    • @Ibsn,是的,这就是我想要做的。非常感谢!后续问题 - 由于用户尚未在表单中输入任何内容,因此第一次调用 updateFields() 是否会更新没有任何内容的字段?
    • 它将调用$.getJSON(),将send参数作为空字符串传递。然后它将使用任何响应更新字段。由于send 参数作为查询字符串附加到 URL,结果取决于您的 API 如何处理空查询字符串的情况。
    猜你喜欢
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 2014-07-12
    相关资源
    最近更新 更多