2

I have a form with dynamically added rows that have the same name. I try to use getlist but I only get the first value.

Here is my HTML form code:

<html>
<div>
   <form method=POST>
</div>
<table id="linkTable">
    <tbody><tr class="tr_clone" id="addrow">
        <td>First: </td>
        <td><input class="from-field" id="from" type="text" name="first"></td>
        <td>Last: </td>
        <td><input class="to-field" id="to" type="text" name="last"></td>
        <td>Email: </td>
        <td><input class="port-field" id="ports" type="text" name="email"></td>
    </tr>
</tbody></table>
<script>
    $("#addbtn").click(function(){
        $("#addrow").clone().find("input:text").val("").end().prependTo("#linkTable");
    })
</script>
</form>
</html>

Here is my python code:

from flask import Flask, request, render_template

for arg in request.form:
    print arg, request.form.getlist(arg)

Can anyone explain that even if I use getlist, I only get the first value?

Thanks in advance

Youn Elan
  • 2,379
  • 3
  • 23
  • 32
  • Because you can't have multiple inputs with the same name... – Tewdyn May 03 '18 at 04:11
  • in php, I used to do that all the time, all I had to do was to add brackets next to the field name [] and values would be put inside an array. From the documentation, I read you use form.getlist instead of from.get but it does not work. Thanks – Youn Elan May 03 '18 at 11:48

2 Answers2

4

It's convenient to use zip() every time you want to parse same name attribute in html. Have a look at this:

@app.route('/creation', methods=['GET', 'POST'])
def create():
    try:
        if request.method == 'POST':
            for first, last, email in zip(request.form.getlist('first'),
                                          request.form.getlist('last'),
                                          request.form.getlist('email')):
                print(first, last, email)
        else:
            return render_template('create.html')
    except Exception as e:
        print(str(e))
Ninja Warrior 11
  • 362
  • 3
  • 17
  • Though it turned out to be a different issue (wrongly closed form tag), I really like the zip method so I upvoted it. Thanks – Youn Elan May 08 '18 at 20:33
0

After looking for a long time, was able to answer my own question by looking on the web.

I had the following:

<html>
<!-- note how the form has been moved out of the div so that the navigator does not close the div -->
<form method=POST>
<table id="linkTable">
    <tbody><tr class="tr_clone" id="addrow">
        <td>First: </td>
        <td><input class="from-field" id="from" type="text" name="first"></td>
        <td>Last: </td>
        <td><input class="to-field" id="to" type="text" name="last"></td>
        <td>Email: </td>
        <td><input class="port-field" id="ports" type="text" name="email"></td>
    </tr>
</tbody></table>
<script>
    $("#addbtn").click(function(){
        $("#addrow").clone().find("input:text").val("").end().prependTo("#linkTable");
    })
</script>
</form>
</html>

It turns out that closing a div will close a form tag so rows were being dynamically added outside the form. By moving the form directive outside of the div, I started getting multiple values when the form was submitted

I also eventually found a more detailed answer at Form Issue (closing itself early in table)

Youn Elan
  • 2,379
  • 3
  • 23
  • 32