1

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.

1
  • 1
    Flask is a server side web framework, it can only return stuff when you make a request to it and it won't update a page dynamically without your own custom JavaScript code. You can make a custom route not returning HTML and just a 200 status code, and use fetch on the onclick event handler on the checkbox. Websockets don't make sense if there's no data being sent back and forth like this case. Commented Dec 5, 2021 at 3:54

2 Answers 2

2

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("/", {
            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)
Sign up to request clarification or add additional context in comments.

Comments

2

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()" />

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.

2 Comments

Why are you using XMLHttpRequest instead of the more modern fetch?
Because it's supported in more browsers. There's nothing wrong with it either. Obviously, fetch is also possible. See this comparison.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.