How to raise a WidgetActionExecutionError for a non-default fieldset field?

The background is described in this issue: How do I validate in datagridfield? - #2 by Esoth. I can't do more typical validation options because this is on a DataGridField here. I'm in Plone 5.2, collective.z3cform.datagridfield 2.0.1.

  • Setting a constraint on the DGF field does not work because that function never gets called
  • Setting a constraint on the field in the DGF's schema (the sub form) returns an error page to the user, instead of this being caught and displayed as a warning in the form

As a workaround I am trying to use form level validation. The buttonAndHandler method of my form has:

raise WidgetActionExecutionError('myfield', Invalid('Error msg here'))

This works, except for the case where I use plone.supermodel.directives.fieldset to put it in another fieldset. This results in a KeyError on the field name.

I also tried using just raising ActionExecutionError. This works, but only in the sense that it displays a message at the top of the form. It does not highlight the DGF field, let alone the specific subfield in that DGF. Any hints?

I have a validator example here for our DGF (in a separate group form (=fieldset)). The versions are for Plone 6 but this should work on older DGF too:

from plone.autoform import directives
from plone.supermodel import model
from z3c.form import validator
from zope import schema
from zope.interface import Interface


class IDGFSchema(Interface):
    last_name = schema.TextLine(title=_("last_name"))
    first_name = schema.TextLine(title=_("first_name"))
    birthday = schema.Date(title=_("birthday"))
    disability = schema.Bool(title=_("fp_children_disability"), required=False)

    directives.widget(
        "birthday",
        DateFieldWidget,
        _formater_length="long",
    )


class IContentSchema(model.Schema):
    children = schema.List(
        title=_("fp_children"),
        value_type=DictRow(
            title="child",
            schema=IDGFSchema,
        ),
        default=[],
        required=False,
    )
    directives.widget(
        "children",
        DataGridFieldWidgetFactory,
        auto_append=False,
        input_table_css_class="table table-sm",
        display_table_css_class="table table-sm",
    )
    model.fieldset(
        "children",
        label=_("Children"),
        fields=[
            "children",
        ],
    )

class ChildrenValidator(validator.SimpleFieldValidator):
    def validate(self, value):
        if value is None:
            value = []

        _valid = bool(len(value))
        _msg = _("Invalid children data")

        for c in value:
            if not c["first_name"] or not c["last_name"] or not c["birthday"]:
                _valid = False
                continue
            try:
                b_year = c["birthday"].year
                if (
                    b_year <= (datetime.now().year - CHILD_AGE_LIMIT)
                    and not c["disability"]
                ):
                    _valid = False
                    _msg = _(
                        "Too old. Minimum birthyear: ${min_year}",
                        mapping=dict(min_year=datetime.now().year - CHILD_AGE_LIMIT + 1),
                    )
            except Exception:
                pass

        if not _valid:
            raise Invalid(_msg)


validator.WidgetValidatorDiscriminators(
    ChildrenValidator,
    field=IContentSchema["children"],
)

and register the ChildrenValidator adapter in a zcml file:

<adapter factory=".mymodule.ChildrenValidator" />
1 Like

Interesting, I don't think I knew about that class. Bit of an aside, I'm trying to find the documentation for this. Unfortunately it looks like a lot of older documentation has been moved or removed. This page https://github.com/plone/plone.app.dexterity/blob/master/docs/advanced/validators.rst mentions the z3c form validators section at http://docs.plone.org/develop/plone/forms/z3c.form.html#validators which is no longer a valid link.

you can replace https://6.docs.plone.org/develop/plone/forms/z3c.form.html#validators with https://5.docs.plone.org/develop/plone/forms/z3c.form.html#validators and find the missing docs.

1 Like