I am using Plone 4.3 and I have a form.SchemaForm plone.directives have an interface that has a start field from IEventBasic and a validator:
from datetime import timedelta
from plone.directives import form
from plone.app.contenttypes.interfaces import IEvent
from z3c.form import validator
from zope.component import provideAdapter
from zope.interface import Invalid
class IMyObject(form.SchemaForm)
my_field_a = schema.TextLine(title='a_field')
...
class MyObject(Item):
implements(IMyObject, IEvent)
class EndMyObjectValidator(validator.SimpleFieldValidator):
def validate(self,value):
#code for checking if end field is within a certain range from start field
if self.end > self.start + timedelta(days=6):
raise Invalid('The end date is not within range of the start date's week')
validator.WidgetValueDiscriminators(EndMyObjectValidator, field=IEventBasic['end'])
provideAdapter(EndMyObjectValidator)
In my type file (my.object.myobject.xml under profiles/default/types), I place the behavior in the behaviors section.
<behaviors>
<element value="plone.app.event.dx.behaviors.IEventBasic"/>
</behaviors>
The problem is it validates the end field in any Event object or any object that implements the IEventBasic interface/schema.
I thought maybe since the Plone documentation says that the parameters 'view' and 'context' of WidgetValueDiscriminators accept an interface, then I could do either:
validator.WidgetValidatorDiscriminators(EndMyObjectValidator, view=IMyObject, field=IEventBasic['end'])
or
validator.WidgetValidatorDiscriminators(EndMyObjectValidator, context=IMyObject,field=IEventBasic['end']
Unfortunately, none of those trigger at all. I guess I'm misunderstanding what the context and view parameters actually do. How can I make it so the validators are specifically for dealing with MyObject?
Source: http://docs.plone.org/develop/addons/schema-driven-forms/customising-form-behaviour/validation.html
For now I am doing:
...
from gpcl.container.my_container import MyContainer
...
class EndMyObjectValidator(validator.SimpleFieldValidator):
def validate(self,value):
if self.widgets.form.portal_type <> 'my.object.myobject':
return
...
validator.WidgetValueDiscriminators(EndMyObjectValidator, field=IEventBasic['end'])
provideAdapter(EndMyObjectValidator)
Update 2: I removed my comment before because it was for an unrelated problem. I changed the way I was checking for the type.
Ok, register your own Add Form and Subclassing the Default Dexterity Add Form. More Information about Validating in action handlers and Custom Add Forms
in my task.py
(Contenttype and so on...):
# -*- coding: utf-8 -*-
from zope.interface import implementer
from zope.interface import Invalid
from z3c.form import button
from z3c.form import validator
from z3c.form import util
from z3c.form.interfaces import ActionExecutionError
from z3c.form.interfaces import WidgetActionExecutionError
from plone.dexterity.content import Item
from plone.dexterity.browser import add
from viisionar.training.interfaces import ITask
from Products.statusmessages.interfaces import IStatusMessage
from my.addon import _
@implementer(ITask)
class Task(Item):
pass
class AddForm(add.DefaultAddForm):
portal_type = 'Task'
def __init__(self, context, request, ti=None):
super(AddForm, self).__init__(context, request, ti=None)
@button.buttonAndHandler(_('Save'), name='save')
def handleAdd(self, action):
print "Handle Add"
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
# Your Custom validation
# Debug Do what yo want
print data
if error:
"""
# Global Portal Message
raise ActionExecutionError(Invalid(_(u"Please provide a valid end date")))
# or
# Error Message in Widget
raise WidgetActionExecutionError('IEventBasic.end', Invalid(u"Please put the the right end date"))
"""
# /Your Custom validation
obj = self.createAndAdd(data)
if obj is not None:
# mark only as finished if we get the new object
self._finishedAdd = True
IStatusMessage(self.request).addStatusMessage(
self.success_message, "info"
)
class AddView(add.DefaultAddView):
form = AddForm
in my configure.zcml
i register the custom Add form
<adapter
for="
Products.CMFCore.interfaces.IFolderish
zope.publisher.interfaces.browser.IDefaultBrowserLayer
plone.dexterity.interfaces.IDexterityFTI"
provides="zope.publisher.interfaces.browser.IBrowserPage"
factory="my.addon.task.AddView"
name="Task" />
<class class="my.addon.task.AddView">
<require
permission="cmf.AddPortalContent"
interface="zope.publisher.interfaces.browser.IBrowserPage"/>
</class>
in my task.xml Definition:
<property name="factory">Task</property>
<property name="schema">my.addon.interfaces.ITask</property>
<property name="klass">my.addon.task.Task</property>
<property name="behaviors">
<element value="plone.app.content.interfaces.INameFromTitle" />
<element value="plone.app.event.dx.behaviors.IEventBasic"/>
</property>