根据先前的用户条目动态填充表单字段
Dynamically populate a form field based on a previous user entry
我有一个使用 Flask 和 wtforms 的应用程序,部分功能是为前两个字段获取用户输入并填充 SelectMultipleField 类型的其余表单字段(我将参考将这些作为 select 字段),并根据前两个字段从数据库中进行选择(我将这些称为输入字段)。
我现在的问题是让 select 字段动态填充。我找到了一个解决方案 ,这似乎正是我所需要的。它将 select 字段实例化为所有可能的选择,然后当它在输入字段中检测到 JQuery“onchange”事件时,根据用户输入将 select 字段过滤为选择输入字段。例如,用户在表单中输入特定公司,select 字段仅填充该公司的“位置”。
但是,在针对我的问题采用此解决方案时,我无法获得 运行 的代码,而且我进行了广泛的研究,但无法解决此问题。我是 JQuery 和 Stack Overflow 的新手,所以非常感谢任何帮助。下面是我的代码。请注意,我只关注其中一个输入字段并动态填充 select 字段之一,直到我让它工作。 Test_table 是输入字段,test_join_key 是 select 字段。
这是包含相关字段的表格-
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 视图以实例化所有 select 字段 -
@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 视图根据输入字段的用户输入获取 select 字段的选择 -
@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 检测输入字段中的输入和 select 字段的过滤器选择(注入到 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 代码段获取到运行。但是,更新它以使用函数的参数对多个字段执行相同的操作再次导致代码不是 运行ning。我已根据 W3 学校的教程以及其他 Stack Overflow 问题检查以确保我的语法正确,但仍然无法将其获取到 运行。这是更新后的 Jquery,用于检测输入字段中的输入和 select 字段的过滤器选择 -
<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);
});
});
您的代码中存在一些语法错误。
$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_ 字段 prod_table
更改时。
所以这段代码应该这样做:
$(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));
});
});
我有一个使用 Flask 和 wtforms 的应用程序,部分功能是为前两个字段获取用户输入并填充 SelectMultipleField 类型的其余表单字段(我将参考将这些作为 select 字段),并根据前两个字段从数据库中进行选择(我将这些称为输入字段)。
我现在的问题是让 select 字段动态填充。我找到了一个解决方案
但是,在针对我的问题采用此解决方案时,我无法获得 运行 的代码,而且我进行了广泛的研究,但无法解决此问题。我是 JQuery 和 Stack Overflow 的新手,所以非常感谢任何帮助。下面是我的代码。请注意,我只关注其中一个输入字段并动态填充 select 字段之一,直到我让它工作。 Test_table 是输入字段,test_join_key 是 select 字段。
这是包含相关字段的表格-
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 视图以实例化所有 select 字段 -
@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 视图根据输入字段的用户输入获取 select 字段的选择 -
@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 检测输入字段中的输入和 select 字段的过滤器选择(注入到 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 代码段获取到运行。但是,更新它以使用函数的参数对多个字段执行相同的操作再次导致代码不是 运行ning。我已根据 W3 学校的教程以及其他 Stack Overflow 问题检查以确保我的语法正确,但仍然无法将其获取到 运行。这是更新后的 Jquery,用于检测输入字段中的输入和 select 字段的过滤器选择 -
<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);
});
});
您的代码中存在一些语法错误。
$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_ 字段 prod_table
更改时。
所以这段代码应该这样做:
$(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));
});
});