Pre-populating a BooleanField as checked (WTForms)
Asked Answered
G

8

20

For the life of me, I can't figure out how to pre-populate a BooleanField with WTForms. I have a field called "active". It defaults to being not checked, and it's not required. So I set it up like...

class QuestionForm(Form):
    question = TextField('Question', [validators.Required()])
    slug = TextField('Slug', [validators.Required()])
    active = BooleanField('Active')

Then I have an EDIT PAGE where I display a form for the 'question' I want to edit.

{{ form.question.label }}
{{ form.question(value=q.question) }}

{{ form.active(value=q.active) }} Show this question?

If 'active' is True, I'd like the BooleanField (checkbox) to have the 'checked' attribute. And if False, not to. But I can't even figure out how to make the checkbox have a checked state, when rendering the form, let alone the conditional part.

The only way, I've been able to get it to show up checked is if I add default=True when defining the form. But that's not what I need.

I've tried using 'default', 'initial', 'value', 'selected' while rendering the form with no luck. And I've searched the docs and Google. I think I'm missing something! :)

UPDATE

Here's what my view looks like. Maybe it is the problem?

@mod.route('/q/<slug>/edit', methods = ['GET', 'POST'])
def edit(slug):
    form = QuestionForm(request.form, csrf_enabled=False)
    q = Question.query(Question.slug==slug).get()
    if request.method=='POST':
        if form.validate_on_submit():
            q.question = form.data.get('question')
            q.slug = form.data.get('slug')
            q.active = form.data.get('active')
            q.put()
            return redirect('/questions')
    return render_template('questions/edit.html', form=form, q=q)
Gleda answered 3/11, 2013 at 21:4 Comment(0)
K
13

If you have an object you can use it to populate your form like form = QuestionForm(obj=my_obj). If you only want to set the active attribute use form = QuestionForm(active=True).

Karleen answered 3/11, 2013 at 21:39 Comment(5)
I added my view to the question. I think I'm doing it right. Or do I need to use the 'q' object when defining my form? Is that what you're saying?Gleda
Yes, use your q object. form = QuestionForm(request.form, csrf_enabled=False, obj=q)Karleen
Ahhhhhh. It all makes sense now! You're a genius!Gleda
This worked for me, but only when I removed the other bits; form = QuestionForm(formdata=request.form, obj=result) didn't fill the checkbox properly, but QuestionForm(obj=result) did!Halliehallman
The proposed solution worked for me: QuestionForm(active=True). In my case the solution did not work as I was passing variables and the variable was of type string instead of bool, causing this solution to not work. Cast the variable to bool first and then this solution works as a charm.Unbelief
S
12

A BooleanField defined like:

checkbox = BooleanField('title',
              default=True,
              render_kw ={'checked':''})
Slung answered 4/4, 2020 at 15:59 Comment(3)
Both default=True and default="checked" worked for me. I didn't need the render_kw part, can you elaborate why that would be necessary?Unbelief
Hello, as far as I remember I have added the Checkbox label for the checkbox to be selected.<input **checked** type="checkbox">Preter
only the render_kw={"checked": ...} worked here, didn't even need the default partWrongheaded
P
8

snahor's answer helped after much searching (+1). The google seems weak on this question. I found I needed

<div class="form-group">
  {{adminForm.is_admin.label}}
  {{adminForm.is_admin(checked=True, class_="form-control")}}
</div>

<div class="form-group">
  {{adminForm.is_admin.label}}
  {{adminForm.is_admin(checked=False, class_="form-control")}}
</div>

which I have utilised as

<div class="form-group">
  {{adminForm.is_admin.label}}
  {{adminForm.is_admin(checked=user.is_admin, class_="form-control")}}
</div>
Parsifal answered 27/4, 2015 at 22:37 Comment(2)
This is only thing that worked for me with Flask 0.12 and WTForms 2.1Muscular
"The google seems weak on this question." Yes, b/c the web it broken.Alcorn
H
2

To have the default boolean value as True, you need to set the default to "checked"

Basic fields Basic fields generally represent scalar data types with single values, and refer to a single input from the form.

class wtforms.fields.BooleanField(default field arguments, false_values=None)

Represents an input type="checkbox". Set the checked-status by using the default-option. Any value for default, e.g. default="checked" puts checked into the html-element and sets the data to True

Source

class QuestionForm(Form):
    question = TextField('Question', [validators.Required()])
    slug = TextField('Slug', [validators.Required()])
    active = BooleanField('Active', default="checked")
Hysteresis answered 28/7, 2018 at 21:21 Comment(0)
G
2

None of these solutions worked for me. There seems to be a bug in WTForms that has not been fixed.

Instead, when the route is called I set the value of the Boolean field after I have initialised the form. This works for me

form = GameCreateForm(request.form)
form.allow_comments.data = True
Gustaf answered 21/5, 2020 at 20:37 Comment(0)
L
2

I had the same problem, and after hours of searching and reading, the solution was very simple.

form = forms.TestForm(request.form)
form.yourbooleanfield.checked = YourVariable

if request.method=="POST" and form.validate():
    print(form.yourbooleanfield.data)
Leathers answered 30/6, 2020 at 19:5 Comment(1)
Uhh I don't think that's a great solution. I mean you could put the setting of checked AFTER your if statement up there. Because if you don't do that it'll always be set to YourVariable and it won't matter what the user put in...Lemniscate
A
0

In addition to specifying in the template, you can likewise specify in the class definition

class QuestionForm(Form):
    question        = TextField('Question', [validators.Required()])
    slug            = TextField('Slug'    , [validators.Required()])
    activeChecked   = BooleanField('Active', default=True  )
    activeUnChecked = BooleanField('Active', default=False )
Alula answered 15/7, 2017 at 1:4 Comment(1)
Has no effect for me. Always defaults to falseMuscular
B
0

This worked for me

BooleanField(default="checked")

https://wtforms.readthedocs.io/en/2.3.x/fields/

class wtforms.fields.BooleanField(default field arguments, false_values=None)
Brooklime answered 3/9, 2020 at 0:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.