Reputation: 117
I have a list of members, from a for loop in jinja2 with select and option
I would like to be able to select one of the members from the for loop, and add that member to another list of entries to an event, with the extra options available to the user. (getting the member is easy, from the value of the button, getting the options is the problem)
For example:
Jinja2 Template:
<form method="post" action="add_member_to_list">
<table>
{% for member in members %}
<tr>
<th>{{ member.name }}</th>
<td><input type="checkbox" name="in_out"></td>
<td><select name="day">
<option>Monday</option>
<option>Wednesday</option>
</select>
</td>
<td><button type="submit" name="id" value="{{ member.id }}">Add</button></td>
</tr>
{% endfor %}
</table>
</form>
in Google App Engine - Python
class AddUser(BaseHandler):
def post(self):
in_out = self.request.get("in_out")
id = self.request.get("id")
day = self.request.get("day")
In this scenario, self.response.get("day") only ever returns the option selected for the first iteration of the for loop.
The checkbox; self.request.get("in_out"), returns on or off as expected.
So submitting the nth iteration of the for loop: "Monday" is always returned from select/option.
How can I get the select/option corresponding to the nth iteration of the for loop?
Thanks!
Upvotes: 0
Views: 403
Reputation: 3859
The simplest solution will be to move the form tag into your for loop
<table>
{% for member in members %}
<form method="post" action="add_member_to_list">
<tr>
<th>{{ member.name }}</th>
<td><input type="checkbox" name="in_out"></td>
<td><select name="day">
<option>Monday</option>
<option>Wednesday</option>
</select>
</td>
<td><button type="submit" name="id" value="{{ member.id }}">Add</button></td>
</tr>
</form>
{% endfor %}
</table>
Upvotes: 1
Reputation: 117
I found a quite simple solution for this:
instead of
day = self.request.get("day")
I used
day = self.request.get_all("day")
Which returns a list of all the options from the select, including the option the user choose for the member.
Then, for the Add Button, instead of
<td><button type="submit" name="id" value="{{ member.id }}">Add</button></td>
I assigned the name "loop" and a value of {{ loop.index0}}
so,
self.request.get("loop")
returns the position of the member selected, corresponding the position on the day list of the target. voila.
The member I get from a hidden td instead of from the submit button.
The final code:
<form method="post" action="add_member_to_list">
<table>
{% for member in members %}
<tr>
<th>{{ member.name }}</th>
<td><input type="checkbox" name="in_out"></td>
<td>
<select name="day">
<option>Monday</option>
<option>Wednesday</option>
</select>
</td>
<td class="hidden"><input name="id" value="{{ member.id }}"></td>
<td><button type="submit" name="loop" value="{{ loop.index0 }}">Add</button></td>
</tr>
{% endfor %}
</table>
</form>
class AddUser(BaseHandler):
def post(self):
day = self.request.get_all("day")
id = self.request.get_all("id")
loop = self.request.get("loop")
target_day = day[int(loop)]
target_id = id[int(loop)]
Niiice.
Upvotes: 0
Reputation: 469
So your resulting form has multiple fields with the same name, right?
Like for the first member, there is a and for the second member, there is also a ?
If so, forms don't support that. You have to have a unique name for each field. You'll have to throw in a memberID on each iteration of the loop, or come up with a better design. Something like <select name="day{{member.id}}">
would be a hacky fix.
Another way is you just leave the in_out and day OUT of the for loop, keep it outside.
I hope that helps.
Upvotes: 0