Python 您正在努力实现,但以下是您应该如何使用表单
在您的HTML中Python 您正在努力实现,但以下是您应该如何使用表单,python,html,flask,Python,Html,Flask,在您的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.
<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>
当您想在模板中使用WTForm时,可以使用{{form.input\u name}
访问输入。这将在表单中呈现HTML
标记(或
,具体取决于表单定义)。不要使用{{form.inpute\u name.data}
在您看来,要访问随表单一起提交的数据,如果表单方法类型为POST
或request.args.get('input\u name')
,则使用request.form['input\u name']
,如果表单方法类型为get
更新
您应该确保选项元组的第一个元素不是空字符串,因为这是提交表单时传递给视图的值
尝试按以下方式更改它:
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)
更新#2
您没有在原始问题中指定要在提交表单之前立即反映输入的更改。这只能使用javascript实现
将下面的javascript代码添加到HTML中。这些是事件侦听器,用于侦听表单输入中的任何更改。每次检测到更改时,相应的标签文本将相应更改。还要检查上面更新的HTML代码。我在标签中添加了
标记,以反映javascript代码的变化
$(function(){
$('#stack_name').on('change keyup paste', function(){
$(#'stack_label').text($(this).val());
});
$('#bucket').change(function(){
$(#'bucket_label').text($(this).val());
});
$('#key_pair').change(function(){
$(#'key_pair_label').text($(this).val());
});
});
谢谢你的回复。当我实现您的解决方案时,1)STACK_NAME在最后一页显示为空,2)我没有将输入设置为
{{form.input-NAME….}
形式的原因是我不确定如何处理具有动态选项的输入。例如,BUCKET
输入实际上是下拉式的,选项来自AWS API请求(在app.py中执行并传递到HTML文件),以获取用户的BUCKET列表。请参阅我的问题中添加的关于动态表单输入的信息。(对不起,我不小心编辑了你的回答而不是我的问题,所以请忽略!)没关系,我解决了问题2)。但我仍然遇到问题1)——变量在“查看”页面上显示为空白。当然,我已经在上面发布了!查看我的更新,让我知道这是否解决了问题谢谢您的回复。当我实现您的解决方案时,1)STACK_NAME在最后一页显示为空,2)我没有将输入设置为{{form.input-NAME….}
形式的原因是我不确定如何处理具有动态选项的输入。例如,BUCKET
输入实际上是下拉式的,选项来自AWS API请求(在app.py中执行并传递到HTML文件),以获取用户的BUCKET列表。请参阅我的问题中添加的关于动态表单输入的信息。(对不起,我不小心编辑了你的回答而不是我的问题,所以请忽略!)没关系,我解决了问题2)。但我仍然遇到问题1)——变量在“查看”页面上显示为空白。当然,我已经在上面发布了!查看我的更新,并让我知道这是否解决了问题
{% 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 %}
<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>
@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
)
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)
$(function(){
$('#stack_name').on('change keyup paste', function(){
$(#'stack_label').text($(this).val());
});
$('#bucket').change(function(){
$(#'bucket_label').text($(this).val());
});
$('#key_pair').change(function(){
$(#'key_pair_label').text($(this).val());
});
});