[FE-discuss] Conditional validator

Top Page
Author: Christoph Haas
Date:  
To: formencode-discuss
Subject: [FE-discuss] Conditional validator
Dear list,

for a few days I'm struggling with a way to validate my HTML form with
Formencode and Pylons' @validate decorator. The fancy part of my form is
that the set of fields that are submitted depend on one field. Let me
tell you what I'm about to do.

My application allows to create DNS entries. There are different types
of entries like A (address), PTR (pointer), MX (mail exchanger) and so
on. Each type needs different fields filled:

A: type='A'
     name (a hostname with a domain)
     content (an IP address)
     ttl (the time-to-live)

PTR: type='PTR'
     name (an IP address)
     content (a hostname with a domain)
     ttl (the time-to-live)

MX: type='MX'
     name (a hostname with a domain)
     content (a hostname with a domain)
     ttl (the time-to-live)
     priority (an integer)

So as you can see the set of fields in a validation schema depends on
the "type" variable. Now I'd like to create different schemas and have
formencode use any schema. That's why I thought of Any() first but it
didn't allow me to choose different schemas.

Then Steven Holmes on #pylons suggested to create a new conditional
validator like he describes in http://rafb.net/p/N5k3mz74.html.
But it's also not what I had in mind. Or I'm too stupid to recognize its
beauty.

I'm rather thinking of something like this (pseudo-code):

class ValidateNewA(formencode.Schema):
    type = formencode.validators.OneOf(['A'])
    name = myvalidators.EndsWithExistingDnsZone()
    content = myvalidators.ValidInet()
    ttl_days = myvalidators.IntRange(min=0, max=365, if_empty=0)
    ttl_hours = myvalidators.IntRange(min=0, max=23, if_empty=0)
    ttl_minutes = myvalidators.IntRange(min=0, max=59, if_empty=0)
    ttl_seconds = myvalidators.IntRange(min=0, max=59, if_empty=0)

class ValidateNewPTR(formencode.Schema):
    type = formencode.validators.OneOf(['PTR'])
    name = myvalidators.ValidInet()
    content = myvalidators.EndsWithExistingDnsZone()
    ttl_days = myvalidators.IntRange(min=0, max=365, if_empty=0)
    ttl_hours = myvalidators.IntRange(min=0, max=23, if_empty=0)
    ttl_minutes = myvalidators.IntRange(min=0, max=59, if_empty=0)
    ttl_seconds = myvalidators.IntRange(min=0, max=59, if_empty=0)

And now the actual validator I would use with @validate:

class ValidateNew(formencode.Schema):
    .... = myvalidators.If(type, 'A', ValidateNewA)
    .... = myvalidators.If(type, 'PTR', ValidateNewPTR)

I'm just not sure how to express that because there is no "...."
variable I'd use. Would I have to use the chained_validators for "...."?
Would I write a compound validator called "If" that works similar to
Any() or All()?

Hints welcome. If there is no sane way to do this fancy validation with
formencode I could as well use different Pylons actions and use
different @validate calls.

 Christoph


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
FormEncode-discuss mailing list
FormEncode-discuss@???
https://lists.sourceforge.net/lists/listinfo/formencode-discuss