如何在html中显示Flask表单数据的摘要?

时间:2018-08-30 18:28:31

标签: python html flask

我创建了一个多步骤表单,在最后的“页面”上,我希望它是一种“审阅顺序”,在这里我总结了前几页中所有用户的输入。不过,我很难让输入显示在最后一页上(使用当前方法)。这是我到目前为止的内容,而我正在苦苦挣扎的部分在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 %}

1 个答案:

答案 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>