Skip to main content

A collection of widgets, templates and other components for use with z3c.form and Plone

Project description

plone.app.z3cform

Abstract

A collection of widgets and templates, and other components for use with z3c.form in Plone. This is much related to plone.z3cform, the library that enables Zope 2 applications to use z3c.form.

WYSIWYG widget

The wysiwyg package provides an implementation of the Plone WYSIWYG widget compatible with z3c.form. This will allow you to use Kupu, FCKeditor and other editors compatible with the Plone WYSIWYG interface in your z3c.form forms.

To use, simply set the widget factory for the widget you’d like to be displayed with the WYSIWYG widget:

>>> from zope import interface, schema
>>> from z3c.form import form, field
>>> from z3c.form.interfaces import INPUT_MODE
>>> from plone.app.z3cform.wysiwyg.widget import WysiwygFieldWidget
>>> class IProfile(interface.Interface):
...     name = schema.TextLine(title=u"Name")
...     age = schema.Int(title=u"Age")
...     bio = schema.Text(title=u"Bio")
>>> class MyForm(form.Form):
...     fields = field.Fields(IProfile)
...     fields['bio'].widgetFactory[INPUT_MODE] = WysiwygFieldWidget

Query select widget

The queryselect module provides a query source compatible with z3c.formwidget.query which combines to a selection field that can be queried.

The native value type for the widget is Archetypes UID collections. The default implementation will simply search using the SearchableText index in the portal catalog.

This is how your form schema could look like:

>>> from zope import interface, schema
>>> from plone.app.z3cform.queryselect import ArchetypesContentSourceBinder
>>> class ISelection(interface.Interface):
...     items = schema.Set(
...         title=u"Selection",
...         description=u"Search for content",
...         value_type=schema.Choice(
...             source=ArchetypesContentSourceBinder()))

Optionally, instead of storing Archetypes UIDs, you can choose to use persistent.wref, i.e. weak references, instead of UIDs:

>>> from plone.app.z3cform.queryselect import uid2wref
>>> factory = uid2wref(ISelection['items'])

To store weak references instead of UIDs you would register such a factory as a component adapting the context. The factory automatically provides the interface which defines the field. (XXX: Please rewrite this paragraph.)

KSS inline validation

First, let’s set up KSS debug mode:

>>> from zope.interface import alsoProvides
>>> from kss.core.tests.base import IDebugRequest
>>> from zope.publisher.browser import TestRequest
>>> from zope.annotation.interfaces import IAttributeAnnotatable
>>> def make_request(form={}, lang='en'):
...     request = TestRequest(HTTP_ACCEPT_LANGUAGE=lang)
...     request.form.update(form)
...     alsoProvides(request, IDebugRequest)
...     alsoProvides(request, IAttributeAnnotatable)
...     return request

Then we create a simple z3c form

>>> from zope import interface, schema
>>> from z3c.form import form, field, button
>>> from plone.app.z3cform.layout import FormWrapper
>>> class MySchema(interface.Interface):
...     age = schema.Int(title=u"Age")
>>> class MyForm(form.Form):
...     fields = field.Fields(MySchema)
...     ignoreContext = True # don't use context to get widget data
...
...     @button.buttonAndHandler(u'Apply')
...     def handleApply(self, action):
...         data, errors = self.extractData()
...         print data['age'] # ... or do stuff
>>> class MyFormWrapper(FormWrapper):
...     form = MyForm
...     label = u"Please enter your age"
>>> from zope.component import provideAdapter
>>> from zope.publisher.interfaces.browser import IBrowserRequest
>>> from zope.interface import Interface
>>> provideAdapter(adapts=(Interface, IBrowserRequest),
...                provides=Interface,
...                factory=MyFormWrapper,
...                name=u"test-form")

Let’s verify that worked:

>>> from zope.component import getMultiAdapter
>>> from zope.interface import Interface, implements
>>> from Acquisition import Implicit
>>> class Bar(Implicit):
...     implements(Interface)
...     def restrictedTraverse(self, name):
...         # fake traversal to the form
...         if name.startswith('@@'):
...             return getMultiAdapter((self, self._REQUEST), Interface, name[2:]).__of__(self)
...         else:
...             return getattr(self, name)
...
>>> context = Bar()
>>> request = make_request()
>>> context._REQUEST = request # evil test fake
>>> formWrapper = getMultiAdapter((context, request), name=u"test-form")
>>> formWrapper
<Products.Five.metaclass.MyFormWrapper object ...>
>>> formWrapper.form
<class 'plone.app.z3cform.tests.example.MyForm'>
>>> del context, request

