What about a dict? This isn't complete but you get the idea. Would it
break something too?

if isinstance(onvalidation, dict):
    before = onvalidation.get('before',lambda form: None)
    after = onvalidation.get('after',lambda form: None)
    if before:
        before(self)
    if status and after:
        after(self)
elif isinstance(onvalidation, (list,tuple):
    [f(self) for f in onvalidation]
else:
    onvalidation(self)


On Nov 27, 9:37 pm, mdipierro <[email protected]> wrote:
> Ignor my current proposal. It would break something else. Needs more
> thought.
>
> Massimo
>
> On Nov 27, 9:35 pm, mdipierro <[email protected]> wrote:
>
> > Here is my proposal.
>
> > if isinstance(onvalidation,tuple):
> >     use onvalidation[0] as Nathan suggests (pre validation)
> >     use onvalidation[1] as currently used (post validation)
> > else:
> >     everything works as it does now. (post validation only)
>
> > If this works for Nathan, please send me a patch. I do not want to
> > have another config flag for this.
>
> > Massimo
>
> > On Nov 27, 7:03 pm, "mr.freeze" <[email protected]> wrote:
>
> > > Thanks Denes. The example is over-simplified. My actual forms are much
> > > more complex and have many inter-dependencies. It sounds like the
> > > change is not backwards compatible so I will probably just branch
> > > html.py.
>
> > > On Nov 27, 6:02 pm, DenesL <[email protected]> wrote:
>
> > > > ... or just change your catalytic_converter_type requires to
>
> > > > IS_IN_SET(['', 'one','two','three'], zero=None),
>
> > > > and use your code.
>
> > > > On Nov 27, 6:20 pm, DenesL <[email protected]> wrote:
>
> > > > > mr.freeze, you can still use the top part as posted (or similar) and
> > > > > change the bottom to use crud.
>
> > > > > On Nov 27, 5:25 pm, "mr.freeze" <[email protected]> wrote:
>
> > > > > > I want catalytic_converter_type (abbreviated to cc_type below) to be
> > > > > > required for cars after 1975 and be invalid for cars before 1975.
> > > > > > I want to be able to do this:
>
> > > > > > def check_form(form):
> > > > > >     if form.errors.year: return
> > > > > >     if form.vars.year >= 1975:
> > > > > >         if not form.vars.cc_type:
> > > > > >             form.errors.cc_type = 'Required for cars after 1975'
> > > > > >     elif form.vars.cc_type:
> > > > > >         form.errors.cc_type = 'Not valid for cars before 1975'
>
> > > > > > form = crud.create(db.cars,onvalidation=check_form)
>
> > > > > > I can't currently do it because onvalidation will never be called
> > > > > > since validation fails if no cc_type is selected. I know I can hack
> > > > > > around it by switching validators but onvalidation seems like the
> > > > > > proper place for it. It seems like the developer should get a chance
> > > > > > to inspect validation errors but they don't.
>
> > > > > > On Nov 27, 3:19 pm, mdipierro <[email protected]> wrote:
>
> > > > > > > Not sure I understand the test case.
> > > > > > > I do not see how this relevant to the onvalidation issue.
>
> > > > > > > If year>1975 than you want to display and validate the field. If
> > > > > > > year<=1975 you do not want to display the dropbox and/or ignore 
> > > > > > > its
> > > > > > > value.
>
> > > > > > > script=SCRIPT("jQuery('document').ready(function(){var
> > > > > > > y=jQuery('year'); y.keyup(function(){var
> > > > > > > c=jQuery('#cars_catalytic_converter_type__row');if(parseInt(y.val()>1975)c.show();elsec.hide();});});");
>
> > > > > > > db.define_table('cars',
> > > > > > >     Field('make'),
> > > > > > >     Field('model'),
> > > > > > >     Field('year'),
> > > > > > >     Field('catalytic_converter_type',requires =
> > > > > > > IS_IN_SET(('one','two','three'),zero=None),
> > > > > > > comment=script))
>
> > > > > > > On Nov 26, 6:17 pm, "mr.freeze" <[email protected]> wrote:
>
> > > > > > > > Good point. Here is my use case:
>
> > > > > > > > db.define_table('cars',
> > > > > > > >     Field('make'),
> > > > > > > >     Field('model'),
> > > > > > > >     Field('year'),
> > > > > > > >     Field('catalytic_converter_type',requires =
> > > > > > > > IS_IN_SET('one','two','three'),
> > > > > > > > comment='for cars later than 1975'))
>
> > > > > > > > I want catalytic_converter_type to be required if the car year 
> > > > > > > > is
> > > > > > > > greater than 1975. I also want to show an error if
> > > > > > > > catalytic_converter_type is selected and the year is less than 
> > > > > > > > 1975.
> > > > > > > > Allowing the user to see all errors at once would be a bonus 
> > > > > > > > but not a
> > > > > > > > deal breaker. onvalidation seems like the place to handle it 
> > > > > > > > but let
> > > > > > > > me know if there is a better way.
>
> > > > > > > > On Nov 26, 5:48 pm, mdipierro <[email protected]> wrote:
>
> > > > > > > > > Consider this case:
>
> > > > > > > > > db.define_table('numbers',Field('a','integre'),Field('b','integer'))
> > > > > > > > > def validate(form):
> > > > > > > > >     if form.vars.a+form.vars.b>100:
> > > > > > > > >         form.errors.b="a+b must not exceed 100"
> > > > > > > > > form=crud.create(db.numbers,onvalidation=validate)
>
> > > > > > > > > Before the change the function validate is not called if a 
> > > > > > > > > and b are
> > > > > > > > > not valid integer this never triggering an exception, only 
> > > > > > > > > validation
> > > > > > > > > errors.
>
> > > > > > > > > With your proposed change this would cause an error because
> > > > > > > > > form.vars.a is None if request.vars.a does ot pass the 
> > > > > > > > > default integer
> > > > > > > > > validation. The function validation would be called again and 
> > > > > > > > > issue a
> > > > > > > > > ticket.
>
> > > > > > > > > This is a change of behavior. I am not convinced this change 
> > > > > > > > > is a good
> > > > > > > > > idea.
>
> > > > > > > > > Why do you need it?
> > > > > > > > > Other opinions?
>
> > > > > > > > > Massimo
>
> > > > > > > > > On Nov 26, 11:34 am, "mr.freeze" <[email protected]> wrote:
>
> > > > > > > > > > Changing line 1565 of html.py from...
> > > > > > > > > >         if status and onvalidation:
> > > > > > > > > > to...
> > > > > > > > > >         if vars and onvalidation:
>
> > > > > > > > > > On Nov 26, 11:28 am, mdipierro <[email protected]> 
> > > > > > > > > > wrote:
>
> > > > > > > > > > > What would you suggest?
>
> > > > > > > > > > > On Nov 26, 11:10 am, "mr.freeze" <[email protected]> 
> > > > > > > > > > > wrote:
>
> > > > > > > > > > > > I see two issues with this:
> > > > > > > > > > > > 1) The form errors found in onvalidation will not be 
> > > > > > > > > > > > displayed if
> > > > > > > > > > > > there are already form errors
> > > > > > > > > > > > 2) The developer never gets a chance to remove form 
> > > > > > > > > > > > errors for certain
> > > > > > > > > > > > conditions (think contingent form fields)
> > > > > > > > > > > > For example, I am using IS_IN_DB on a field but I only 
> > > > > > > > > > > > want it to be
> > > > > > > > > > > > required if another field is a certain value.
>
> > > > > > > > > > > > Is there a better way?
>
>

Reply via email to