Javascript:表单验证导致选定的 Ajax Live Search 字段被重置为 Null?

标签 javascript jquery ajax flask flask-wtforms

从下面的第一个屏幕截图中,我有一个 Flask 应用程序,它有一个搜索字段,该字段使用 Ajax 请求来查询美国州列表以作为下拉值返回。当我离开Name字段为空并点击提交,这无意中删除了我之前选择的下拉值。我也想在表单验证期间保留下拉字段。
enter image description here
enter image description here
app.py

import sys

from flask import Flask, render_template, request
from forms import InputForm

app = Flask(__name__)

app.config['SECRET_KEY'] = "Development"

US_STATES = ["Alaska", "Alabama", "Arkansas", "American Samoa", "Arizona", "California",
             "Colorado", "Connecticut", "District ", "of Columbia", "Delaware",
             "Florida", "Georgia", "Guam", "Hawaii", "Iowa", "Idaho", "Illinois",
             "Indiana", "Kansas", "Kentucky", "Louisiana", "Massachusetts", "Maryland",
             "Maine", "Michigan", "Minnesota", "Missouri", "Mississippi", "Montana",
             "North Carolina", "North Dakota", "Nebraska", "New Hampshire",
             "New Jersey", "New Mexico", "Nevada", "New York", "Ohio", "Oklahoma",
             "Oregon", "Pennsylvania", "Puerto Rico", "Rhode Island", "South Carolina",
             "South Dakota", "Tennessee", "Texas", "Utah", "Virginia", "Virgin Islands",
             "Vermont", "Washington", "Wisconsin", "West Virginia", "Wyoming"]

@app.route("/", methods=["GET","POST"])
def index():

    form = InputForm()

    if request.method == "POST":
        print(form.name.data, file=sys.stderr)
        print(form.states.data, file=sys.stderr)
        print(form.territory.data, file=sys.stderr)
        print("Hello from outside Validate.", file=sys.stderr)

        if form.validate_on_submit():
            print(form.name.data, file=sys.stderr)
            print(form.states.data, file=sys.stderr)
            print(form.territory.data, file=sys.stderr)
            print("Hello from inside Validate.", file=sys.stderr)
        else:
            print(form.errors)

    return render_template("states.html", form=form)


@app.route("/search")
def search():
    text = request.args["searchText"]

    result = [c for c in US_STATES if text.lower() in c.lower()]
    return {"results": result}


if __name__ == '__main__':
    app.run(host="localhost", port=5001, debug=True)
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, SelectField, SubmitField
from wtforms import validators
from wtforms.validators import Optional, InputRequired, DataRequired

class InputForm(FlaskForm):
    name = StringField("Name", validators=[DataRequired()])
    states = SelectField("US States", validate_choice=False)
    territory = SelectField("Is Territory?", choices=["Unknown", "Yes", "No"], default="Unknown", validators=[InputRequired()])
    submit = SubmitField("Add State", validators=[Optional()])
模板\index.html
<!DOCTYPE html>
<html>
  <head>
    <title>Live Search Ajax Demo</title>
    <meta charset="utf-8" />

    <!-- CSS Stylesheets -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.1/css/bootstrap-select.css"/>

    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.1/js/bootstrap-select.js"></script>

    <script type="text/javascript">
      function liveSearch(value) {
        value = value.trim();
        if (value != "") {
          $.ajax({
            url: "search",
            data: { searchText: value },
            dataType: "json",
            success: function (data) {
              var res = "";
              for (i in data.results) {
                res += "<option value=" + data.results[i] + ">" + data.results[i] + "</option>";
              }
              $("#states").html(res);
            },
          });
        } else {
          $("#states").html("");
        }
      }
    </script>
  </head>
  <body>
      <!-- Main -->
      <main role="main" class="container">
        <div>
            {% block content %}
            {% endblock %}
        </div>
      </main>
  </body>