Inline validation

Inline validation is invoked via the @@kss_z3cform_inline_validation view.

>>> context = Bar()
>>> request = make_request(form={'form.widgets.age': 'Title'})
>>> context._REQUEST = request
>>> view = getMultiAdapter((context, request), name=u"kss_z3cform_inline_validation")

This is wired up with KSS. When the user leaves a form control with inline validation enabled, it will be called with the following parameters:

>>> view.validate_input(formname=u'test-form', fieldname=u'form.widgets.age', value='Title')
[{'selectorType': 'css', 'params': {'html': u'<![CDATA[The entered value is not a valid integer literal.]]>', 'withKssSetup': u'True'},
  'name': 'replaceInnerHTML',
  'selector': u'#formfield-form-widgets-age div.fieldErrorBox'},
 {'selectorType': 'css',
  'params': {'value': u'error'},
  'name': 'addClass',
  'selector': u'#formfield-form-widgets-age'}]
>>> request = make_request(form={'form.widgets.age': '20'})
>>> context._REQUEST = request
>>> view = getMultiAdapter((context, request), name=u"kss_z3cform_inline_validation")
>>> view.validate_input(formname=u'test-form', fieldname=u'form.widgets.age', value='20')
[{'selectorType': 'css', 'params': {}, 'name': 'clearChildNodes', 'selector': u'#formfield-form-widgets-age div.fieldErrorBox'},
 {'selectorType': 'css', 'params': {'value': u'error'}, 'name': 'removeClass', 'selector': u'#formfield-form-widgets-age'},
 {'selectorType': 'css', 'params': {'name': u'display', 'value': u'none'}, 'name': 'setStyle', 'selector': '.portalMessage'},
 {'selectorType': 'htmlid', 'params': {'html': u'<![CDATA[<dt>Info</dt><dd></dd>]]>', 'withKssSetup': u'True'},
  'name': 'replaceInnerHTML', 'selector': 'kssPortalMessage'},
 {'selectorType': 'htmlid', 'params': {'name': u'class', 'value': u'portalMessage info'},
  'name': 'setAttribute', 'selector': 'kssPortalMessage'},
 {'selectorType': 'htmlid', 'params': {'name': u'display', 'value': u'none'}, 'name': 'setStyle', 'selector': 'kssPortalMessage'}]

Inline validation with groups

We use plone.app.z3cform.tests.example.MyGroupFormWrapper and validate the field ‘name’ that’s part of a group. Inline validation is invoked via the @@kss_z3cform_inline_validation view.

>>> request = make_request(form={'form.widgets.name': ''})
>>> context._REQUEST = request
>>> view = getMultiAdapter((context, request), name=u"kss_z3cform_inline_validation")

The validation view takes an Attribute fieldset with the index of the group.

>>> view.validate_input(formname=u'test-group-form', fieldname=u'form.widgets.name', fieldset="0", value='')
[{'selectorType': 'css', 'params': {'html': u'<![CDATA[Required input is missing.]]>', 'withKssSetup': u'True'},
  'name': 'replaceInnerHTML',
  'selector': u'#fieldset-0 #formfield-form-widgets-name div.fieldErrorBox'},
 {'selectorType': 'css',
  'params': {'value': u'error'},
  'name': 'addClass',
  'selector': u'#fieldset-0 #formfield-form-widgets-name'}]
>>> request = make_request(form={'form.widgets.name': u'Name'})
>>> context._REQUEST = request
>>> view = getMultiAdapter((context, request), name=u"kss_z3cform_inline_validation")
>>> view.validate_input(formname=u'test-group-form', fieldname=u'form.widgets.name', fieldset="0", value=u'Name')
[{'selectorType': 'css', 'params': {}, 'name': 'clearChildNodes', 'selector': u'#fieldset-0 #formfield-form-widgets-name div.fieldErrorBox'},
 {'selectorType': 'css', 'params': {'value': u'error'}, 'name': 'removeClass', 'selector': u'#fieldset-0 #formfield-form-widgets-name'},
 {'selectorType': 'css', 'params': {'name': u'display', 'value': u'none'}, 'name': 'setStyle', 'selector': '.portalMessage'},
 {'selectorType': 'htmlid', 'params': {'html': u'<![CDATA[<dt>Info</dt><dd></dd>]]>', 'withKssSetup': u'True'},
  'name': 'replaceInnerHTML', 'selector': 'kssPortalMessage'},
 {'selectorType': 'htmlid', 'params': {'name': u'class', 'value': u'portalMessage info'},
  'name': 'setAttribute', 'selector': 'kssPortalMessage'},
 {'selectorType': 'htmlid', 'params': {'name': u'display', 'value': u'none'}, 'name': 'setStyle', 'selector': 'kssPortalMessage'}]

