'Using <input> inside for loop in jinja flask
I am struggling to figure out how to access individual <input>
elements, that have been created through a for loop. For example:
<form id="score" method="POST" action="/div">
<div class="formInput">
{% for i in range(2) %}
<input type="text" class="sFixed" id="scoreFixed">
{% endfor %}
</div>
</form>
As you can see, I'm creating two input
element's in my form. However, if I try to retrieve the data that I have entered through my Python Flask application, I am only able to get the first input, not the second.
Here is how I am trying to retrieve the data.
@app.route('/div', methods=['POST'])
def div_post():
scoreFixed = request.form.get('scoreGame')
print(scoreFixed)
return redirect('/')
Please help me figure out how to retrieve the input from both elements that have been created in the form.
Solution 1:[1]
Every id
can only exist once in a html document or form. You can set unique ids by using the for loop index in your template. Also you need to give each input
a unique name
{% for i in range(2) %}
<input
type="text"
class="sFixed"
id="scoreFixed_{{i}}"
name="scoreFixed_{{i}}">
{% endfor %}
In your flask endpoint you can then access the scores like this
scores = []
for i in range(2):
score = request.form.get(f"scoreFixed_{i}")
scores.append(score)
Solution 2:[2]
First:
You have to use name=
instead of id=
to get it in Flask
.
I tested it on Python 3.8, Flask 1.1.4 and 2.0.3, Linux Mint 20, browsers Firefox, Chrome, Edge.
In other frameworks/languages you also have to use name=
instead of id=
because browsers send name
but not id
.
Second:
You can use getlist("scoreFixed")
to get list with all elements with the same name.
Of course you can use {{ i }} to add number to name
to get every value separatelly
{% for i in range(2) %}
<input type="text" name="scoreFixed_{{ i }}" ></br>
{% endfor %}
Third:
You need button
to send it.
Minimal working example:
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
print('args :', request.args)
print('form :', request.form)
print('json :', request.json)
print('files:', request.files)
print('scoreFixed getlist():', request.form.getlist("scoreFixed"))
print('scoreFixed get():', request.form.get("scoreFixed"))
print('scoreFixed_0 getlist():', request.form.getlist("scoreFixed_0"))
print('scoreFixed_0 get():', request.form.get("scoreFixed_0"))
print('scoreFixed_1 getlist():', request.form.getlist("scoreFixed_1"))
print('scoreFixed_1 get():', request.form.get("scoreFixed_1"))
return render_template_string('''<form method="POST">
{% for i in range(2) %}
<input type="text" name="scoreFixed" > scoreFixed</br>
{% endfor %}
{% for i in range(2) %}
<input type="text" name="scoreFixed_{{ i }}" > scoreFixed_{{ i }}</br>
{% endfor %}
<button type="submit">SEND</button>
</form>''')
if __name__ == '__main__':
#app.debug = True
app.run()
Result for values a
, b
, c
, d
args : ImmutableMultiDict([])
form : ImmutableMultiDict([('scoreFixed', 'a'), ('scoreFixed', 'b'),
('scoreFixed_0', 'c'), ('scoreFixed_1', 'd')])
json : None
files: ImmutableMultiDict([])
scoreFixed getlist(): ['a', 'b']
scoreFixed get(): a
scoreFixed_0 getlist(): ['c']
scoreFixed_0 get(): c
scoreFixed_1 getlist(): ['d']
scoreFixed_1 get(): d
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |