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)
@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