0
votes

I'm new to flask and WTForms so sorry in advance.

Anyways, I'm trying to create multiple forms using the same form defined below in forms.py

File_Choices = [('1', 'ex1.pdf'), ('2', 'ex2.pdf')
class Inputs(Form):
    Files = SelectField(u'File', choices=File_Choices,validators =[Required()])

I am familiar with the fact that I have to declare something along the lines of: form1=Inputs() to declare a form in the views.py, however the problem arises when I need to declare an unknown amount of forms and track the selected values.

My specific problem is that I have a list that contains N elements and each element has to correspond to a file that the user selects from the form. So I've broken down my problem to just creating N number of forms first and thought about using a for loop like this:

for i in range(len(PDF_list))
    form'i'=Input()

So the end product if the length of the list is 5, is 5 Input forms declared as form1, form2, form3, form4, form5. I know this obviously doesn’t work the way I just coded it but that's the functionality I'm trying to get so I can still access the submitted values using something like

dict(File_Choices).get(form'i'.Files.data).

Theres probably a really obvious way to do this however, I'm new to using flask and WTForms so any help is appreciated and in your solution if you could explain step by step what you're doing since I'm new, that would be awesome.

1

1 Answers

2
votes

I believe what you want is FieldList.

So you'd have something like:

from wtforms.fields import FieldList

file_choices = [('1', 'ex1.pdf'), ('2', 'ex2.pdf')
class Inputs(Form):
    files = FieldList(
        SelectField(u'File', choices=file_choices, validators =[Required()]),
        min_entries = N
    )

min_entries specifies how many "SelectFields" should be present on the form. This way you have one form with multiple dropdown select fields each having the same list of file_choices.

In your template file, you could output all the select fields like this (this will display all N selectfields:

<html>
    <form action="" method=post>
        {{ form.files }}
        <input type="submit" />
    </form>
</html>

You could also iterate over form.files and style each SelectField individually

Now when your form is posted, you can access each SelectField by iterating over form.files like so:

for select_field in form.files:
    print(select_field.data)

You can also access SelectField using an index. To access the third SelectField:

form.files[2].data

will return '1' or '2' depending on which file the user selected in that SelectField