WTForms: How to select options in SelectMultipleField?
Asked Answered
M

5

25

Choices can be set using form.myfield.choices=[("1","Choice1"), ("2","Choice2")]

What is the way to set the selected option?

Malay answered 1/4, 2011 at 22:57 Comment(0)
B
33

You can use the choices and default keyword arguments when creating the field, like this:

my_choices = [('1', 'Choice1'), ('2', 'Choice2'), ('3', 'Choice3')]

SelectMultipleField(choices = my_choices, default = ['1', '3'])

This will mark choices 1 and 3 as selected.


Edit: Default values are apparently processed (copied into the data member) when the form is instatiated, so changing the default afterwards won't have any effect, unless you manually call process() on the field. You could set the data -member, like so:

form.myfield.data = ['1', '3']

But I'm not sure if either of them is a good practice.


Edit: In case you want to actually set the data and not the default, you should probably use the form to load the data.

Form objects take formdata as the first argument and use that to automatically populate field values. (You are supposed to use a dictionary wrapper with a getlist -method for that)

You can also use keyword arguments to set the data when creating the form, like this:

form = MyForm(myfield = ['1', '3'])
Burrow answered 1/4, 2011 at 23:38 Comment(5)
@Malay You are absolutely correct. I did test it, but apparently I read the wrong html output, sorry. Apparently defaults are handled in field.process() when the form is created, so I think you should just feed the data in when initializing the form. I updated the answer again.Burrow
@AleksiTorhamo, Even after 3 years I think this is still the solution even for the latest WTForms. But, form.field.data = [1, 2, 3] doesn't seem to render the output with those options as selected.Voyeur
Four years later, I find that although form.field.data = [1,2,3] does not work, form.field.process_data([1,2,3]) does the trick. Handy if your defaults are not fixed but instead depend on values from a database or something.Alkyl
@KBN, @eaj, add coerce=int to your SelectMultipleField and then form.field.data = [1, 2, 3] will work.Serval
The default=[...] argument in the field constructor worked for me. I'm on flask_wtf.__version__ = '0.14.2'Antoinetteanton
F
19

This is what worked for me on a SelectField:

form.myfield.default = '1'
form.process()

I'm guessing you can just assign a list to form.myfield.default for a SelectMultipleField. The key, though, seems to be calling the process method on the form after you assign to default.

Ferguson answered 27/4, 2012 at 18:43 Comment(2)
@krupan, your answer is cool, it worked for me. Thanks for showing this.Camelopardus
Yes, needs process()Delapaz
S
5

This is what worked for me (with a dynamic multi select field):

form  = MyForm(request.form, obj=my_obj)
form.tags.choices = [('1', 'abc'), ('2', 'def')]
form.tags.default = ['1', '2']
form.tags.process(request.form)

If I just call form.process(), it loses the default values for the other fields in my form.

Scurrility answered 4/9, 2015 at 4:45 Comment(0)
P
1

None of these answers worked for me (WTForms 2.2); all of them led to the same issue. When I submitted data via a POST request, the values I set as defaults (whether by .default, .data, .process_data(), or .process()) would be returned to my controller regardless of edits I made to the values in the form in the browser.

To resolve this, I passed the request type back to my controller and if it was a POST request, I skipped past the part where I set the default values.

form = controller.getForm(request= request.method)

and in the controller where I handled the submission,

getForm(request="")
# ...
if request != "POST":
    # Set the default values for the form
else:
    # Go straight to validating the form data 
Plovdiv answered 25/10, 2018 at 19:29 Comment(0)
J
0

Cheers guys for your help. I tried the last answer and it did not work for me. With a call to the process method it works and what you can do is just use it and pass to its data argument the data you don't want to be reset. So something like this:

    form.process(data={k: v for k, v in request.form.items() if 
    k=='your_form_item_name'})
Jacobjacoba answered 18/7, 2017 at 13:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.