I think jeverling's answer is very close and led my to a tested solution. I needed items to remain checked, but each time the url is serviced, the checkbox items are cleared unless you can specify the selections.
The important part is ChoiceObj (was MyObj above) inheriting from object so that setattr can be called on it. To make this work, the arguments to setattr(obj, attribute, value) where
- obj is the ChoiceObj instance
- attribute is the name of the form
- value set in the list of choices.
color.py:
from flask.ext.wtf import Form
from flask import Flask, render_template, session, redirect, url_for
from wtforms import SelectMultipleField, SubmitField, widgets
SECRET_KEY = 'development'
app = Flask(__name__)
app.config.from_object(__name__)
class ChoiceObj(object):
def __init__(self, name, choices):
# this is needed so that BaseForm.process will accept the object for the named form,
# and eventually it will end up in SelectMultipleField.process_data and get assigned
# to .data
setattr(self, name, choices)
class MultiCheckboxField(SelectMultipleField):
widget = widgets.TableWidget()
option_widget = widgets.CheckboxInput()
# uncomment to see how the process call passes through this object
# def process_data(self, value):
# return super(MultiCheckboxField, self).process_data(value)
class ColorLookupForm(Form):
submit = SubmitField('Save')
colors = MultiCheckboxField(None)
allColors = ( 'red', 'pink', 'blue', 'green', 'yellow', 'purple' )
@app.route('/', methods=['GET', 'POST'])
def color():
selectedChoices = ChoiceObj('colors', session.get('selected') )
form = ColorLookupForm(obj=selectedChoices)
form.colors.choices = [(c, c) for c in allColors]
if form.validate_on_submit():
session['selected'] = form.colors.data
return redirect(url_for('.color'))
else:
print form.errors
return render_template('color.html',
form=form,
selected=session.get('selected'))
if __name__ == '__main__':
app.run()
And templates/color.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method="post">
<table>
<tr>
<td>
{{ form.hidden_tag() }}
{{ form.colors }}
</td>
<td width="20"></td>
<td>
<b>Selected</b><br>
{% for s in selected %}
{{ s }}<br>
{% endfor %}
</td>
</tr>
</table>
<input type="submit">
</form>
</body>
</html>