根据之前的用户条目动态填充表单字段

时间:2021-05-04 19:19:33

标签: javascript python jquery wtforms

我有一个使用 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 片段为一个表单字段运行。但是,再次使用函数的参数更新它以对多个字段执行相同的操作会导致代码无法运行。我已经根据 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);
            });
         });

1 个答案:

答案 0 :(得分:0)

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

$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_ 字段变化。

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

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