I'm starting in flask, so i have many questions about it. And one of them is how to create an array based on name of the checkbox input?
In other words, python will follow the logic: for each of type "checkbox", which ones were filled?
I have those codes:
index.html
{% block content %}
<form method="POST" action="">
<div class="card" style="margin:50px 0">
<div class="card-header"><b>Letters</b></div>
<ul class="list-group list-group-flush">
<li class="list-group-item">A
<label class="switch ">
<input type="checkbox" name="A" class="danger">
<span class="slider round"></span>
</label>
</li>
<li class="list-group-item">B
<label class="switch ">
<input type="checkbox" name="B" class="danger">
<span class="slider round"></span>
</label>
</li>
<li class="list-group-item">C
<label class="switch ">
<input type="checkbox" name="C" class="danger">
<span class="slider round"></span>
</label>
</li>
</ul>
<button type="submit">Go</button>
</div>
</form>
{% endblock content %}
And funcs.py
from flask import Flask, render_template, url_for, redirect, request
app = Flask(__name__)
app.config['SECRET_KEY'] = '0000'
#app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
When the user has checked boxes named "A" and "C", python creates an array and display the array shortly afterwards when the user submit.
checked = ["A", "C"]
Your HTML is heading in the right direction, but a few minor changes for Flask to handle this effectively.
First, set the current value of the name attribute to the value attribute. This will determine values Flask pulls during the form post. Secondly, set the name attribute to have a common value.
<input type="checkbox" value="A" class="danger" name='my_checkbox'>
<input type="checkbox" value="B" class="danger" name='my_checkbox'>
<input type="checkbox" value="C" class="danger" name='my_checkbox'>
After the HTML is configured as such, you can use the getlist method from Flask's request module.
print(request.form.getlist('my_checkbox'))
>>> ['A', 'C']
When a POST request is sent to the flask server you can get form contents from request.form. which is a dictionary based off of the POST request.
With check boxes, if the box is ticked the input name in <input type="checkbox" name="A" class="danger"> would be in this dictionary. Therefore you can check for the check box like so:
if "A" in request.form:
checked.append("A") # You can of course append any arbitrary value
Related
I am making a website that has a submit button and multiple input fields in different divs. I am using Flask to make the website, and I want to log what is submitted from those input fields into separate variables, to eventually be stored in a database. My problem is that whenever I press the submit button, it only works with one text box, the one closest to it in the HTML.
This is the Flask code for getting the text from the input box:
#app.route('/', methods=["GET", "POST"])
def home():
if request.method == "POST":
name = request.form.get("name")
notes = request.form.get("notes")
print(notes)
return render_template("messaging.html")
Here's the HTML for the actual inputs and submissions:
<div class="content">
<div class="page-top">
<input type="text" class="user-input-box" id="name" name="name" placeholder="Name" autocomplete="off">
</div>
<div class="user-input" id="user-input">
<input type="text" class="user-input-box" name="notes" placeholder="Notes" autocomplete="off">
</div>
<button type="submit" class="message-send">Send</button>
</div>
It only works with the notes input box, not the name.
If you can help that would be great, sorry if the code isn't very good I'm new to HTML and Flask. Thanks!
any time you use button with type "submit", must use form. and button can submit your form.
Watching some HTML tutorials won't be a bad idea if you faced a challenge in forms.
<form id="form1" action="/yourRoute" method="POST"></form>
<div class="content">
<div class="page-top">
<input type="text" class="user-input-box" id="name" name="name" placeholder="Name" autocomplete="off">
</div>
<div class="user-input" id="user-input">
<input type="text" class="user-input-box" name="notes" placeholder="Notes" autocomplete="off">
</div>
<button type="submit" class="message-send">Send</button>
</div>
</form>
I'm trying to add a comment section to my web app however, I want to know which book its "add comment" has clicked I'm thinking about getting the book's ID.
Here is my python
#app.route("/comment", methods=["GET", "POST"])
def comment():
if request.method == "POST":
if not request.form.get("comment"):
return apology("must provide comment", 400)
book = request.form.get("book_id")
print(session["user_id"])
print(book)
id = session["user_id"]
print(id)
user = db.execute("SELECT username FROM users WHERE id=?", id)
db.execute("INSERT INTO comment (comment, user,book_id) VALUES(?, ?,?)", comment, user,book)
return render_template ("index.html")
else:
return render_template ("comment.html")
Here is my html code
<form action="/comment" method="get">
<div class="container">
<div class="row g-3">
{% for book in books %}
<div class="col-12 col-md-6 col-lg-4">
<div class="card">
<img src="{{book.volumeInfo.imageLinks.smallThumbnail}}">
<div class="card-body">
<h5 style="color:red" class="card-title">{{book.volumeInfo.title}}</h5>
<p style="color:blue" class="card-text">{{book.volumeInfo.authors}}</p>
<p style="visibility:hidden" class="card-text">{{book.id}}</p>
<input name="book" style="visibility:hidden" class="form-control mx-auto w-auto" name="book_id" value="{{book.id}}" type="text">
More Info
<button value="{{book.id}}" class="btn btn-primary">add comment</button>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
This HTML element
<input name="book" style="visibility:hidden" class="form-control mx-auto w-auto" name="book_id" value="{{book.id}}" type="text">
has two different values for attribute name, please try removing one of them, that is
<input name="book_id" style="visibility:hidden" class="form-control mx-auto w-auto" value="{{book.id}}" type="text">
and then write if you can access book_id properly in your Flask application. As side if you need to have input invisble to user you might use type="hidden" rather than tinker with styling, in this case
<input name="book_id" value="{{book.id}}" type="hidden">
I have two forms on my page, each with its own fields and submit button, but whenever I use any of them, they always check the overall page fields instead of just the form they're contained in...
The simulator.html has two forms, the first one is this:
<div class="forms">
<div class="form-1">
<form method="post" action="{{ url_for('core.simulator') }}">
<div class="container">
<div class="row g-3">
<div class="col-sm-3">
<label class="form-label"><b>Capital:</b></label>
<input type="text" class="form-control" name="capital_html" required>
</div>
<div class="col-sm-3">
<label class="form-label"><b>Price:</b></label>
<input type="text" class="form-control" name="price_html" required>
</div>
</div>
</div>
<br>
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
<button id="btn" type="submit" class="btn btn-info">Launch simulation!</button>
</div>
</form>
<br>
<p>Units to purchase: <b>{{simulation_units}}</b>
</div>
</div>
And the second one is this:
<h3> Screener</h3>
<div class="forms">
<div class="form-2">
<form method="post" action="{{ url_for('core.simulator') }}">
<div class="container">
<div class="row g-3">
<div class="col-sm-3">
<label class="form-label"><b>Ticker:</b></label>
<input type="text" class="form-control" name="ticker_symbol_html" placeholder="Enter Ticker Symbol" required>
</div>
</div>
</div>
<br>
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
<button id="btn" type="submit" class="btn btn-info">Launch!</button>
</div>
<p>Symbol <b>{{simulation_symbol}}.
</form>
</div>
</div>
The views.py file has the back-end code for each, the first one is this:
def capital_simulator():
if request.method == 'POST':
simulation_capital = request.form.get('capital_html', '')
simulation_price = request.form.get('price_html', '')
try:
simulation_units = math.floor(float(simulation_capital) / float(simulation_price))
except KeyError:
simulation_units == 0
return render_template('simulator.html',form1=form,capital_html=simulation_capital,price_html=simulation_price,simulation_units=simulation_units)
And the second form back-end script is this:
def screener():
if request.method == 'POST':
ticker_symbol = request.form.get('ticker_symbol_html', '')
return render_template('simulator.html',ticker_symbol=ticker_symbol_html,ticker_symbol=simulation_symbol)
I thought by specifically calling the mentioned fields and containing them into forms classes, I would avoid an overall validation, but right now I'm failing to make the submit button focus on their own forms. How can I fix this, please?
You have two forms. One is within the 'form-1' div. One is within the 'form-2' div. Each one has its own <form> and </form> tags, which means they are separate forms. The first form contains two <input> fields: one called capital_html, one called price_html, and a button called btn. The second form has one <input> field called ticker_symbol_html and a button called btn.
Let's say the user fills in the first two fields and clicks the first button. That's going to send a request to whatever the URL is in the <form> tag. In the data, it will send three things:
capital_html=xxx
price_html=yyy
btn=submit
That's it. That's all you get. You don't get any fields from the other form. If the user clicks the other form, all you will get is
ticker_symbol_html=xxx
btn=submit
The problem, as you can see, is there's no easy way for you to tell which form was submitted. If you have to use the same URL for both, the usual way to solve this is to add a hidden field that gets sent with the data, like:
<input type=hidden name="ident" text="form1">
and in the second one:
<input type=hidden name="ident" text="form2">
Now, your handler can say
if request.form.get("ident") == "form1":
# Go handle first form.
else:
# Go handle second form.
I am learning Flask for the first time so I created a basic application of adding names into an unordered list. The names which is inserted are taken input in a input field. Basically when I didn't add Bootstrap it was working fine but when I added Bootstrap it is doing nothing when I click the button.
Code when no Bootstrap
<form action="{{ url_for('index') }}" method="POST">
<input type="text" name="name" placeholder="Enter your name" style="border-radius: 20px;">
<button>Click Me!</button>
</form>
<ul>
{% for item in task %}
<li> {{ item }} </li>
{% endfor %}
</ul>
Code when Bootstrap added :
<form action="{{ url_for('index') }}" method="POST">
<div class="input-group col-lg-10 col-sm-6">
<input type="text" name="name" class="form-control" placeholder="Enter your name"
style="border-radius: 20px;">
<span class="input-group-btn">
<button class="btn btn-primary" type="button">Click Me!</button>
</span>
</div>
</form>
<ul>
{% for item in task %}
<li> {{ item }} </li>
{% endfor %}
</ul>
This is my application.py :
from flask import Flask
from flask import render_template,request
app = Flask(__name__)
task=[]
#app.route("/",methods=["GET","POST"])
def index():
if request.method=="POST":
name = request.form.get("name")
task.append(name)
return render_template("index.html",task=task)
Your problem probably is not Bootstrap but type="button".
If you use type="button" in <button> even without Bootstrap then you have the same problem.
You have to remove it or use type="submit".
In <button> you can use only
type="submit" to send form to server
type="reset" to clear form (without sending to server)
type="button" to create clickable button but it doesn't send to server and you can assign JavaScript code which run some function after clicking.
BTW: I'm not sure but maybe Bootstrap has some JavaScript file which you has to link in HTML to change button behavior when you use type="button".
Minimal working example
from flask import Flask
from flask import render_template_string, request
app = Flask(__name__)
#app.route("/", methods=["GET","POST"])
def index():
if request.method=="POST":
name = request.form.get("name")
print(name)
return render_template_string("""<form action="{{ url_for('index') }}" method="POST">
<input type="text" name="name" placeholder="Enter your name">
<br>
<button>Button without Type</button>
<br>
<button type="submit">Button type="Submit"</button>
<button type="reset">Button type="Reset"</button>
<button type="button">Button type="Button"</button>
<button type="button" onclick="alert('Clicked')">Button type="Button" with JavaScript</button>
<br>
<input type="submit" value='Input type="Submit"'/>
<input type="reset" value='Input type="Reset"'/>
<input type="button" value='Input type="Button"'/>
<input type="button" onclick="alert('Clicked')" value='Input type="Button" with JavaScript"'/>
</form>""")
app.run()
Doc: < button >, < input >
Change <button> to <input type=“submit” value=“Click Me! />. You can add whatever bootstrap classes you want to style this submit input like a button.
<form method="post" class="form-horizontal" role="form">
<div class="btn-group col-sm-3">
<button id="typeSelect" type="button" name="reportType" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
People <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>
...
</li>
...
</ul>
</div>
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">Name</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="inputName" placeholder="Name" name="name" value="{{name}}" onblur="isEmpty(this)">
</div>
</div>
</form>
I have two inputs in my form and I am trying to get the input in my Python code.
report_type = self.request.get('reportType')
name = self.request.get('name')
name is working correctly, but report_type will always be None.
What is the correct way to retrieve the selection in a button (Bootstrap)?
According to the button element specifications:
A button (and its value) is only included in the form submission if the button itself was used to initiate the form submission.
You will have to find another way to pass the value of the button. You could, for example, store the value in a hidden field.