I want to sum the values from a form in Python Flask. How can I do that?
<form action="/count_daily_calories" method="post">
<p>Input 1: <input type="text" name="daily_calories" value="input"></p>
<p>Input 2: <input type="text" name="daily_calories" value="input"></p>
<input type="submit" value="Calculate">
<p>Result: <input type="text" name="result_dc" value="result"></p>
</form>
Flask Code:
#app.route('/daily_intake')
def daily_intake():
if 'user_id' not in session:
return redirect('/')
return render_template("daily_intake.html")
Here I keep getting all the errors:
#app.route('/count_daily_calories', methods=['POST'])
def count_daily_calories():
if 'user_id' not in session:
return redirect('/')
float(request.form['result']) += float(request.form['input'])
return redirect('/daily_intake')
I keep getting the errors can't assign to function call
It will be easier to do all in one function. Using redirect you would have to keep values in cookies to get it later from cookies after redirection and put it in form
I get values from browser using request.form, convert it to float() and next I sum values. When I have result then I render again page with values - and I use {{ result }} in HTML to put values in correct place.
In example I use render_template_string instead of render_template only to make it simpler to copy and run - all will be in one file.
from flask import Flask, request, render_template_string
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
vals = request.form.getlist('daily_calories')
val1 = float(vals[0])
val2 = float(vals[1])
result = val1 + val2
else:
val1 = ''
val2 = ''
result = ''
return render_template_string('''
<form action="/" method="POST">
<p>Input 1: <input type="number" name="daily_calories" value="{{ val1 }}"></p>
<p>Input 2: <input type="number" name="daily_calories" value="{{ val2 }}"></p>
<input type="submit" value="Calculate">
<p>Result: <input type="number" name="result_dc" value="{{ result }}"></p>
</form>
''', val1=val1, val2=val2, result=result)
app.run()
EDIT: Similar example using only JavaScript to get values, calculate sum and put it in form. It blocks button to send data to server and flask doesn't have to calculate it.
If user doesn't use JavaScript then it will not work and it would need mix with previous version.
from flask import Flask, request, render_template_string
app = Flask(__name__)
#app.route('/')
def index():
return render_template_string('''
<form action="/" method="post">
<p>Input 1: <input type="number" name="daily_calories" value="" id="val1"></p>
<p>Input 2: <input type="number" name="daily_calories" value="" id="val2"></p>
<input type="submit" value="Calculate" id="button_calculate">
<p>Result: <input type="number" name="result_dc" value="" id="result"></p>
</form>
<script>
var val1_input = document.getElementById("val1");
var val2_input = document.getElementById("val2");
var result_input = document.getElementById("result");
var button_input = document.getElementById("button_calculate");
button_input.onclick = function(event) {
result_input.value = parseFloat(val1_input.value) + parseFloat(val2_input.value);
//event.preventDefault(); // don't send to server
return false; // don't send to server
}
</script>
''')
if __name__ == '__main__':
app.run()
EDIT:
This example uses pure JavaScript to send AJAX to url /calculate which sends result.
from flask import Flask, request, render_template_string
app = Flask(__name__)
#app.route('/')
def index():
return render_template_string('''
<form action="/" method="POST">
<p>Input 1: <input type="number" name="daily_calories" value="" id="val1"></p>
<p>Input 2: <input type="number" name="daily_calories" value="" id="val2"></p>
<input type="submit" value="Calculate" id="button_calculate">
<p>Result: <input type="number" name="result_dc" value="" id="result"></p>
</form>
<script>
var val1_input = document.getElementById("val1");
var val2_input = document.getElementById("val2");
var result_input = document.getElementById("result");
var button_input = document.getElementById("button_calculate");
button_input.onclick = function(event) {
var formData = new FormData();
formData.append('val1', val1_input.value)
formData.append('val2', val2_input.value)
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if(request.readyState == 4 && request.status == 200)
{
//alert(request.responseText);
result_input.value = request.responseText;
}
}
request.open('POST', "/calculate");
// execute the request
request.send(formData);
return false; // don't send button to server
}
</script>
''')
#app.route('/calculate', methods=['POST'])
def calcualte():
val1 = float(request.form.get('val1'))
val2 = float(request.form.get('val2'))
return str(val1+val2)
if __name__ == '__main__':
app.run()
Related
In my page I have two different forms. I want to read the information from the first form whenever I press a button in the second form. Is this possible?
First form:
<form id="loadData" method="post" action="/loadData">
{% if day %}
Day: <input id="day" name="day" size="5px" value={{day}}>
Month: <input id="month" name="month" size="5px" value={{month}}>
Year: <input id="year" name="year" size="5px" value={{year}}>
{% else %}
Day: <input id="day" name="day" size="5px">
Month: <input id="month" name="month" size="5px">
Year: <input id="year" name="year" size="5px">
{% endif %}
.
.
.
</form>
Second form:
<form id="createFile" method="post" action="/createFile">
<button type="submit">Create</button>
</form>
By clicking the button in the second form I want to read the information in the first one to create a file containing all those information.
I tried something like
#app.route("/createFile", methods=["GET", "POST"])
def createFile():
if request.method == "POST":
day = request.form["day"]
month = request.form["month"]
year = request.form["year"]
return redirect('/')
but I can't manage to read those variable properly.
Despite corresponding in the comments i'm not entirely sure this is your end goal, but let's give it a go?
basically all i did was copy stuff from the links attached in the comment.
a.html:
<form id="form_id" action="/loadData" method="POST">
<input type="text" name="q" value="abcd">
<button type="submit">loadData</button>
</form>
<button id="createFile"> createFile </button>
<script>
function post(path, params, method = 'post') {
// The rest of this code assumes you are not using a library.
// It can be made less verbose if you use one.
const form = document.createElement('form');
form.method = method;
form.action = path;
for (const key in params) {
if (params.hasOwnProperty(key)) {
const hiddenField = document.createElement('input');
hiddenField.type = 'hidden';
hiddenField.name = key;
hiddenField.value = params[key];
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
form.submit();
}
var form_1 = document.querySelector('#form_id')
document.querySelector('#createFile').addEventListener('click', (e) => {
var data = Object.fromEntries(new FormData(form_1).entries());
post("/createFile",data)
});
</script>
app.py:
from crypt import methods
from flask import Flask, request
app = Flask(__name__)
#app.route("/loadData", methods=["POST"])
def loadData():
data = request.get_data()
return f"<h1 style='color:blue'>loadData data: {data}</h1>"
#app.route("/createFile", methods=["POST"])
def createFile():
data = request.get_data()
return f"<h1 style='color:red'>createFile data: {data}</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
page looks like this:
clicking on loadData:
clicking on createFile:
this whole setup is pretty convoluted and unnecessarily complex. what are you trying to achieve?
so, I'm trying to make some sort of wind chill calculator to practice python and flask. And I got the basic calculator working, nothing too fancy, but I just can't figure it out how to reset all the fields.
Like the reset button does reset the id="v" and id="t" fields but it does not work for the id="result" field, and I can't seem to find anything of help.
Thinking of adding and elif condition for the reset button...
So is there a way to tie the reset button to specific fields? Or how could I make it reset everything?
# .py file:
#app.route('/', methods=['POST', 'GET'])
def calc():
if request.method == 'POST':
if 't' in request.form and 'v' in request.form:
t = int(request.form.get('t'))
v = int(request.form.get('v'))
calc = fnc.wind_chill(t, v)
return render_template('app.html', title='Chill Calc', calc=calc)
elif ????:
return ????
else:
return render_template('app.html', title='Chill Calc')
# .html file:
<div class="container">
<form action="/" method="POST">
<label>Speed:</label>
<input class="pure-u" type="number" id="v" name="speed" placeholder="Input speed here">
<label>Temperature:</label>
<input class="pure-u" type="number" id="t" name="temp" placeholder="Input temp here">
<div>
<input type="submit" value="Calculate" id="calculate_button"/>
<input type="reset" value="Reset" id="reset_button"/>
<div class="alert">
Chill is:
<input class="pure-u" type="text" id="result" value="{{ calc }}" onclick="reset"/>
</div>
</div>
</form>
</div>
If you press Reset, it will be reset to the default value.
After submitting the form, let's take the value for "calc" is 30. Then your HTML will look like this,
<input id="v" name="speed" placeholder="Input speed here">
<input id="t" name="time" placeholder="Input temp here">
<input id="result" ***value="30"***/>
Now, if you change the 30 to some other value and then if you press reset, then it will reset to 30. But the above 2 inputs don't have any default value, so those will reset to empty.
I have a solution for this. You can pass the calc value through Javascript.
<form>
.....
Chill is:
<input class="pure-u" type="text" id="result"/>
</form>
<script>
document.getElementById('result').value = "{{calc}}"
</script>
This won't add any default value. So you can use Reset Button.
Note:
Use the input name instead of ID.
# wrong.
if 't' in request.form and 'v' in request.form:
t = int(request.form.get('t'))
v = int(request.form.get('v'))
# use name instead of ID
if 'time' in request.form and 'speed' in request.form:
t = int(request.form.get('time'))
v = int(request.form.get('speed'))
EDIT:
If you want this in server-side, then change the HTML like this,
<form method="POST">
Speed: <input type="number" id="v" name="v" placeholder="Input speed here"><br>
Temparature: <input type="number" id="t" name="t" placeholder="Input temp here"><br>
<button name='btn' value="calculate">Calculate</button>
<button name='btn' value="reset">Reset</button><br>
Chill: <input type="text" value="{{calc}}" id="result"/>
</form>
And python file should be like this,
#app.route('/', methods=['POST', 'GET'])
def calc():
if request.method == 'POST':
if request.form['btn'] == 'calculate':
t = int(request.form.get('t'))
v = int(request.form.get('v'))
calc = t*v
else:
calc = ''
return render_template('wind.html', title='Chill Calc', calc=calc)
return render_template('wind.html', title='Chill Calc')
But this will send an additional request to the backend server. Since we have all the option available in the frontend itself, I think this is not a good method to use backend for resetting the page.
This is the my index.html
<!DOCTYPE html>
<script>
function add_field()
{
var total_text=document.getElementsByClassName("input_text");
total_text=total_text.length+1;
field_div = document.getElementById("field_div");
new_input = "<li id='input_text"+total_text+
"_wrapper'><input type='text' class='input_text' name='input_text[]' id='input_text"+
total_text+"' placeholder='Enter Text'>"+
"<label><input name='input_text"+total_text+"' id='input_text[]' type='radio' value='1'>1</label>"+
"<label><input name='input_text"+total_text+"' type='radio' id='input_text[]' value='2'>2</label>"+
"</li>";
field_div.insertAdjacentHTML('beforeend',new_input);
}
function remove_field()
{
var total_text=document.getElementsByClassName("input_text");
document.getElementById("input_text"+total_text.length+"_wrapper").remove();
}
</script>
{% extends "bootstrap/base.html" %}
{% block content %}
<div class = "container">
<h1>Give the words</h1>
<form action='/results' method="post">
<div id="wrapper">
<input type="button" value="Add TextBox" onclick="add_field();">
<input type="button" value="Remove TextBox" onclick="remove_field();">
<ol id="field_div">
</ol>
</div>
<input type='submit' value='Select'>
</form>
</div>
{% endblock %}
My views.py is as follows:
from flask import render_template, request, url_for
from app import app
from .translit import *
#app.route('/')
def search():
return render_template('index.html')
#app.route('/results', methods = ['GET', 'POST'])
def results():
if request.method == 'GET':
return redirect(url_for('/'))
else:
values = getperm(request.form.getlist('input_text[]'))
print(request.form.getlist('input_text[]'))
return render_template('results.html',
values = values)
Right now, I can extract the input from all the input texts as a list?
How do I get the values form each <li> as a list thereby creating a list of lists?
As an example,
if i type
a 1
b 2
I should be able to extract the result as [[a,1],[b,2]]
We should manipulate the value attribute of checkbox.
Added checkbox with each textbox.
app.py:
from flask import Flask, render_template, url_for, request
app = Flask(__name__)
#app.route('/')
def search():
return render_template('dynamic_input.html')
#app.route('/results', methods = ['GET', 'POST'])
def results():
if request.method == 'GET':
return redirect(url_for('search'))
else:
input_values = request.form.getlist('input_text[]')
checkbox_values = request.form.getlist('input_checkbox')
return render_template('dynamic_input_results.html',
input_values = input_values,
checkbox_values = checkbox_values)
if __name__ == '__main__':
app.run(debug = True)
dynamic_input.html:
<!DOCTYPE html>
<script>
function add_field()
{
var total_text=document.getElementsByClassName("input_text");
total_text=total_text.length+1;
field_div = document.getElementById("field_div");
new_input = "<li id='input_text"+total_text+"_wrapper'>";
new_input += "<input type='text' class='input_text' name='input_text[]' id='input_text"+
total_text+"' placeholder='Enter Text'>";
new_input += "<input type='checkbox' name='input_checkbox' value='"+total_text+"' id='input_checkbox"+
total_text+"'";
new_input += "</li>";
field_div.insertAdjacentHTML('beforeend',new_input);
}
function remove_field()
{
var total_text=document.getElementsByClassName("input_text");
document.getElementById("input_text"+total_text.length+"_wrapper").remove();
}
</script>
<div class = "container">
<h1>Give the words</h1>
<form action='/results' method="post">
<div id="wrapper">
<input type="button" value="Add TextBox" onclick="add_field();">
<input type="button" value="Remove TextBox" onclick="remove_field();">
<ol id="field_div">
</ol>
</div>
<input type='submit' value='Select'>
</form>
</div>
dynamic_input_results.html:
<ul>
{% for value in input_values %}
<li>{{value}}</li>
{% endfor %}
<hr>
{% for value in checkbox_values %}
<li>{{value}}</li>
{% endfor %}
</ul>
Output:
probably not what you were hoping for but this might do the trick if your result list is small enough
#assuming your result list is ll
alplhabet = list(string.ascii_lowercase)
if len(ll)<=len(alplhabet):
res = []
for i in map(None,alplhabet[:len(ll)],ll):
res.append(list(i))
return res
I am trying to have an input field in the template that the user enters a query and that query goes to the views.py
and from there i m taking the query and pass it as argument to the bash script.
This is what i have for now.
views.py
def home(request):
if request.method == 'POST':
try:
query = request.POST['query']
test = subprocess.check_call(['home/.../bash.sh',
query])
return render(request, 'base.html', {'input': test})
except KeyError:
return HttpResponse("Nothing was submitted!")
base.html
<form action="/" method="post">
{% csrf_token %}
<input type="hidden" name="query" value="{{ input }}">
<input type="submit" value="Submit">
</form>
I am stuck right here..i don't know if i shout request.POST or something else much simpler...cause i don't want to use a form.
I figure it out by creating a script in the html template.
<script>
$(".opener").click(function () {
var thead = $("#mytable").find("thead");
thead.find('th').last().remove();
thead = thead.html();
var row = $(this).parents('tr');
row.find('td').last().remove();
row = row.html();
var table = $(document.createElement('table'));
table.append('<thead>' + thead + '</thead>');
table.append('<tbody><tr>' + row + '</tr></tbody>')
$(".modal").html("").append(table);
$(".modal").dialog({width: 'auto', position: 'top'});
});
</script>
Basically, I have written two views for my Flask webpage:
#app.route("/")
def main():
and
#app.route('/', methods=['POST'])
def main_post():
Later on, I have created two more views in an analogical way:
#app.route("/questions")
def questions():
and
#app.route('/questions', methods=['POST'])
def questions_post():
Somehow, my last ['POST'] method does not work at all. Can anyone tell me why? (After sending second ['POST'] there is 'bad request'.)
Here is my code:
#app.route("/")
def main():
questionPath, answersPath, returnPath, databasePath, testName, amount = setup.setup()
names = database.getListOfTests(databasePath)
return render_template('index.html', entries = names)
#app.route('/', methods=['POST'])
def main_post():
text = request.form['text']
processed_text = text
questionPath, answersPath, returnPath, databasePath, testName, amount = setup.setup()
names = database.getListOfTests(databasePath)
if not text in names:
return render_template('index.html', entries = names)
else:
questions2, answers2 = database.getFromDatabase(processed_text,databasePath)
session['messages'] = questions2
return redirect(url_for('questions'))
#app.route("/questions")
def questions():
messages = session['messages']
session['messages'] = messages
return render_template('index2.html', entries = messages)
#app.route('/questions', methods=['POST'])
def questions_post():
text2 = request.form['text2']
processed_text = text2
print(processed_text)
return "XD"
And html:
index.html
<form action="." method="POST">
<input type="text" name="text">
<input type="submit" name="my-form" value="Send">
</form>
index2.html
<form action="." method="POST">
<input type="text" name="text2">
<input type="submit" name="my-form" value="Send2">
</form>
"." is not correct url.
Use empty string action="" or remove action to send form to the same url
<form action="./questions" method="POST">
<input type="text" name="text2">
<input type="submit" name="my-form" value="Send2">
By editing your index2.html action="./view" this would work fine.