【问题标题】:Flask get checkbox value without submit buttonFlask 在没有提交按钮的情况下获取复选框值
【发布时间】:2022-01-10 19:49:36
【问题描述】:

我试图在没有提交的情况下获取 Flask 中复选框的值。

这是我的 app.py:

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.form.get('c_check')=="0":
        print('success: 0')
        checked=''
    elif request.form.get('c_check')=="1":
        print('success: 1')
        checked='checked'
    return render_template('index.html')

这是我用来切换复选框的 JavaScript:

function hello() {
    if (document.querySelector('input').value=='0') {    
        document.querySelector('input').value='1'
        console.log('value 1');
    }
    else {
        document.querySelector('input').value='0'
        console.log('value 0');
    }
}

这是我的 index.html:

<form method="post" action="">

    <div class="form-check form-switch">
        <input class="form-check-input btn-lg" 
        name="c_check" 
        value="0" 
        type="checkbox" 
        role="switch" 
        id="flexSwitchCheckChecked" 
        onclick="hello()"
        >
        
        <label class="form-check-label btn-lg" 
        for="flexSwitchCheckChecked"></label>
        <input type="submit">
    </div>
</form>

<script src="{{url_for('static', filename= 'js/hello.js')}}"></script>

我想要

  1. 移除提交按钮
  2. 当我点击复选框时,Python 应该会收到复选框值,0 或 1。

当前代码仅在我单击提交按钮时返回 1。解决方案应该是我完全移除提交按钮,让 Python 监听值的变化并实时打印出来。

我对socketio解决方案持开放态度,但我不知道该怎么做。

【问题讨论】:

  • Flask 是一个服务器端 Web 框架,它只能在您向它发出请求时返回内容,并且如果没有您自己的自定义 JavaScript 代码,它不会动态更新页面。您可以创建一个不返回 HTML 且仅返回 200 状态代码的自定义路由,并在复选框上的 onclick 事件处理程序上使用 fetch。如果没有像这种情况那样来回发送的数据,那么 Websocket 就没有意义了。

标签: javascript python html flask


【解决方案1】:

为此,您需要向输入添加一个侦听器。完全刷新的表单提交可能会导致用户体验不佳,因此我们将使用 JS 发送异步请求以将数据 POST 到路由,然后从响应中读取数据。

这是一个概念验证演示,它一直使用 JSON,这是当今 AJAX 的标准:

index.html:

<body>
  <input type="checkbox" />
  <div class="result"></div>
  <script>
    document
      .querySelector("input")
      .addEventListener("click", e => {
        fetch("http://127.0.0.1:5000/", {
            method: "POST",
            headers: {
              "Accept": "application/json",
              "Content-Type": "application/json"
            },
            body: JSON.stringify({
              c_check: Number(e.target.checked)
            })
          })
          .then(res => {
            if (!res.ok) {
              throw Error(res.status);
            }

            return res.json();
          })
          .then(({data: {val}}) => {
            console.log(val);
            const res = document.querySelector(".result");
            res.innerText = `client got: ${val}`;
          })
          .catch(err => console.error(err))
        ;
      })
    ;
  </script>
</body>

app.py:

from flask import (
    Flask, jsonify, render_template, request
)

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template("index.html")

    val = request.json.get("c_check")
    print(val)
    return jsonify({"data": {"val": val}})
    
if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000, debug=True)

【讨论】:

    【解决方案2】:

    您只需要为此更改客户端;使用 AJAX。 这是使用纯 JavaScript 的最简单示例:

    function ajaxRequest() {
      const checked = document.getElementById("mycheckbox").checked;
      console.log("Sending data to the server that the checkbox is", checked);
      
      // Use the XMLHttpRequest API
      const xhttp = new XMLHttpRequest();
      xhttp.onload = function() {
        console.log("Result sent to server!");
      }
      xhttp.open("POST", "/", true);
      xhttp.send();
    }
    <label for="mycheckbox">Check or uncheck this box:</label>
    <input id="mycheckbox" type="checkbox" onchange="ajaxRequest()" />

    显然该示例无法运行,因为没有服务器,但这是一个带有复选框的 AJAX 示例,一旦用户单击复选框。

    【讨论】:

    • 你为什么使用XMLHttpRequest而不是更现代的fetch
    • 因为更多的浏览器支持它。它也没有什么问题。显然,fetch也是可能的。看到这个comparison
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多