Reputation: 53
I have a simple program using FastAPI that multiplies a float value by 2 and displays it in HTML; this value is inputted through a HTML form. I'm wondering how I can get the value to display dynamically, without the page reloading when you press enter or press the submit button.
Here are the scripts (main.py and double.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
</head>
<body>
<h1>Hello World!</h1>
<form method="post">
<input type="number" step="0.00000001" name="num"/>
<input type="submit"/>
</form>
<p>Result: {{ result }}</p>
</body>
</html>
from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
import uvicorn
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.get("/", response_class=HTMLResponse)
async def double_num(request: Request):
result = "Type a number"
return templates.TemplateResponse('double.html', context={'request': request, 'result': result})
@app.post("/", response_class=HTMLResponse)
async def double_num(request: Request, num: float = Form(...)):
result = num*2
return templates.TemplateResponse('double.html', context={'request': request, 'result': result})
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
I realize similar questions have been asked but they seem to involve jquery/javascript and don't work for me due to the FastAPI/python backend.
Upvotes: 3
Views: 2501
Reputation: 34501
As described in this answer, to keep the page from reloading/redirecting when submitting an HTML <form>
, you would need to use a Javascript interface/library, such as Fetch API, to make an asynchronous HTTP
request. If you would like to prevent the page from reloading when the user hits the enter key as well, you could use a similar approach to this answer that provides a solution on how to handle the <form>
submission on the submit event (using the Event.preventDefault()
method). Example below:
app.py
from fastapi import FastAPI, Request, Form
from fastapi.templating import Jinja2Templates
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.get("/")
async def double_num(request: Request):
return templates.TemplateResponse('double.html', context={'request': request})
@app.post("/")
async def double_num(num: float = Form(...)):
return num * 2
templates/double.html
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
<script>
document.addEventListener("DOMContentLoaded", (event) => {
document.getElementById("myForm").addEventListener("submit", function (e) {
e.preventDefault(); // Cancel the default action
submitForm();
});
});
</script>
</head>
<body>
<h1>Hello World!</h1>
<form id="myForm">
<input type="number" name="num">
<input class="submit" type="submit" value="Submit">
</form>
<div id="responseArea">Type a number</div>
<script>
function submitForm() {
var formElement = document.getElementById('myForm');
var data = new FormData(formElement);
fetch('/', {
method: 'POST',
body: data,
})
.then(response => response.text())
.then(data => {
document.getElementById("responseArea").innerHTML = data;
})
.catch(error => {
console.error(error);
});
}
</script>
</body>
</html>
Upvotes: 3