Home > Net >  Flask get checkbox value without submit button
Flask get checkbox value without submit button

Time:12-05

I'm trying to get value of checkbox in Flask without a submit.

Here is my 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')

Here is my JavaScript that toggles the checkbox:

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');
    }
}

And here is my 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>

I want to

  1. Remove the submit button
  2. When I click on the checkbox, Python should receive the checkbox value, 0 or 1.

The present code only returns 1 when I click the submit button. The solution should be that I remove the submit button entirely and have Python listen on the value change and print that in real time.

I'm open to socketio solution, but I don't know how to do it.

CodePudding user response:

You only need to change the client-side for this; use AJAX. Here's the simplest example using pure 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()" />
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Obviously the example won't work because there is no server, but this is an example of AJAX with a checkbox once a user clicks a checkbox.

CodePudding user response:

To do this, you'll want to add a listener to the input. A form submission with a full refresh would probably be poor UX, so we'll send an asynchronous request with JS to POST the data to the route, then read data from the response.

Here's a proof-of-concept demo that uses JSON all the way through, the standard for AJAX nowadays:

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)
  • Related