Search code examples
javascriptpythondatabaseflasktransfer

How do i pass an int from html file (template) to py file (flask)?


I'm trying to make a local site (just to get the basics of flask) and I want to click a button and store the number of clicks in a txt file. I have the button clicking down and can send the number of clicks TO the html file, but I have no idea how to send that int back to the py file in order to update the txt file.

In the following code I use localStorage as a stand-in but I want it to get the data from the txt file and send the data back to the txt file when the button is pressed.

html file-

<body>
<button type="button" onclick="buttonPress()">Click Me!</button>
<button type="button" onclick="reset()">Reset</button>

<script type="text/javascript">
    var clicks = {{ sClicks }}

    localStorage.setItem('sClicks', clicks);
    updateText();

    function buttonPress(){
        clicks += 1;
        localStorage.setItem('sClicks', clicks);
        updateText();
    }

    function reset(){
        localStorage.clear();
        clicks = 0;
        localStorage.setItem('sClicks', clicks);
        updateText();
    }

    function updateText(){
        document.getElementById("carrier").innerHTML = localStorage.getItem('sClicks');
    }
</script>
</body>

py file-

app = Flask(__name__)
clicks = open('Clicks.txt').read()

@app.route('/')
def test():
    return render_template('index.html', sClicks=clicks)

if __name__ == '__main__':
    app.run(debug=True, host='my ip adress')

Solution

  • Below is an example of how you could send the event using a javascript xhr request that sends a post request to the /clicks route.

    Note that in the POST request i haven't added any data to the request body but merely just use the fact that the route is called with a POST request as a notification that the counter should increase by 1.

    from flask import Flask, request
    from os import path
    
    app = Flask(__name__)
    
    
    @app.route("/clicks", methods=["POST", "GET"])
    def click_collector():
        # POST logic
        if request.method == "POST":
            current_count = read_click_db()
            if current_count is not None:
                new_count = int(current_count) + 1
                return write_click_db(new_count)
            return write_click_db(1)
    
        # GET logic
        elif request.method == "GET":
            current_count = read_click_db()
            if current_count is not None:
                return current_count
            return "0"
    
    
    def read_click_db() -> str:
        if not path.isfile("Clicks.txt"):
            print("File doesn't exist")
            return
        with open("Clicks.txt", "rt") as f:
            click_counter = f.readline()
            f.close()
        return click_counter
    
    
    def write_click_db(counter: int):
        with open("Clicks.txt", "wt") as f:
            f.write(str(counter))
            f.close()
            return str(counter)
    
    
    if __name__ == "__main__":
        app.run(host="localhost", port=5000)
    

    Execute the below JavaScript function in the browser console.

    function notify_click_event() {
        req = new XMLHttpRequest();
        req.open("POST", "http://localhost:5000/clicks")
        req.send()
    }