0

I have a content type derived from plone.directives.form.Schema; it has several dozen fields across four fieldsets. I'm trying to create a zope.interface.invariant that looks at fields from two different fieldsets.

From tracing the behaviour, it looks like the invariant is called once for each fieldset, but not for the entire form.

I'm aware I can provide my own handler and perform all the checks I need there, but that feels chunky compared to distinctly defined invariants. While the obvious solution is to move related fields onto the same fieldset, the current setup reflects a layout that is logical the end user.

Is there an existing hook where I could perform validation on multiple fields across fieldsets?

Matthew Trevor
  • 14,354
  • 6
  • 37
  • 50

1 Answers1

1

The answer seems to be no: z3c.form.group.Group.extractData calls z3c.form.form.BaseForm.extractData once for each group/fieldset, and this call already includes invariant validation.

Instead of registering your own handler, you could also overwrite extractData:

from plone.directives import form, dexterity
from z3c.form.interfaces import ActionExecutionError,WidgetActionExecutionError
# ...

class EditForm(dexterity.EditForm):
  grok.context(IMyEvent)

  def extractData(self, setErrors=True):
    data, errors = super(EditForm, self).extractData(setErrors)

    if not None in(data['start'], data['end']):
      if data['end'] < data['start']:
        raise WidgetActionExecutionError('end', Invalid(_(u"End date should not lie before the start date.")))
      if data['end'] - data['start'] > datetime.timedelta(days=7):
        raise WidgetActionExecutionError('end', Invalid(_(u"Duration of convention should be shorter than seven (7) days.")))

    return data, errors

Please note that this class derives from dexterity.EditForm, which includes Dexterity's default handlers, instead of form.SchemaForm.

WidgetActionExecutionError does not work reliably, though. For some fields, it produces a 'KeyError'.

Stephan
  • 41,764
  • 65
  • 238
  • 329
cfaerber
  • 89
  • 2