</html>
模板\states.html
{% extends "index.html" %}
{% block content %}
<div class="content-section">
  <div class="col-6">
    <div class="row mt-4 mb-4">
      <h2>Live Search in Flask with Ajax</h2>
      <hr>
      <div class="row mt-4 mb-4">
      <form method="POST" action="" novalidate="novalidate">
        {{ form.hidden_tag() }}
        <fieldset class="form-group">
          <div class="row">
            <div class="col">
              {{ form.name.label(class="form-control-label") }}
              {% if form.name.errors %}
                  {{ form.name(class="form-control form-control-md is-invalid") }}
                  <div class="invalid-feedback">
                      {% for error in form.name.errors %}
                          <span>{{ error }}</span>
                      {% endfor %}
                  </div>
              {% else %}
                  {{ form.name(class="form-control form-control-md") }}
              {% endif %}
            </div>
            <div class="col">
              {{ form.territory.label(class="form-control-label") }}
              {% if form.territory.errors %}
                  {{ form.territory(class="form-control form-control-md is-invalid") }}
                  <div class="invalid-feedback">
                      {% for error in form.territory.errors %}
                          <span>{{ error }}</span>
                      {% endfor %}
                  </div>
              {% else %}
                  {{ form.territory(class="form-control form-select") }}
              {% endif %}
            </div>
          </div>
          <div class="row">
            <div class="input-group mt-4 mb-4">
              <input type="text" class="form-control" placeholder="Search USA States" onkeyup="liveSearch(this.value)">
                {{ form.states(class="form-control form-select") }}
              </input>
            </div>
          </div>
          <div class="input-group mb-3 justify-content-md-end">
            <div class="form-group">
                {{ form.submit(class="btn btn-primary btn-sm") }}
            </div>
          </div>
        </fieldset>        
      </form>
    </div>
  </div>
</div>
{% endblock content %}

最佳答案

JQuery official documentation如果您需要某些东西,非常适合初学者,我建议您从那里开始。
否则,请清楚地说明您要做什么。
这是一种更简洁的方法来完成您已经完成的工作。

确保您的表单内容具有非常严格的规则(我认为您可以在后端的“表单构建器”上自定义此规则),例如:

<input name="Name" type="text" maxlength="10" required />
$(document).ready(function () {
    $('#inputSearchStates').keyup(function () { // when a keyboard key is hitted (even CTRL is included and all keyboard keys...)
        var value = $(this).val().trim(); // remove first and last blank spaces from your string (note that blank spaces in the middle will still remain)
        if (this.form.reportValidity()) { // return true if the form is valid (required inputs already filled ...etc)
            $.ajax({
                url: "search",
                data: {
                    searchText: value
                },
                dataType: "json",
                success: function (data) {
                    // data is the returned result from your backend
                    // it can be a string/filled array/empty array/number/float ...etc
                    $("#states").empty(); // always make your dropdown empty (with definitely no options to select)

                    data.results.each(function () { // automatically fetch the response result (a JS array) if exists , else it will do nothing.
                        $("#states").append(`
                                <option value="${this}"> ${this} </option>
                        `); // for each available data in your response result and append <options> respectively
                    });

                    // remember that your dropdown will still empty if no data there is no data in your response array.
                },
            });
        }
    });
});

关于Javascript:表单验证导致选定的 Ajax Live Search 字段被重置为 Null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67472739/

相关文章:

javascript - 基于 Ajax 的多个自动完成/自动建议插件

jquery - 将背景视频切换为背景颜色

java - Ajax 框架小应用程序

javascript - 从绝对路径 AJAX 加载

javascript - 我收到无效 json 错误

javascript - 在 JavaScript 上运行计时器

javascript - 需要 lodash 组合的帮助才能获得以下对象

javascript - html5 Canvas 填充文本具有特定的 alpha 和背景具有不同的 alpha

javascript - 如何在页面加载时替换多个标签中的单词实例?

javascript - .each(function() 中包含多个函数 - jQuery