I need to get data from 2 different forms. The first "index.html" rendering takes a user's selected option and stores it on the variable "item".
on "page2.html", the "item" value is shown here just fine. And again, the user is entering some new data on the textbox input and then it's redirected to the next rendering, "page3.html"
on "page3.html", it is supposed to show both data from the forms on "index.html" and "page2.html" but i'm getting "None" when I try to show the "item" value. Why?
I've tried to do it on separate app.route() routes, but I got the None type value as well.
the app.py file:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/", methods=['GET', 'POST'])
def index():
if request.method == 'POST':
if request.form.get('send') == 'send':
item = str(request.form.get('test1'))
return render_template('page2.html', item=item)
if request.form.get('send2') == 'send2':
item = str(request.form.get('test1'))
text = request.form.get('textbox')
return render_template('page3.html', item=item, text=text)
else:
return render_template('index.html')
app.run(debug=True)
the index.html file:
<div align="center">
<form method="POST" action="{{ url_for('index') }}">
<select name="test1">
<option name="1" value="1">1</option>
<option name="2" value="2">2</option>
<option name="3" value="3">3</option>
</select>
<button type="submit" name="send" value="send">Send</button>
</form>
</div>
the page2.html file:
<div align="center">
<form method="POST" action="{{ url_for('index') }}">
<h2>Previous selection: {{ item }}</h2><br>
<input type="text" name="textbox" value="Enter text">
<button type="submit" name="send2" value="send2">Send</button>
</form>
</div>
and the page3.html file:
<div align="center">
<h2>Your result is:</h2><br>
<h2>"{{ text }}" and "{{ item }}" </h2>
</div>
store the value of item in a session so that you can access it later. Once you are done you can clear the session like session.pop("session_name", None)
if request.form.get('send') == 'send':
item = str(request.form.get('test1'))
session["test1"]=item
return render_template('page2.html', item=item)
if request.form.get('send2') == 'send2':
item = session.get("test1")
text = request.form.get('textbox')
return render_template('page3.html', item=item, text=text)
Related
I have a form in HTML that looks like this:
<form action="{{ url_for('home_blueprint.tabledata', tablename = col )}}" method="post">
<select name="tables" placeholder="Table" id="tables" size=3>
{% for col in column_names %}
<option value = "{{ col }}">{{ col }}</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-primary btn-block btn-large">Submit</button>
</form>
Basically, the form above displays a drop-down list of items {{ col }}. I want that a selected and submitted item from the list above (for example: 'tablename' ) appears in my URL like www.example.com/tabledata/tablename
My flask code is here:
#blueprint.route('/tabledata/<tablename>', methods=['GET', 'POST'])
#login_required
def tabledata(tablename):
return render_template('index.html', tablename=tablename)
In other words, I want to pass a variable from this form to flask using url_for.
How I do that? Thank you in advance!!
There are many ways to do this. I'll go with the most basic one (at least for me).
You just need to tweak your function so if someone submits a GET request, he/she gets the dropdown list, and if the user submits a POST request, fetch the POST data and redirect him/her to another url, the dynamic one.
So your flask code becomes:
#blueprint.route('/tabledata/<tablename>', methods=['GET', 'POST'])
#login_required
def tablename(tablename):
return "Hi"
#blueprint.route('/tabledata')
#login_required
def tabledata():
if request.method == 'GET':
return render_template('index.html', column_names=['abc', 'def', 'ghi']) # Column names were added by me, ignore it
elif request.method == 'POST':
data = request.form.get("tables")
return redirect(url_for('tablename', tablename=data))
And just a little change to the form action:
<form action="{{ url_for('home_blueprint.tabledata')}}" method="POST">
<select name="tables" placeholder="Table" id="tables" size=3>
{% for col in column_names %}
<option class="column" value="{{ col }}">{{ col }}</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-primary btn-block btn-large">Submit</button>
</form>
Now if you click on an option, say 'abc', from the dropdown, and submit it, you will be taken to the url www.example.com/tabledata/abc .
I have two flask form in same page. One form is visible at the beginning and user have to select an option and based on that the second form is generated. Second from contains a dropdown which will submit the form on onchange event. When this submission occurs I am getting bad request error. My Html form is:
<form action="/ip" method="POST" name="btn" value="project">
<label>Select Project : </label>
<select class="form-control" style="width: 50%;display:inline-block" name="project_name">
<option></option>
<option value="k">Ki</option>
<option value="s">S</option>
<option value="l">L</option>
</select>
<button type="submit" class="btn btn-primary m-b-10 m-l-5" style="display:inline-block" ">Fetch Details</button>
</form>
<form method="POST" action="/ip" name="btn" value="dlvr">
<select id="subsystem_value" onchange="this.form.submit()">
{% for i in data %}
{% for k in i %}
<option value={{ k }}>{{ k }}</option>
{% endfor %}
{% endfor %}
</select>
</form>
and my flask view is :
#auth.route('/ip',methods = ['POST', 'GET'])
def ip():
if request.method == 'POST':
if request.form['btn'] == "project":
project = request.form['project_name']
c, conn = connection()
subsystem = "SELECT distinct sub from ip where project='{}'".format(project)
query = "SELECT distinct del from ip where project='{}'".format(project)
c.execute(query)
data = c.fetchall()
c.execute(subsystem)
subsystem = c.fetchall()
sub = []
for row in subsystem:
for id in row:
sub.append(id)
conn.close()
return render_template('ip.html', data=data,sub=sub)
else:
subsystem = request.form['subsystem_value']
return render_template('ip.html')
else:
return render_template('ip.html')
I tried to make same name for forms and gave separate values too. But still I am getting bad request error.
I have two areas where your error is coming from
1) Form name is deprecated since HTML 4 and is no longer submitted therefore
if request.form['btn'] == "project":
will not be understood by flask
The way to go around that is to give your submit button a name like this
<button type="submit" name="project" class="btn btn-primary m-b-10 m-l-5" style="display:inline-block" ">Fetch Details</button>
and in your flask view, check for the form like this
if 'project' in request.form:
2) The second error is on this line
<form method="POST" action="/ip" name="btn" value="dlvr">
<select id="subsystem_value" onchange="this.form.submit()">
line two here should be name= "subsystem_value", not id="subsystem_value"
otherwise this line in flask will not be understood
subsystem = request.form['subsystem_value']
So I have this simplified code that is no longer giving me an error and returning the values the way I think you want them
in flask
#app.route('/ip',methods = ['POST', 'GET']) #Used #pp.route to match my testing app
def ip():
if request.method == 'POST':
if 'project' in request.form:
project = request.form['project_name']
return str(project)
else:
subsystem = request.form['subsystem_value']
return str(subsystem)
else:
return render_template('test.html')
in the template
<form action="/ip" method="POST" >
<label>Select Project : </label>
<select class="form-control" style="width: 50%;display:inline-block" name="project_name">
<option></option>
<option value="k">Ki</option>
<option value="s">S</option>
<option value="l">L</option>
</select>
<button type="submit" name="project" class="btn btn-primary m-b-10 m-l-5" style="display:inline-block" ">Fetch Details</button>
</form>
<form name method="POST" action="/ip" >
<select name="subsystem_value" onchange="this.form.submit();">
<option value="test1">t1</option>
<option value="test2">t2</option>
<option value="test3">t3</option>
</select>
</form>
Hope that helps you out
You are in the perfect position to avail yourself of Flasks debug facilities, which you can activate by either setting the environment variable FLASK_DEBUG=1 or by passing debug=True to app.run().
See http://flask.pocoo.org/docs/1.0/api/#flask.Flask.debug
Also, if there's any chance that this code will face hostile users, use SQL bind variables instead of constructing a query from untrusted input. A SQL Injection attack can ruin your day.
I'm using Flask 0.12 with Python 3.6 to create a simple app that will display selected items in another page when the submit button is clicked.
The main Flask app is in app.py as:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/result', methods=['POST'])
def result():
return render_template('result.html')
This renders the following webpage using Bootstrap:
<h1>Example Page</h1>
<p>Choose the options in the form below then submit your selections.</p>
<form action="">
<div class="form-group">
<label for="vehicle">Vehicle</label>
<select id="vehicle" class="form-control">
<option>truck</option>
<option>car</option>
<option>van</option>
</select>
</div>
<div class="form-group">
<label for="year">Year</label>
<select id="year" class="form-control">
<option>1972</option>
<option>1999</option>
<option>2010</option>
</select>
</div>
</form>
<br>
<button type="submit" class="btn btn-default">Submit</button>
How can I get Flask to show the selected items in my results.html template when the submit button is clicked?
You have to make few changes in the form to display in result page.
You have to add action url and method in form
<form action="/result" method="post">
Add name in the select field
<select id="vehicle" class="form-control" name="vehicle">
<select id="year" class="form-control" name="year">
Use flask request to get the form values
from flask import request
# inside your POST view
vehicle = request.form.get('vehicle')
year = request.form.get('year')
return render_template('result.html', vehicle=vehicle, year=year)
Finally in your result html page add these...
{{ vehicle }} {{ year }}
I'm trying to get a select option that is selected to stay after the page refresh using Flask. I have attempted to do so with Jinga2, but it's is not working:
<div class="col-sm-4 col-lg-4 col-md-4">
<select class="form-control" id="myselect" name="thing" required>
<option value="" {% if thing=='' %} selected {% endif %} ></option>
<option value="Foo" name="Foo" id="Foo" {% if thing =="Foo" %} selected {% endif %}>Foo</option>
<option value="Bar" name="Bar" id="Bar" {% if thing =="Bar" %} selected {% endif %}>Bar</option>
</select>
</div>
Where the variable energy is populated and passed through with Python. After looking into this, I feel that this is the way to make this work in Flask, though apparently not. Any assistance would be appreciated!
#app,route('/things', methods=['POST']
def things()
if len(facts['thing']) > 11:
energy = [facts['thing'][0:8],facts['thing'][9:]]
else:
energy = [facts['things']]
...
return render_template('thing.html', thing=energy)
Please see this example as it works for what you're trying to do. I can't exactly debug what's going wrong in your code because you've provided me with parts and I don't know what they're doing.
Folder structure
Test
|___templates
| |___things.html
|___Test.py
things.html
<form method="post">
<div class="col-sm-4 col-lg-4 col-md-4">
<select title="thing" class="form-control" id="myselect" name="thing" required>
<option value="" {% if thing=='' %} selected {% endif %} ></option>
<option value="Foo" name="Foo" id="Foo" {% if thing =="Foo" %} selected {% endif %} >Foo</option>
<option value="Bar" name="Bar" id="Bar" {% if thing =='Bar' %} selected {% endif %}>Bar</option>
</select>
<button type="submit">SEND</button>
</div>
</form>
Test.py
from flask import Flask, render_template, request
app = Flask(__name__)
PORT = 5000
#app.route('/things', methods=['GET', 'POST'])
def things():
"""
Accepts both GET and POST requests. If it's a GET request,
you wouldn't have a last selected thing, so it's set to an
empty string. If it's a POST request, we fetch the selected
thing and return the same template with the pre-selected
thing.
You can improve on this and save the last selected thing
into the session data and attempt to retrieve it from there.
"""
thing = ''
if request.method == 'GET':
return render_template('things.html', thing=thing)
else:
thing = request.form.get('thing', '')
return render_template('things.html', thing=thing)
if __name__ == '__main__':
app.run(port=PORT)
The important part is rendering the page with selected in your desired option:
<option value="Foo" selected>Foo</option>
double_j's answer to use templates to insert it into your html works great, but if you're building the dropdown from a list it may be easier to build your html from python:
import flask
import socket
app = flask.Flask(__name__)
all_things = ['Foo', 'Bar', 'Fizz', 'Buzz']
current_thing = None
def show_selection(target):
if target == current_thing:
return 'selected'
else:
return ''
def menu():
template = '''<form action = "things" method = "post">
<select id="target" name="target">
{targets}
</select>
<input type="submit" name="build" value="Build">
</form>
'''
# vvv This is the important part vvv
targets = [f'<option value="{t}" {show_selection(t)}>{t}</option>' for t in all_things]
return template.format(
targets='\n'.join(targets)
)
# ^^^ This is the important part ^^^
#app.route('/things', methods=['GET', 'POST'])
def things():
global current_thing
current_thing = flask.request.form.get('target')
page = menu()
if flask.request.method == 'POST' and 'build' in flask.request.form:
page += f'Building {current_thing}'
else:
page += 'Press Build button'
return page
if __name__ == '__main__':
PORT = 8080
print("Visit http://{}:{} to trigger builds".format(socket.gethostname(), PORT))
app.run(host='0.0.0.0', port=PORT, debug=True)
try this, if you have not already
{% if thing == "Foo" %}
<option value = "Foo" name ="Foo" id="Foo" selected>Foo</option>
<option value = "Bar" name ="Bar" id="Bar">Bar</option>
{% elif thing == "Bar" %}
<option value = "Foo" name ="Foo" id="Foo">Foo</option>
<option value = "Bar" name ="Bar" id="Bar" selected>Bar</option>
{% endif %}
Good evening to everyone who reads this post.
I want to add a select box to my web site in flask, but i can not understand how to set up html for that
I look forward to see any comments and suggestions :)
My python code:
class selectmenu(Form):
month = SelectField('Choose month',choices=[('dec', 'dec'), ('yan', 'yan'), ('feb', 'febt')])
#app.route('/searchemp/', methods=['GET', 'POST'])
def searchemp():
form = selectmenu(request.form)
m = form.month.data
HTML:
<form action="" class="form-signin" method="post">
<h2 class="form-signin-heading" align="center">title</h2>
<input type="text" class="form-control"
placeholder= "username" name="username" value="{{request.form.username}}" required autofocus>
<!--
<input type="text" class="form-control"
placeholder= "month" name="month" value="{{request.form.month}}">
-->
<select name="month">
<option value="{{request.form.month}}">dec</option>
<option value="{{request.form.month}}">yanuary</option>
<option value="{{request.form.month}}">feb</option>
<option value="{{request.form.month}}">mar</option>
</select>
<button class="btn btn-lg btn-success btn-block" type="submit">Search</button>
<br>
<p align="center">{{error}} </p>
</form>
Jinja2 template engine will render selectfield with choices, you dont have to create a html select field, jinja2 already does. And if you need to check form submission use validate_on_submit() or request.method == 'POST':
class SelectMenu(Form):
month = SelectField('Select Month', choices=[(1, 'January'), (2,'February')])
#app.route('/searchemp/', methods=['GET', 'POST'])
def searchemp():
form = SelectMenu(request.form)
if form.validate_on_submit():
# get posted data
m = form.month.data
return render_template('index.html', form=form)
# index.html
<form action="" method="POST">
{{form.month.label}}{{form.month}}
</form>