I have a Pylons app and am using FormEncode and HtmlFill to handle my forms. I have an array of text fields in my template (Mako)
<tr>
<td>Yardage</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
<td>${h.text('yardage[]', maxlength=3, size=3)}</td>
</tr>
However, I can't seem to figure out how to validate these fields. Here is the relevant entry from my Schema
yardage = formencode.ForEach(formencode.validators.Int())
I'm trying to validate that each of these fields is an Int. However, no validation occurs for these fields.
UPDATE As requested here is the code for the action of this controller. I know it was working as I can validate other form fields.
def submit(self):
schema = CourseForm()
try:
c.form_result = schema.to_python(dict(request.params))
except formencode.Invalid, error:
c.form_result = error.value
c.form_errors = error.error_dict or {}
c.heading = 'Add a course'
html = render('/derived/course/add.html')
return htmlfill.render(
html,
defaults = c.form_result,
errors = c.form_errors
)
else:
h.redirect_to(controler='course', action='view')
UPDATE
It was suggested on IRC that I change the name of the elements from yardage[] to yardage
No result. They should all be ints but putting in f into one of the elements doesn't cause it to be invalid. As I said before, I am able to validate other form fields. Below is my entire schema.
import formencode
class CourseForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
name = formencode.validators.NotEmpty(messages={'empty': 'Name must not be empty'})
par = formencode.ForEach(formencode.validators.Int())
yardage = formencode.ForEach(formencode.validators.Int())
Turns out what I wanted to do wasn't quite right.
Template:
(Should have made it in a loop to begin with.) You'll notice that the name of the first element will become
hole-1.yardage. I will then useFormEncode.variabledecodeto turn this into a dictionary. This is done in theSchema:
The HoleSchema will validate that
hole-#.parandhole-#.yardageare both ints and are not empty.formencode.ForEachallows me to applyHoleSchemato the dictionary that I get from passingvariable_decode=Trueto the@validatedecorator.Here is the
submitaction from myController:
Using the
@validatedecorator allows for a much cleaner way to validate and fill in the forms. Thevariable_decode=Trueis very important or the dictionary will not be properly created.