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.

.. _z3c.form: http://pypi.python.org/pypi/z3c.form
.. _Plone: http://plone.org
.. _plone.z3cform: http://pypi.python.org/pypi/plone.z3cform

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)
>>> context = Bar()
>>> request = make_request()
>>> 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'})
>>> 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'})
>>> 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': ''})
>>> 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'})
>>> 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',)
>>> 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.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.3.tar.gz (24.0 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