I'm trying to make a Flask web that has a pomodoro timer where the user can set the timer themselves.
Here's my code: app.py
import time
from flask import Flask, render_template, url_for, flash, redirect, request, jsonify
app = Flask(__name__)
@app.route("/")
def index():
return render_template('index.html')
# Get is for loading that page; Post is for submitting the "form" / set timer
@app.route("/pomodoro.html", methods=["GET", "POST"])
def pomodoro():
if request.method == "POST":
# Cast user inputs as int and store in variables
hours = int(request.form.get("hours"))
minutes = int(request.form.get("minutes"))
seconds = int(request.form.get("seconds"))
# Check if user input is valid aka no negative numbers
if hours < 0 or minutes < 0 or seconds < 0:
return apology("There is no negative time...", 400)
# Check if the input is blank. If so, replace with 0
if not hours:
hours = 0
elif not minutes:
minutes = 0
elif not seconds:
seconds = 0
# Calculate total number of seconds from the user inputs
totalTime = hours * 3600 minutes * 60 seconds
print(totalTime)
# Countdown timer
while(totalTime > -1):
# Call the function to start countdown
hours, minutes, seconds = runTimer(totalTime)
totalTime -= 1
return jsonify({'hours' : hours, 'minutes' : minutes, 'seconds' : seconds})
# Let the user know if the time has expired
if(totalTime == 0):
flash("Time's up")
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("pomodoro.html")
# Figure out how many h, m, s there are and store them in total variables
def runTimer(totaltime):
# Divmod returns 2 values. Ex. 10/5 then totalMin will be 2 and totalSec, or the remainder, will be 0
# Parameter is totaltime / 60
totalMinutes, totalSeconds = divmod(totaltime, 60)
totalHours = 0
if(totalMinutes > 60):
totalHours, totalMinutes = divmod(totalMinutes, 60)
return totalSeconds, totalMinutes, totalHours
if __name__ == "__main__":
app.run(debug=True)
pomodoro.html
{% extends "layout.html" %}
{% block title %}
Pomodoro
{% endblock %}
{% block script %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
// This function will be executed after the HTML is loaded
$(document).ready(function() {
// When the submit button is clicked, the function with AJAX starts
$('#start_button').on('submit', function(e) {
// Prevent event default before starting an ajax call
e.preventDefault();
console.log("Hello");
$.ajax({
data : {
// Key : value pair.
sec : $('#seconds').val(),
min : $('#minutes').val(),
hr : $('#hours').val(),
},
type : 'POST',
// Where to get the data
url : '/pomodoro',
// After data is obtained, update values
success: function(data) {
$('#hours').val(data.hours);
$('#minutes').val(data.minutes);
$('#seconds').val(data.seconds);
}
});
})
});
</script>
{% endblock %}
{% block main %}
<form action="/pomodoro" method="post">
<div id="countdown_container">
<ul>
<li><input type="number" id="hours" name="hours" placeholder="Hours" value="{{ request.form.hours }}"></li>
<li><input type="number" id="minutes" name="minutes" placeholder="Minutes"></li>
<li><input type="number" id="seconds" name="seconds" placeholder="Seconds"></li>
</ul>
</div>
<div id="buttons_container">
<button id="start_button" type="submit" >Start</button>
<button id="cancel_button" type="button" >Cancel</button>
</div>
</form>
{% endblock %}
I have 2 questions about my code.
I'm getting a POST 404 error. My GET works fine. I tried printing in app.py and pomodoro.html but neither showed up. I tried using the debugger but perhaps I was doing it wrong, the debugger wouldn't let me go into my def pomodoro function to check the specifics. I double checked my spelling and syntax so hopefully there's no careless mistake.
Right now, my pomodoro is being calculated in app.py then the information is sent over to pomodoro.html. Am I on the right track? I'm not sure if this will allow dynamic data update on the webpage.
Thank you!
CodePudding user response:
Your app route is "/pomodoro.html" and your form is posting to "/pomodoro", I don't think the form can actually properly post anywhere. Try matching your route in app.py and where the form posts to in pomodoro.html