Inline-Validation and Translation of ErrorSnippets

We use plone.app.z3cform.tests.example.MyGroupFormWrapper and validate the field ‘name’ that’s part of a group. Inline validation is invoked via the @@kss_z3cform_inline_validation view.

>>> request = make_request(form={'form.widgets.name': ''}, lang='de',)
>>> context._REQUEST = request
>>> view = getMultiAdapter((context, request), name=u"kss_z3cform_inline_validation")

The validation view takes an Attribute fieldset with the index of the group.

>>> view.validate_input(formname=u'test-group-form', fieldname=u'form.widgets.name', fieldset="0", value='')
[{'selectorType': 'css', 'params': {'html': u'<![CDATA[Erforderliche Eingabe fehlt.]]>', 'withKssSetup': u'True'},
  'name': 'replaceInnerHTML',
  'selector': u'#fieldset-0 #formfield-form-widgets-name div.fieldErrorBox'},
 {'selectorType': 'css',
  'params': {'value': u'error'},
  'name': 'addClass',
  'selector': u'#fieldset-0 #formfield-form-widgets-name'}]

Changelog

0.4.6 - 2009-07-26

  • Include plone.z3cform’s overrides.zcml from our own overrides.zcml. [optilude]

  • Updated to collective.z3cform.datetimewidget>=0.1a2 to fix a ZCML conflict with z3c.form. [davisagli]

0.4.5 - 2009-05-25

  • Made the KSS form support conditional on both kss.core and Archetypes being installled. [hannosch]

  • Use the date/time widgets from collective.z3cform.datetimewidget as the default widget for Date and Datetime fields. [davisagli]

0.4.4 - 2009-05-03

0.4.3 - 2009-04-17

  • Added a display template for the WYSIWYG widget. [optilude]

  • Make the ?fieldset.current query string variable work. Set it to the id of a fieldset other than default to pre-select a different fieldset, e.g. …/@@formview?fieldset.current=3 [optilude]

  • Hide the ‘default’ fieldset if there’s nothing to show there. [optilude]

  • Provide ‘portal’ variable in wysiwyg template, as its used by some editors. [davisagli]

0.4.2 - 2008-09-04

  • Make the WYSIWYG widget work also for non-Acquisition wrapped content.

0.4.1 - 2008-08-21

  • Removed maximum version dependency on zope.component. This should be left to indexes, known good sets or explicit version requirements in buildouts. If you work with zope.component >= 3.5 you will also need five.lsm >= 0.4. [hannosch]

  • Make use of new plone.z3cform support for looking up the layout template by adapter. This means that forms now no longer need to depend on plone.app.z3cform unless they want to use Plone-specific widgets.

0.4.0 - 2008-07-31

  • Add inline validation support with KSS

  • Require zope.component <= 3.4.0 to prevent compatibility issues with five.localsitemanager, of which a buggy version (0.3) is pinned by plone.recipe.plone 3.1.4. Upgrade to this version if you’re seeing:

    ...
    Module five.localsitemanager.registry, line 176, in registeredUtilities
    ValueError: too many values to unpack

0.3.2 - 2008-07-25

  • Fixed a bug in macros.pt where ‘has_groups’ and ‘show_default_label’ for fieldsets were set in the ‘form’ macro, rendering the ‘field’ macro unusable by itself.

0.3.1 - 2008-07-24

  • Fixed a bug where we would use the form macros defined in plone.z3cform instead of our own.

0.3 - 2008-07-24

  • Create this package from Plone-specific bits that have been factored out of plone.z3cform.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plone.app.z3cform-0.4.6.tar.gz (24.9 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page