如何在 flask-wtf wtforms 中组合不同的字段类型
How to combine different field types in flask-wtf wtforms
我正在使用 flask-wtf 表单构建表单。我有一个字段,用户可以在其中 select 多个选项。如果他们想要的选择不在我的列表中。我想允许用户 select“其他”并通过文本字段指定他们的选项。
我没有找到在 wtforms 中执行此操作的方法。我到处搜索,似乎无法在任何地方找到答案。我正在做的事情绝不是一个独特的场景,而且在我的想象中会很常见。所以我想我可能 thinking/going 错了。
question1_options = [('rice','rice'),('chips','chips'),('tuna','tuna'), ('other', 'other')]
question2_options = [('yes', 'yes'),('no', 'no')]
class MyForm(FlaskForm):
q1 = SelectMultipleField('favourite food?', choices=question1_options)
q2 = RadioField('do you like football', choices=question2_options)
我想达到的目标:
将 SelectMultipleField 与 StringField 组合在一起,以便在列表中没有合适的选项时使用。用户可以 select 其他并输入他们想要的内容
我找不到合并两个字段的方法。
我认为应该是两个分开的字段始终可见
q1_options = [('rice','rice'),('chips','chips'),('tuna','tuna')] #, ('other', 'other')]
class MyForm(FlaskForm):
q1 = SelectMultipleField('Favourite food?', choices=q1_options)
q1_other = StringField('Other favourite food?')
或者它应该使用 JavaScript
来显示 StringField
当你 select other
.
我尝试创建最少的工作代码。
因为它使用 multiple select
所以它需要更复杂的 JavaScript
代码。
from flask import Flask, render_template_string
from flask_wtf import FlaskForm
from wtforms import SelectMultipleField, StringField, RadioField
from wtforms.validators import DataRequired, Optional
# --- form ---
q1_options = [('rice','rice'),('chips','chips'),('tuna','tuna'), ('other', 'other')]
class MyForm(FlaskForm):
q1_list = SelectMultipleField('Favourite food?', choices=q1_options, validators=[DataRequired()])
q1_other = StringField('Other', validators=[Optional()])
# --- app ---
app = Flask(__name__)
app.config['SECRET_KEY'] = 'qwerty123456'
@app.route('/', methods=['GET', 'POST'])
def index():
form = MyForm()
#print(dir(form))
print(form.validate_on_submit())
#if form.validate_on_submit():
if form.is_submitted():
print('list:', form.q1_list.data)
print('other:', form.q1_other.data)
return render_template_string('''<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form method="POST">
{{ form.q1_list.label }}<br>
{{ form.q1_list(onchange="get_selection(this);") }}<br>
{{ form.q1_other(style="display:none") }}<br>
<input type="submit" value="Go">
</form>
<script language="javascript">
//var q1_list = document.querySelector("#q1_list");
var q1_other = document.querySelector("#q1_other");
function get_selection(select){
//console.log(select);
//console.log(select.value);
//console.log(select.options);
var opts = [];
var opt;
var len = select.options.length;
for(var i = 0; i < len; i++) {
opt = select.options[i];
if (opt.selected) {
opts.push(opt.value);
}
}
//console.log(opts);
if(opts.includes('other')){
q1_other.style.display = 'block';
}else{
q1_other.style.display = 'none';
}
}
</script>
</body>
</html>
''', form=form)
# --- start ---
if __name__ == '__main__':
app.debug = True
app.run()
与addEventListener
相同而不是onchange
<form method="POST">
{{ form.q1_list.label }}<br>
{{ form.q1_list() }}<br>
{{ form.q1_other(style="display:none") }}<br>
<input type="submit" value="Go">
</form>
<script language="javascript">
//var q1_list = document.querySelector("#q1_list");
var q1_other = document.querySelector("#q1_other");
q1_list.addEventListener('input', function(event) {
//console.log(event);
//console.log(event.target.value);
//console.log(event.target.options);
var select = event.target;
//console.log(select.options);
var opts=[];
var opt;
var len = select.options.length;
for(var i = 0; i < len; i++) {
opt = select.options[i];
if (opt.selected) {
opts.push(opt.value);
}
}
//console.log(opts);
if(opts.includes('other')){
q1_other.style.display = 'block';
}else{
q1_other.style.display = 'none';
}
}, false);
</script>
我正在使用 flask-wtf 表单构建表单。我有一个字段,用户可以在其中 select 多个选项。如果他们想要的选择不在我的列表中。我想允许用户 select“其他”并通过文本字段指定他们的选项。
我没有找到在 wtforms 中执行此操作的方法。我到处搜索,似乎无法在任何地方找到答案。我正在做的事情绝不是一个独特的场景,而且在我的想象中会很常见。所以我想我可能 thinking/going 错了。
question1_options = [('rice','rice'),('chips','chips'),('tuna','tuna'), ('other', 'other')]
question2_options = [('yes', 'yes'),('no', 'no')]
class MyForm(FlaskForm):
q1 = SelectMultipleField('favourite food?', choices=question1_options)
q2 = RadioField('do you like football', choices=question2_options)
我想达到的目标:
将 SelectMultipleField 与 StringField 组合在一起,以便在列表中没有合适的选项时使用。用户可以 select 其他并输入他们想要的内容
我找不到合并两个字段的方法。
我认为应该是两个分开的字段始终可见
q1_options = [('rice','rice'),('chips','chips'),('tuna','tuna')] #, ('other', 'other')]
class MyForm(FlaskForm):
q1 = SelectMultipleField('Favourite food?', choices=q1_options)
q1_other = StringField('Other favourite food?')
或者它应该使用 JavaScript
来显示 StringField
当你 select other
.
我尝试创建最少的工作代码。
因为它使用 multiple select
所以它需要更复杂的 JavaScript
代码。
from flask import Flask, render_template_string
from flask_wtf import FlaskForm
from wtforms import SelectMultipleField, StringField, RadioField
from wtforms.validators import DataRequired, Optional
# --- form ---
q1_options = [('rice','rice'),('chips','chips'),('tuna','tuna'), ('other', 'other')]
class MyForm(FlaskForm):
q1_list = SelectMultipleField('Favourite food?', choices=q1_options, validators=[DataRequired()])
q1_other = StringField('Other', validators=[Optional()])
# --- app ---
app = Flask(__name__)
app.config['SECRET_KEY'] = 'qwerty123456'
@app.route('/', methods=['GET', 'POST'])
def index():
form = MyForm()
#print(dir(form))
print(form.validate_on_submit())
#if form.validate_on_submit():
if form.is_submitted():
print('list:', form.q1_list.data)
print('other:', form.q1_other.data)
return render_template_string('''<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form method="POST">
{{ form.q1_list.label }}<br>
{{ form.q1_list(onchange="get_selection(this);") }}<br>
{{ form.q1_other(style="display:none") }}<br>
<input type="submit" value="Go">
</form>
<script language="javascript">
//var q1_list = document.querySelector("#q1_list");
var q1_other = document.querySelector("#q1_other");
function get_selection(select){
//console.log(select);
//console.log(select.value);
//console.log(select.options);
var opts = [];
var opt;
var len = select.options.length;
for(var i = 0; i < len; i++) {
opt = select.options[i];
if (opt.selected) {
opts.push(opt.value);
}
}
//console.log(opts);
if(opts.includes('other')){
q1_other.style.display = 'block';
}else{
q1_other.style.display = 'none';
}
}
</script>
</body>
</html>
''', form=form)
# --- start ---
if __name__ == '__main__':
app.debug = True
app.run()
与addEventListener
相同而不是onchange
<form method="POST">
{{ form.q1_list.label }}<br>
{{ form.q1_list() }}<br>
{{ form.q1_other(style="display:none") }}<br>
<input type="submit" value="Go">
</form>
<script language="javascript">
//var q1_list = document.querySelector("#q1_list");
var q1_other = document.querySelector("#q1_other");
q1_list.addEventListener('input', function(event) {
//console.log(event);
//console.log(event.target.value);
//console.log(event.target.options);
var select = event.target;
//console.log(select.options);
var opts=[];
var opt;
var len = select.options.length;
for(var i = 0; i < len; i++) {
opt = select.options[i];
if (opt.selected) {
opts.push(opt.value);
}
}
//console.log(opts);
if(opts.includes('other')){
q1_other.style.display = 'block';
}else{
q1_other.style.display = 'none';
}
}, false);
</script>