Как показать сводку данных формы Flask в формате HTML? - PullRequest
0 голосов
/ 30 августа 2018

Я создал многошаговую форму, и на заключительной «странице» я хочу, чтобы это было что-то вроде «порядка просмотра», где я суммирую все входные данные пользователей с предыдущих страниц. Однако у меня возникли проблемы с отображением входных данных на последней странице (используя мой текущий метод). Вот что у меня есть, и часть, с которой я борюсь, находится в разделе html под Pipeline Input Review:

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)

газопровод-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 ПОПЫТКА:

Трубопровод-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 голосов
/ 30 августа 2018

Вы не используете форму правильно, и я не уверен, чего вы пытаетесь достичь, но вот как вы должны использовать форму

В вашем 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>

В вашем app.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}}. Это отобразит тег HTML <input> в вашей форме (или <select> в зависимости от определения формы). Не используйте {{form.inpute_name.data}}

По вашему мнению, для доступа к данным, отправленным с помощью формы, которую вы используете request.form['input_name'], если метод формы имеет тип POST или request.args.get('input_name'), если метод формы имеет тип GET

UPDATE

Вы должны убедиться, что первый элемент вашего выбора кортежа не является пустой строкой, поскольку это значение передается вашему представлению при отправке формы.

попробуйте изменить его следующим образом:

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-код выше. Я добавил <span> теги внутри ваших ярлыков, чтобы отразить изменения из кода 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());
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...