[英]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 片段為一個表單字段運行。 但是,使用 function 的參數更新它以對多個字段執行相同的操作會再次導致代碼無法運行。 我已經根據 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用新要求更新了問題
如果我理解正確,您將嘗試在prod_table
更改時更新所有test_字段,並在test_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));
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.