我创建了一个多步骤表单,在最后的“页面”上,我希望它是一种“审阅顺序”,在这里我总结了前几页中所有用户的输入。不过,我很难让输入显示在最后一页上(使用当前方法)。这是我到目前为止的内容,而我正在苦苦挣扎的部分在Pipeline Input Review
下的html部分中:
app.py :
@app.route('/', methods=['GET', 'POST'])
def pipeline():
form = InputForm(request.form)
if request.method == 'POST':
STACK_NAME = form.stack_name.data
BUCKET = form.bucket.data
KEY_PAIR = form.key_pair.data
return render_template('pipeline-alt.html',
title='Pipeline Input',
form=form)
pipeline-alt.html:
<form method="POST" id="regForm" action="">
<h1>Pipeline Input</h1>
<div class="tab">
<h3>Pipeline Infrastructure:</h3>
<label>Stack Name</label>
<input placeholder="(e.g. my-pipeline-run)..." oninput="this.className = ''" name="stack_name"></input>
<label>Pipeline Deployment S3 Bucket</label>
<input placeholder="bucket name..." oninput="this.className = ''" name="bucket">
<label>Key Pair</label>
<select placeholder="key pair..." oninput="this.className = ''" name="key_pair">
<!-- Current attempt at accessing the input data -->
<div class="tab">
<h3>Pipeline Input Review:</h3>
<label>Stack Name: {{ form.stack_name.data }}</label>
<label>Pipeline Deployment S3 Bucket: {{ form.bucket.data }}</label>
<label>Key Pair: {{ form.key_pair.data }}</label>
</div>
</form>
输入表单:
class InputForm(FlaskForm):
bucket_choices = [("", "---")] + [("", bucket["Name"]) for bucket in s3_client.list_buckets()["Buckets"]]
ref_choices = [("", "---")] + [("", bucket["Name"]) for bucket in s3_client.list_buckets()["Buckets"]]
key_choices = [("", "---")] + [("", pair["KeyName"]) for pair in ec2_client.describe_key_pairs()["KeyPairs"]]
stack_name = StringField('STACK NAME', validators=[validators.required()])
bucket = SelectField('PIPELINE DEPLOYMENT BUCKET', validators=[validators.required()], choices=bucket_choices)
key_pair = SelectField('KEY PAIR', validators=[validators.required()], choices=key_choices)
更新2次尝试:
pipeline-alt.html
{% extends 'layout.html' %}
{% block body %}
<form method="POST" id="regForm" action="{{ url_for('pipeline') }}">
<h1>Pipeline Input</h1>
<br>
<!-- One "tab" for each step in the form: -->
<div class="tab">
<h3>Pipeline Infrastructure:</h3>
<br><br>
<label>Stack Name</label>
{{ form.stack_name(placeholder="(e.g. my-pipeline-run)...", oninput="this.className = ''")}}
<label>Pipeline Deployment S3 Bucket</label>
{{ form.bucket(placeholder="Deployment bucket name...", oninput="this.className = ''") }}
<label>Key Pair</label>
{{ form.key_pair(placeholder="AWS ssh key pair...", oninput="this.className = ''") }}
<label>Start Point</label>
{{ form.start_point(placeholder="Start point..", oninput="this.className = ''") }}
</div>
<div class="tab">
<h3>Review</h3>
<label>Stack Name: <span id="stack_name_label">{{ STACK_NAME }}</span></label>
<br>
<label>Pipeline Deployment S3 Bucket: <span id="bucket_label">{{ BUCKET }}</span></label>
<br>
<label>AWS SSH Key Pair: <span id="gpce_ssh_key_pair_label">{{ GPCE_SSH_KEY_PAIR }}</span></label>
<br>
<label>Start Point: <span id="start_point_label">{{ START_POINT }}</span></label>
</div>
<br>
<div style="overflow:auto;">
<div style="float:right;">
<button type="button" id="prevBtn" onclick="nextPrev(-1)">Previous</button>
<button type="button" id="nextBtn" onclick="nextPrev(1)">Next</button>
</div>
</div>
<!-- Circles which indicates the steps of the form: -->
<div style="text-align:center;margin-top:40px;">
<span class="step"></span>
<span class="step"></span>
<span class="step"></span>
</div>
</form>
<script>
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the crurrent tab
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("tab");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == (x.length - 1)) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n)
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("tab");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab + n;
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("regForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("step")[currentTab].className += " finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i, x = document.getElementsByClassName("step");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className += " active";
}
</script>
<script>
$(function() {
$('#stack_name').on('change keyup paste', function(){
$(#'stack_name_label').text($(this).val());
});
$('#bucket').change(function(){
$(#'bucket_label').text($(this).val());
});
$('#key_pair').change(function(){
$(#'key_pair_label').text($(this).val());
});
$('#start_point').change(function(){
$(#'start_point_label').text($(this).val());
});
});
</script>
{% endblock %}
答案 0 :(得分:2)
您使用的表单不正确,我不确定您要达到的目的,但这是您应该如何使用表单
在您的HTML中
<form method="POST" id="regForm" action="{{url_for('pipeline')}}">
<h1>Pipeline Input</h1>
<div class="tab">
<h3>Pipeline Infrastructure:</h3>
<label>Stack Name</label>
{{ form.stack_name(placeholder='yourplaceholder', oninput="this.className....") }}
<label>Pipeline Deployment S3 Bucket</label>
{{ form.bucket(placeholder='bucket name')}}
<label>Key Pair</label>
{{ form.key_pair }}
<!-- Current attempt at accessing the input data -->
<div class="tab">
<h3>Pipeline Input Review:</h3>
<label>Stack Name: <span id="stack_label">{{ STACK_NAME }}</span></label>
<label>Pipeline Deployment S3 Bucket: <span id="bucket_label"> {{ BUCKET }}</span></label>
<label>Key Pair: <span id="key_pair_label">{{ KEY_PAIR }}</span></label>
</div>
</form>
在您的应用中。py
@app.route('/', methods=['GET', 'POST'])
def pipeline():
form = InputForm(request.form)
STACK_NAME = ''
BUCKET = ''
KEY_PAIR = ''
if request.method == 'POST':
STACK_NAME = request.form['stack_name'] # this is how you access the value of the input
BUCKET = request.form['bucket']
KEY_PAIR = request.form['key_pair']
return render_template('pipeline-alt.html',
title='Pipeline Input',
form=form,
STACK_NAME=STACK_NAME,
BUCKET=BUCKET,
KEY_PAIR=KEY_PAIR
)
要在模板中使用WTForm时,可以使用{{form.input_name}}
访问输入。这将在您的表单(或<input>
,具体取决于您的表单定义)中呈现HTML <select>
标签。不要使用{{form.inpute_name.data}}
在您看来,要访问使用表单提交的数据,如果表单方法的类型为request.form['input_name']
,请使用POST
;如果表单方法的类型是{{1,则请使用request.args.get('input_name')
}}
更新
您应该确保选择的元组的第一个元素不是空字符串,因为这是提交表单时传递给视图的值。
尝试如下更改:
GET
更新#2
您没有在原始问题中指定要在提交表单之前立即反映输入的更改。这只能使用javascript。
将以下javascript代码添加到HTML中。这些是事件侦听器,用于侦听表单输入中的任何更改。每次检测到更改时,相应的标签文本都会相应更改。另外,请检出上面更新的HTML代码。我在标签内添加了class InputForm(FlaskForm):
bucket_choices = [("", "---")] + [('bucket["Name"]', bucket["Name"]) for bucket in s3_client.list_buckets()["Buckets"]]
ref_choices = [("", "---")] + [('bucket["Name"]', bucket["Name"]) for bucket in s3_client.list_buckets()["Buckets"]]
key_choices = [("", "---")] + [('pair["KeyName"]', pair["KeyName"]) for pair in ec2_client.describe_key_pairs()["KeyPairs"]]
stack_name = StringField('STACK NAME', validators=[validators.required()])
bucket = SelectField('PIPELINE DEPLOYMENT BUCKET', validators=[validators.required()], choices=bucket_choices)
key_pair = SelectField('KEY PAIR', validators=[validators.required()], choices=key_choices)
标签,以反映javascript代码的更改
<span>