Skip to content

Instantly share code, notes, and snippets.

@doobeh
Last active June 8, 2023 18:09
Show Gist options
  • Save doobeh/4668212 to your computer and use it in GitHub Desktop.
Save doobeh/4668212 to your computer and use it in GitHub Desktop.
Checkbox WTForms Example (in Flask)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{{ form.hidden_tag() }}
{{ form.example }}
<button type="submit">Submit</button>
</form>
</body>
</html>
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import widgets, SelectMultipleField
SECRET_KEY = 'development'
app = Flask(__name__)
app.config.from_object(__name__)
class MultiCheckboxField(SelectMultipleField):
widget = widgets.ListWidget(prefix_label=False)
option_widget = widgets.CheckboxInput()
class SimpleForm(FlaskForm):
string_of_files = ['one\r\ntwo\r\nthree\r\n']
list_of_files = string_of_files[0].split()
# create a list of value/description tuples
files = [(x, x) for x in list_of_files]
example = MultiCheckboxField('Label', choices=files)
@app.route('/',methods=['post','get'])
def hello_world():
form = SimpleForm()
if form.validate_on_submit():
print(form.example.data)
return render_template("success.html", data=form.example.data)
else:
print("Validation Failed")
print(form.errors)
return render_template('example.html',form=form)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Success</h1>
{{ data }}
</body>
</html>
@insomniac807
Copy link

Yeah I would like to see how it is rendered in the html template. For me the border only surrounds the first option which makes it look very messy. a shame because the rest works beautifully

@Skillz-Interface
Copy link

Thank you

@samuelvarghese
Copy link

Any idea on how the example.html should be structured ? I'm not able to figure it out.

@MarcosMoss
Copy link

what does your Models.py look like?

@adamtongji
Copy link

Thanks a lot!

@1oh1
Copy link

1oh1 commented Apr 19, 2019

example.html

<html>
  <body>
    <form method="post">
      {{ form.csrf_token }}
      {{ form.example }}
      <input type="submit">
    </form>
  </body>
</html>

@shyenatech
Copy link

shyenatech commented Mar 8, 2020

The form.validate_on_submit() does not work in this case. It considers the values as invalid. Hence use form.is_submitted() to make it work.

if form.is_submitted():
print form.example.data
else:
print form.errors
return render_template('example.html',form=form)

@doobeh
Copy link
Author

doobeh commented Mar 9, 2020

@shyenatech-- the code seems (admittedly outdated) but fine, are you sure you're including the csrf token {{ form.hidden_tag() }} to handle the security component? I've updated it for the new version of Flask-WTF here: https://gist.github.com/doobeh/4668212 to give you an idea of how you don't have to skip the important validation step. Good luck!

@MuhammedTech
Copy link

How to query data from db instead of choices=files

@sgarbidonna
Copy link

Hi! How I mark as checked a checkbox? Is for an edit form. Where I need to mark was already marked before on the create

@xelandar
Copy link

Thanks for this code example.

I was struggling with validating the form though. I needed at least one checkbox to be checked. Above comments mentioning form.validate_on_submit() or form.is_submitted() unfortunately didn't help.

After some googling I stumbled on this stackoverflow answer that finally helped.

My final custom validator code:

def validate(self, extra_validators=None):
  if super().validate(extra_validators):
    if not request.form.getlist('example'):
      self.example.errors.append('At least one checkbox must be selected')
      return False
    else:
      return True
      
    return False

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