Skip to content

Instantly share code, notes, and snippets.

@ectrimble20
Created May 12, 2018 23:56
Show Gist options
  • Save ectrimble20/468156763a1389a913089782ab0f272e to your computer and use it in GitHub Desktop.
Save ectrimble20/468156763a1389a913089782ab0f272e to your computer and use it in GitHub Desktop.
Multiple Checkboxes using Flask WTForms
{% extends "layout_new.html" %}
{% block content_main %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">User Choices</legend>
{% if form.choices.errors %}
<div class="invalid-feedback">
{% for error in form.choices.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% endif %}
{% for choice in form.choices %}
<div class="form-check">
{{ choice(class="form-check-input") }}
{{ choice.label(class="form-check-label") }}
</div>
{% endfor %}
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content_main %}
class MultiCheckboxField(SelectMultipleField):
widget = widgets.ListWidget(prefix_label=False)
option_widget = widgets.CheckboxInput()
class ExampleForm(FlaskForm):
choices = MultiCheckboxField('Routes', coerce=int)
submit = SubmitField("Set User Choices")
@example.route("/example", methods=["GET", "POST"])
def example():
form = ExampleForm()
# populate the forms dynamically with the choices in the database
form.check_options.choices = [(c.id, c.desc) for c in Choices.query.all()]
# if it's a post request and we validated successfully
if request.POST and form.validate_on_submit():
# get our choices again, could technically cache these in a list if we wanted but w/e
c_records = Choices.query.all()
# need a list to hold our choices
accepted = []
# looping through the choices, we check the choice ID against what was passed in the form
for choice in c_records:
# when we find a match, we then append the Choice object to our list
if choice.id in form.check_options.data:
accepted.append(choice)
# now all we have to do is update the users choices records
user.choices = accepted
db.session.add(user)
db.session.commit(user)
else:
# tell the form what's already selected
form.choices.data = [c.id for c in user.choices]
return render_template('example.html', form=form)
user_choices = app_db.Table('user_choices',
app_db.Column('user_id', app_db.Integer, app_db.ForeignKey('user.id'), primary_key=True),
app_db.Column('choice_id', app_db.Integer, app_db.ForeignKey('choice.id'), primary_key=True)
)
class User(db.Model, UserMixin):
id = app_db.Column(app_db.Integer, primary_key=True)
# other stuff as required
choices = db.relationship('Choices', secondary=user_choices, lazy='subquery'
backref=db.backref('users_choice', lazy=True))
class Choices(db.Model):
id = app_db.Column(app_db.Integer, primary_key=True)
desc = app_db.Column(app_db.String(25), nullable=False)
@ogost
Copy link

ogost commented May 18, 2020

Very useful, thank you!

@Nurou
Copy link

Nurou commented Jun 14, 2020

This was helpful. Thanks!

@cooneycw
Copy link

Can't say enough about how much this helped me! As a note to others, I had to import "widgets" from wtforms.

@evereux
Copy link

evereux commented Oct 11, 2020

# tell the form what's already selected
form.choices.data = [c.id for c in user.choices]

Thanks! 👍

@MarkhorMountain
Copy link

Very valuable. Thanks a lot!

@BonaFideBOSS
Copy link

How to set attributes (key and value) to each checkbox?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment