This package provides an implementation for HTML forms and widgets. The goal
is to provide a simple API but with the ability to easily customize any data or
steps. This document, provides the content of this package’s documentation
files. The documents are ordered in the way they should be read:

form.txt [must read]

Describes the setup and usage of forms in the most common usages. Some
details are provided to the structure of form components.

group.txt [must read]

This document describes how widget groups are implemented within this
package and how they can be used.

subform.txt [must read]

Introduces the complexities surrounding sub-forms and details two classes of
sub-forms, including code examples.

field.txt [must read]

Provides a comprehensive explanation of the field manager API and how it is
to be used.

button.txt [must read]

Provides a comprehensive explanation of the button manager API. It also
outlines how to create buttons within schemas and how buttons are converted
to actions.

zcml.txt [must read]

Explains the ZCML directives defines by this package, which are designed to
make it easier to register new templates without writing Python code.

validator.txt [advanced users]

Validators are used to validate converted form data. This document provides
a comprehensive overview of the API and how to use it effectively.

widget.txt [advanced users]

Explains in detail the design goals surrounding widgets and widget managers
and how they were realized with the implemented API.

contentprovider.txt [advanced users]

Explains how to mix content providers in forms to render more html around
widgets.

action.txt [advanced users]

Explains in detail the design goals surrounding action managers and
actions. The execution of actions using action handlers is also covered. The
document demonstrates how actions can be created without the use of buttons.

value.txt [informative]

The concept of attribute value adapters is introduced and fully
explained. Some motivation for this new and powerful pattern is given as
well.

datamanager.txt [informative]

Data managers are resposnsible for accessing and writing the data. While
attribute access is the most common case, data managers can also manage
other data structures, such as dictionaries.

The purpose of this package is to make development of forms as simple
as possible, while still providing all the hooks to do customization
at any level as required by our real-world use cases. Thus, once the
system is set up with all its default registrations, it should be
trivial to develop a new form.

The strategy of this document is to provide the most common, and thus
simplest, case first and then demonstrate the available customization
options. In order to not overwhelm you with our set of well-chosen defaults,
all the default component registrations have been made prior to doing those
examples:

>>> from z3c.form import testing
>>> testing.setupFormDefaults()

Note, since version 2.4.2 the IFormLayer doesn’t provide IBrowserRequest
anymore. This is useful if you like to use z3c.form components for other
requests than the IBrowserRequest.

What’s next? Well, first things first. Let’s create an add form for the
person. Since practice showed that the IAdding interface is overkill for
most projects, the default add form of z3c.form requires you to define the
creation and adding mechanism.

This is as simple as it gets. We explicitly define the pieces that
are custom to every situation and let the default setup of the
framework do the rest. This is intentionally similar to
zope.formlib, because we really like the simplicity of
zope.formlib’s way of dealing with the common use cases.

Let’s try to add a new person object to the root folder (which
was created during test setup). For this add form, of course, the
context is now the root folder:

Since forms are not necessarily pages – in fact often they are not –
they must not have a __call__ method that does all the processing
and rendering at once. Instead, we use the update/render
pattern. Thus, we first call the update() method.

>>> addForm.update()

Actually a lot of things happen during this stage. Let us step through it one
by one pointing out the effects.

Just because a field is requested in the field manager, does not mean that a
widget has to be created for the field. There are cases when a field
declaration might be ignored. The following reasons come to mind:

No widget is created if the data are not accessible in the content.

A custom widget manager has been registered to specifically ignore a field.

The next step is to determine the value that should be displayed by the
widget. This value could come from three places (looked up in this order):

The field’s default value.

The content object that the form is representing.

The request in case a form has not been submitted or an error occurred.

Since we are currently building an add form and not an edit form,
there is no content object to represent, so the second step is not
applicable. The third step is also not applicable as we do not have
anything in the request. Therefore, the value should be the field’s
default value, or be empty. In this case the field provides a default
value:

>>> age.value
u'20'

While the default of the age field is actually the integer 20, the
widget has converted the value to the output-ready string '20'
using a data converter.

After all widgets have been instantiated and the update() method has been
called successfully, the actions are set up. By default, the form machinery
uses the button declaration on the form to create its actions. For the add
form, an add button is defined by default, so that we did not need to create
our own. Thus, there should be one action:

After everything is set up, all pressed buttons are executed. Once a submitted
action is detected, a special action handler adapter is used to determine the
actions to take. Since the add button has not been pressed yet, no action
occurred.

Note: The adapts() declaration might look strange. An error view
snippet is actually a multiadapter that adapts a combination of 6
objects – error, request, widget, field, form, content. By specifying
only the error, we tell the system that we do not care about the other
discriminators, which then can be anything. We could also have used
zope.interface.Interface instead, which would be equivalent.

In the examples previously we set the template manually. If no
template is specified, the system tries to find an adapter. Without
any special configuration, there is no adapter, so rendering the form
fails:

It frequently happens that a customer comes along and wants to
slightly or totally change some of the text shown in forms or make
optional fields required. It does not make sense to always have to
adjust the schema or implement a custom schema for these use
cases. With the z3c.form framework all attributes – for which it is
sensible to replace a value without touching the code – are
customizable via an attribute value adapter.

To demonstrate this feature, let’s change the label of the name widget
from “Name” to “Full Name”:

Let’s say a client requests that all add forms should have a “Cancel”
button. When the button is pressed, the user is forwarded to the next URL of
the add form. As always, the goal is to not touch the core implementation of
the code, but make those changes externally.

Adding a button/action is a little bit more involved than changing a value,
because you have to insert the additional action and customize the action
handler. Based on your needs of flexibility, multiple approaches could be
chosen. Here we demonstrate the simplest one.

The first step is to create a custom action manager that always inserts a
cancel action:

When an edit form is successfully committed, a detailed object-modified event
is sent out telling the system about the changes. To see the error, let’s
create an event subscriber for object-modified events:

Depending on the project, it is often desirable to change the status messages
to fit the application. In zope.formlib this was hard to do, since the
messages were buried within fairly complex methods that one did not want to
touch. In this package all those messages are exposed as form attributes.

There are three messages for the edit form:

formErrorsMessage – Indicates that an error occurred while
applying the changes. This message is also available for the add form.

successMessage – The form data was successfully applied.

noChangesMessage – No changes were found in the form data.

Let’s now change the noChangesMessage:

>>> editForm.noChangesMessage = u'No changes were detected in the form data.'
>>> editForm.update()
>>> print(testing.render(editForm, './/xmlns:i'))
<i>No changes were detected in the form data.</i>

When even more flexibility is required within a project, one could also
implement these messages as properties looking up an attribute value. However,
we have found this to be a rare case.

Sometimes it is not desirable to edit a class instance that implements the
fields, but other types of object. A good example is the need to modify a
simple dictionary, where the field names are the keys. To do that, a special
data manager for dictionaries is available:

One very common use case is to extend forms. For example, you would like to
use the edit form and its defined “Apply” button, but add another button
yourself. Unfortunately, just inheriting the form is not enough, because the
new button and handler declarations will override the inherited ones. Let me
demonstrate the problem:

Another important part of a form is that we can use custom widgets. We can do
this in a form by defining a widget factory for a field. We can get the field
from the fields collection e.g. fields['foo']. This means, we can define
new widget factories by defining fields['foo'].widgetFactory = MyWidget.
Let’s show a sample and define a custom widget:

Even though the data might be validated correctly, it sometimes happens that
data turns out to be invalid while the action is executed. In those cases a
special action execution error can be raised that wraps the original error.

The action execution errors are connected to the form via an event
listener called handlerActionError. This event listener listens for
IActionErrorEvent events. If the event is called for an action associated
with a form, the listener does its work as seen above. If the action is not
coupled to a form, then event listener does nothing:

When applying the data of a form to a content component, the function
applyChanges() is called. It simply iterates through the fields of the
form and uses the data managers to store the values. The output of the
function is a list of changes:

Sometimes, it’s useful to update actions again after executing them,
because some conditions could have changed. For example, imagine
we have a sequence edit form that has a delete button. We don’t
want to show delete button when the sequence is empty. The button
condition would handle this, but what if the sequence becomes empty
as a result of execution of the delete action that was available?
In that case we want to refresh our actions to new conditions to make
our delete button not visible anymore. The refreshActions form
variable is intended to handle this case.

Let’s create a simple form with an action that clears our context
sequence.

Now, the most interesting case when context is not empty, but becomes
empty as a result of pressing the “empty” button. We set the
refreshActions flag in the action handler, so our actions should
be updated to new conditions.

Group forms allow you to split up a form into several logical units without
much overhead. To the parent form, groups should be only dealt with during
coding and be transparent on the data extraction level.

For the examples to work, we have to bring up most of the form framework:

>>> from z3c.form import testing
>>> testing.setupFormDefaults()

So let’s first define a complex content component that warrants setting up
multiple groups:

Most of the group is setup like any other (sub)form. Additionally, you can
specify a label, which is a human-readable string that can be used for layout
purposes.

Let’s now create an add form for the entire vehicle registration. In
comparison to a regular add form, you only need to add the GroupForm as
one of the base classes. The groups are specified in a simple tuple:

When an edit form with groups is successfully committed, a detailed
object-modified event is sent out telling the system about the changes.
To see the error, let’s create an event subscriber for object-modified events:

You can customize the content for a group by overriding a group’s
getContent method. This is a very easy way to get around not
having object widgets. For example, suppose we want to maintain the
vehicle owner’s information in a separate class than the vehicle. We
might have an IVehicleOwner interface like so.

Traditionally, the Zope community talks about sub-forms in a generic manner
without defining their purpose, restrictions and assumptions. When we
initially talked about sub-forms for this package, we quickly noticed that
there are several classes of sub-forms with different goals.

Of course, we need to setup our defaults for this demonstration as well:

This class of sub-forms provides a complete form within a form, including its
own actions. When an action of the sub-form is submitted, the parent form
usually does not interact with that action at all. The same is true for the
reverse; when an action of the parent form is submitted, the sub-form does not
react.

A classic example for this type of sub-form is uploading an image. The subform
allows uploading a file and once the file is uploaded the image is shown as
well as a “Delete”/”Clear” button. The sub-form will store the image in the
session and when the main form is submitted it looks in the session for the
image.

This scenario was well supported in zope.formlib and also does not require
special support in z3c.form. Let me show you, how this can be done.

Next we define the car form, which has the owner form as a sub-form. The car
form also needs a special template, since it needs to render the sub-form at
some point. For the simplicity of this example, I have duplicated a lot of
template code here, but you can use your favorite template techniques, such as
METAL macros, viewlets, or pagelets to make better reuse of some code.

In this class of sub-forms, a sub-form is often just a collection of widgets
without any actions. Instead, the sub-form must be able to react to the
actions of the parent form. A good example of those types of sub-forms is
actually the example I chose above.

So let’s redevelop our example above in a way that the owner sub-form is just
a logical unit that shares the action with its parent form. Initially, the
example does not look very different, except that we use EditSubForm as a
base class:

Now, we know, we know. This might not be the behavior that you want. But
remember how we started this document. We started with the recognition that
there are many classes and policies surrounding subforms. So while this
package provides some sensible default behavior, it is not intended to be
comprehensive.

Let’s now create an error in the sub-form, ensuring that an error message
occurs:

Final Note: With zope.formlib and zope.app.form people usually wrote
complex object widgets to handle objects within forms. We never considered
this a good way of programming, since one loses control over the layout too
easily.

Ok, that was easy. But what about writing a form including a subform without a
context? Let’s show how we can write a form without any context using the
sample above. Note, this sample form does not include actions which store the
form input. You can store the values like in any other forms using the forms
widget method self.widgets.extract() which will return the form and
subform input values.

One of the features in zope.formlib that works really well is the syntax
used to define the contents of the form. The formlib uses form fields, to
describe how the form should be put together. Since we liked this way of
working, this package offers this feature as well in a very similar way.

A field manager organizes all fields to be displayed within a form. Each field
is associated with additional meta-data. The simplest way to create a field
manager is to specify the schema from which to extract all fields.

When a form (or any other widget-using view) is updated, one of the tasks is
to create the widgets. Traditionally, generating the widgets involved looking
at the form fields (or similar) of a form and generating the widgets using the
information of those specifications. This solution is good for the common
(about 85%) use cases, since it makes writing new forms very simple and allows
a lot of control at a class-definition level.

It has, however, its limitations. It does not, for example, allow for
customization without rewriting a form. This can range from omitting fields on
a particular form to generically adding a new widget to the form, such as an
“object name” button on add forms. This package solves this issue by providing
a widget manager, which is responsible providing the widgets for a particular
view.

The default widget manager for forms is able to look at a form’s field
definitions and create widgets for them. Thus, let’s create a schema first:

>>> import zope.interface
>>> import zope.schema

>>> class LastNameTooShort(zope.schema.interfaces.ValidationError):
... """The last name is too short."""

For more details on how to define fields within a form, see form.txt. We
can now create the fields widget manager. Its discriminators are the form for
which the widgets are created, the request, and the context that is being
manipulated. In the simplest case the context is None and ignored, as it
is true for an add form.

In a third case, the widget will be shown in display mode, if the attribute of
the context is not writable. Clearly this can never occur in add forms, since
there the context is ignored, but is an important use case in edit forms.

Thus, we need an implementation of the IPerson interface including some
security declarations:

Besides managing widgets, the widget manager also controls the process of
extracting and validating extracted data. Let’s start with the validation
first, which only validates the data as a whole, assuming each individual
value being already validated.

Before we can use the method, we have to register a “manager validator”:

In the background the widget factory assignment really just registered the
default factory in the WidgetFactories object, which manages the
custom widgets for all modes. Now all modes show this input widget:

Buttons are a method to declare actions for a form. Like fields describe
widgets within a form, buttons describe actions. The symmetry goes even
further; like fields, buttons are schema fields within schema. When the form
is instantiated and updated, the buttons are converted to actions.

Let’s now create a schema that describes the buttons of a form. Having button
schemas allows one to more easily reuse button declarations and to group them
logically. Button objects are just a simple extension to Field
objects, so they behave identical within a schema:

Now if we rerun update we will get this other ButtonAction
implementation. Note, there are two strategies what now could happen. We can
remove the existing action and get the new adapter based action or we can
reuse the existing action. Since the ButtonActions class offers an API for
remove existing actions, we reuse the existing action because it very uncommon
to replace existing action during an for update call with an adapter. If
someone really will add an action adapter during process time via directly
provided interface, he is also responsible for remove existing actions.

As you can see we still will get the old button action if we only call update:

>>> actions.update()
>>> actions.keys()
['apply', 'cancel']

>>> actions['apply']
<ButtonAction 'form.buttons.apply' u'Apply'>

This means we have to remove the previous action before we call update:

>>> del actions['apply']
>>> actions.update()

Make sure we do not append a button twice to the key and value lists by calling
update twice:

Aehm, something should have happened. But in order for the system to look at
the handlers declared in the form, a special action handler has to be
registered with the system:

>>> zope.component.provideAdapter(button.ButtonActionHandler)

And voila, the execution works:

>>> actions.execute()
successfully applied

Finally, if there is no handler for a button, then the button click is
silently ignored:

>>> form.handlers = button.Handlers()
>>> actions.execute()

While this might seem awkward at first, this is an intended feature. Sometimes
there are several sub-forms that listen to a particular button and one form or
another might simply not care about the button at all and not provide a
handler.

In this case the buttonAndHandler decorator creates a button and a handler
for it. By default the name is computed from the title of the button, which is
required. All (keyword) arguments are forwarded to the button
constructor. Let’s now render the form:

This helper function also supports a keyword argument provides, which
allows the developer to specify a sequence of interfaces that the generated
button should directly provide. Those provided interfaces can be used for a
multitude of things, including handler discrimination and UI layout:

Sometimes it is desirable to only show a button when a certain condition is
fulfilled. The Button field supports conditions via a simple argument. The
condition argument must be a callable taking the form as argument and
returning a truth-value. If the condition is not fulfilled, the button will not
be converted to an action:

As for widgets, it is often desirable to change attributes of the button
actions without altering any original code. Again we will be using attribute
value adapters to complete the task. Originally, our title is as follows:

A special type of button is the image button. Instead of creating a “submit”-
or “button”-type input, an “image” button is created. An image button is a
simple extension of a button, requiring an image argument to the constructor:

The “image” type of the “input”-element also requires there to be a src
attribute, which is the URL to the image to be used. The attribute is also
supported by the Python API. However, in order for the attribute to work, the
image must be available as a resource, so let’s do that now:

The big difference between the ‘simple’ Widget template and the Object Widget
directive is that the Object Widget template takes the field’s schema into
account. That makes it easy to register different widget templates for different
sub-schemas. You can use this together with SubformAdapter to get a totally
custom subwidget.

Validators are components that validate submitted data. This is certainly not
a new concept, but in the previous form frameworks validation was hidden in
many places:

Field/Widget Validation

The schema field consists of a validate() method. Validation is
automatically invoked when converting a unicode string to a field value
using fromUnicode(). This makes it very hard to customize the field
validation. No hooks were provided to exert additional restriction at the
presentation level.

Schema/Form Validation

This type of validation was not supported at all initially. zope.formlib
fixed this problem by validating against schema invariants. While this was a
first good step, it still made it hard to customize validators, since it
required touching the base implementations of the forms.

Action Validation

zope.formlib supports the notion of action validatos. Actions have a
success and failure handler. If the validation succeeds, the success handler
is called, otherwise the failure handler is chosen. We believe that this
design was ill-conceived, especially the default, which required the data to
completely validate in order for the action to successful. There are many
actions that do not even care about the data in the form, such as “Help”,
“Cancel” and “Reset” buttons. Thus validation should be part of the data
retrieval process and not the action.

For me, the primary goals of the validator framework are as follows:

Assert additional restrictions on the data at the presentation
level.

There are several use cases for this. Sometimes clients desire additional
restrictions on data for their particular version of the software. It is not
always desireable to adjust the model for this client, since the framework
knows how to handle the less restrictive case anyways. In another case,
additional restrictions might be applied to a particular form due to limited
restrictions.

Make validation pluggable.

Like most other components of this package, it should be possible to control
the validation adapters at a fine grained level.

Widgets: context, request, view, field[1], widget

Widget Managers: context, request, view, schema[2], manager

[1].. This is optional, since widgets must not necessarily have fields.
[2].. This is optional, since widget managers must not necessarily have
manage field widgets and thus know about schemas.

Provide good defaults that behave sensibly.

Good defaults are, like in anywhere in this pacakge, very important. We have
chosen to implement the zope.formlib behavior as the default, since it
worked very well – with exception of action validation, of course.

For this package, we have decided to support validators at the widget and
widget manager level. By default the framework only supports field widgets,
since the validation of field-absent widgets is generally not
well-defined. Thus, we first need to create a schema.

Widget validators only validate the data of one particular widget. The
validated value is always assumed to be an internal value and not a widget
value.

By default, the system uses the simple field validator, which simply uses the
validate() method of the field. For instantiation, all validators have the
following signature for its discriminators: context, request, view, field, and
widget

Most of the time we want to ignore unchanged fields/values at validation.
A common usecase for this is if a value went away from a vocabulary and we want
to keep the old value after editing.
In case you want to strict behaviour, register StrictSimpleFieldValidator
for your layer.

If there is no widget or the widget does not provide
interfaces.IContextAware, no value is looked up from the
context. So the not required field validates successfully but the
required one has an required missing error, as the default value of
the field is looked up on the field:

When the value is interfaces.NOT_CHANGED the validator tries to
look up the default value using a interfaces.IValue
adapter. Whether the adapter is found, its value is used as default,
so the validation of the required field is successful here:

Since multiple errors can occur during the validation process, all errors are
collected in a tuple, which is returned. If the tuple is empty, the validation
was successful. Let’s now generate a failure:

The Data class provides a wrapper to present a dictionary as a class
instance. This is used to check for invariants, which always expect an
object. While the common use cases of the data wrapper are well tested in the
code above, there are some corner cases that need to be addressed.

It is used by the validators (especially invariant validators) to provide a
context of validation, for example to look up a vocabulary or access the
parent of an object. Note that the context will be different between add and
edit forms.

Sometimes you might leave out fields in the form which need to compute the
invariant. An exception should be raised. The data wrapper is used to test
the invariants and looks up values on the context object that are left out in
the form.

Widgets are small UI components that accept and process the textual user
input. The only responsibility of a widget is to represent a value to the
user, allow it to be modified and then return a new value. Good examples of
widgets include the Qt widgets and HTML widgets. The widget is not responsible
for converting its value to the desired internal value or validate the
incoming data. These responsibilities are passed data converters and
validators, respectively.

There are several problems that can be identified in the original Zope 3 widget
implementation located at zope.app.form.

Field Dependence – Widgets are always views of fields. While this might
be a correct choice for a high-level API, it is fundamentally wrong. It
disallows us to use widgets without defining fields. This also couples
certain pieces of information too tightly to the field, especially, value
retrieval from and storage to the context, validation and raw data
conversion.

Form Dependence – While widgets do not have to be located within a form,
they are usually tightly coupled to it. It is very difficult to use
widgets outside the context of a form.

Traversability – Widgets cannot be traversed, which means that they
cannot interact easily using Javascript. This is not a fundamental
problem, but simply a lack of the current design to recognize that small
UI components must also be traversable and thus have a URI.

Customizability – A consequence of issue (1) is that widgets are not
customizable enough. Implementing real-world projects has shown that
widgets often want a very fine-grained ability to customize values. A
prime example is the label. Because the label of a widget is retrieved
from the field title, it is impossible to provide an alternative label for
a widget. While the label could be changed from the form, this would
require rewriting the entire form to change a label. Instead, we often
endde up writing cusom schemas.

Flexibility – Oftentimes it is desired to have one widget, but multiple
styles of representation. For example, in one scenario the widget uses a
plain HTML widget and in another a fancy JavaScript widget is used. The
current implementation makes it very hard to provide alternative styles
for a widget.

In this case we instantiated a generic widget. A full set of simple
browser-based widgets can be found in the browser/ package. Since no
helper components are around to fill the attributes of the widget, we have to
do it by hand:

>>> age.name = 'age'
>>> age.label = u'Age'
>>> age.value = '39'

The most important attributes are the “name” and the “value”. The name is used
to identify the widget within the form. The value is either the value to be
manipulated or the default value. The value must be provided in the form the
widget needs it. It is the responsibility of a data converter to convert
between the widget value and the desired internal value.

Before we can render the widget, we have to register a template for the
widget. The first step is to define the template:

The first argument, which is also required, is the path to the template
file. An optional content_type keyword argument allows the developer to
specify the output content type, usually “text/html”. Then there are five
keyword arguments that specify the discriminators of the template:

context – This is the context in which the widget is displayed. In a
simple widget like the one we have now, the context is None.

request – This discriminator allows you to specify the type of request
for which the widget will be available. In our case this would be a browser
request. Note that browser requests can be further broken into layer, so you
could also specify a layer interface here.

view – This is the view from which the widget is used. The simple
widget at hand, does not have a view associated with it though.

field – This is the field for which the widget provides a
representation. Again, this simple widget does not use a field, so it is
None.

widget – This is the widget itself. With this discriminator you can
specify for which type of widget you are providing a template.

We can now register the template factory. The name of the factory is the mode
of the widget. By default, there are two widget modes: “input” and
“display”. However, since the mode is just a string, one can develop other
kinds of modes as needed for a project. The default mode is “input”:

In order for the widget to be able to take the field’s default value and use
it to provide an initial value the widget, we need to provide a data converter
that defines how to convert from the field value to the widget value.

Once widgets are used within a framework, it is very tedious to write Python
code to adjust certain attributes, even though hooks exist. The easiest way to
change those attribute values is actually to provide an adapter that provides
the custom value.

Clearly, this code does not require us to touch the orginal form and widget
code, given that we have enough control over the selection. In the example
above, all the selection discriminators are listed for demonstration
purposes. Of course, the label in this case can be created as follows:

Let’s now simply register the label as a named adapter; the name is the name
of the attribute to change:

>>> zope.component.provideAdapter(AgeLabel, name='label')

Asking the widget for the label now will return the newly registered label:

>>> ageWidget.update()
>>> ageWidget.label
u'Current Age'

Of course, simply setting the label or changing the label extraction via a
sub-class are other options you might want to consider. Furthermore, you
could also create a computed attribute value or implement your own component.

Overriding other attributes, such as required, is done in the same
way. If any widget provides new attributes, they are also overridable this
way. For example, the selection widget defines a label for the option that no
value was selected. We often want to override this, because the German
translation sucks or the wording is often too generic. Widget implementation
should add names of overridable attributes to their “_adapterValueAttributes”
internal attribute.

Let’s try to override the required attribute. By default the widget is required,
because the field is required as well:

Note that we also support single values being returned outside a sequence. The
extracted value is then wrapped by a tuple. This feature is useful when
integrating with third-party client frameworks that do not know about the Zope
naming conventions.

A common use case in user interfaces is to ask the user to define one or more
items. The widget module provides a basic widget implementation to support
this use case.

The MultiWidget allows to store none, one or more values for a sequence or dictionary
field. Don’t get confused by the term sequence. The sequence used in
SequenceWidget means that the widget can choose from a sequence of values
which is really a collection. The MultiWidget can collect values to build
and store a sequence of values like those used in ITuple or IList field.

If the multi is used with a schema.List the value of a multi widget is always list.
When extracting values from the
request, the values must be a list of valid values based on the value_type
field used from the used sequence field. The widget also uses a counter which
is required for processing the input from a request. The counter is a marker
for build the right amount of enumerated widgets.

If we provide no request we will get no value:

>>> multiWidget.extract()
<NO_VALUE>

If we provide an empty counter we will get an empty list.
This is accordance with Widget.extract(), where a missing request value
is <NO_VALUE> and an empty (”) request value is ”.

Each widget normally gets first processed by it’s update method call after
initialization. This update call forces to call extract, which first will get
the right amount of (sub) widgets by the given counter value. Based on that
counter value the right amount of widgets will get created. Each widget will
return it’s own value and this collected values get returned by the extract
method. The multi widget update method will then store this values if any given
as multi widget value argument. If extract doesn’t return a value the multi
widget update method will use it’s default value. If we store a given value
from the extract as multi widget value, this will force to setup the multi
widget widgets based on the given values and apply the right value for them.
After that the multi widget is ready for rendering. The good thing about that
pattern is that it is possible to set a value before or after the update method
is called. At any time if we change the multi widget value the (sub) widgets
get updated within the new relevant value.

MultiWidget also declares the allowAdding and allowRemoving
attributes that can be used in browser presentation to control add/remove
button availability. To ease working with common cases, the
updateAllowAddRemove method provided that will set those attributes
in respect to field’s min_length and max_length, if the field provides
zope.schema.interfaces.IMinMaxLen interface.

Let’s define a field with min and max length constraints and create
a widget for it.

This event should be used by widget-managing components and is not created and
sent out internally by the widget’s update() method. The event was
designed to provide an additional hook between updating the widget and
rendering it.

An action manager is a form-related adapter that has the following
discriminator: form, request, and content. While there is a base
implementation for an action manager, the action module does not provide a
full implementation.

So we first have to build a simple implementation based on the Actions
manager base class which allows us to add actions. Note that the following
implementation is for demonstration purposes. If you want to see a real action
manager implementation, then have a look at ButtonActions. Let’s now
implement our simple action manager:

Now that the manager is updated, we can ask it for the “executed” actions:

>>> manager.executedActions
[<Action 'apply' u'Apply'>]

Executing the actions does nothing, because there are no handlers yet:

>>> manager.execute()

Let’s now register an action handler that listens to the “Apply” action. An
action handler has four discriminators: form, request, content, and
action. All those objects are available to the handler under those names. When
using the base action handler from the action module, __call__() is
the only method that needs to be implemented:

Action handlers, however, can also raise action errors. These action errors
are caught and an event is created notifying the system of the problem. The
error is not further propagated. Other errors are not handled by the system to
avoid hiding real failures of the code.

Let’s see how action errors can be used by implementing a handler for the
cancel action:

In advanced, highly customized projects it is often the case that a property
wants to be overridden for a particular customer in a particular case. A prime
example is the label of a widget. Until this implementation of a form
framework was written, widgets only could get their label from the field they
were representing. Thus, wanting to change the label of a widget meant
implementing a custom schema and re-registering the form in question for the
custom schema. It is needless to say that this was very annoying.

For this form framework, we are providing multiple levels of customization.
The user has the choice to change the value of an attribute through attribute
assignment or adapter lookup. The chronological order of an attribute value
assignment is as follows:

During initialization or right thereafter, the attribute value can be set
by direct attribute assignment, i.e. obj.attr = value

While updating the object, an adapter is looked up for the attribute. If an
adapter is found, the attribute value will be overridden. Of course, if the
object does not have an update() method, one can choose another
location to do the adapter lookup.

After updating, the developer again has the choice to override the attribute
allowing granularity above and beyond the adapter.

The purpose of this module is to implement the availability of an attribute
value using an adapter.

>>> from z3c.form import value

The module provides helper functions and classes, to create those adapters
with as little code as possible.

Creating the widget attribute object, using the helper function above, allows
us to define the discriminators (or the granulatrity) that can be used to
control a widget attribute by an adapter. In our case this is the widget
itself and the form/view in which the widget is displayed. In other words, it
will be possible to register a widget attribute value specifically for a
particular widget, a particular form, or a combination thereof.

Let’s now create a label attribute adapter for the text widget, since our
customer does not like the default label:

>>> TextLabel = WidgetAttribute(u'My Text', widget=TextWidget)

The first argument of any static attribute value is the value itself, in our
case the string “My Text”. The following keyword arguments are the
discriminators specified in the property factory. Since we only specify the
widget, the label will be available to all widgets. But first we have to
register the adapter:

A second implementation of the value adapter in the evaluated value, where one
can specify a function that computes the value to be returned. The only
argument to the function is the value adapter instance itself, which then
contains all the discriminators as specified when creating the generic widget
attribute factory. Let’s take the same use case as before, but generating the
value as follows:

The customer now requires that the title – which is the basis of the widget
label for field widgets – of the last name should be “Surname”. Until now the
option was to write a new schema changing the title. With this attribute value
module, as introduced thus far, we would need to provide a special interface
for the last name field, since registering a label adapter for all text fields
would also change the first name.

Before demonstrating the solution to this problem, let’s first create a field
attribute value:

The attribute value factory will automatically detect instances, create an
interface on the fly, directly provide it on the field and makes it the
discriminator interface for the adapter registratioon.

So after registering the adapter, …

>>> zope.component.provideAdapter(LastNameTitle, name='title')

the adapter is only available to the last name field and not the first name:

For the longest time the way widgets retrieved and stored their values on the
actual content/model was done by binding the field to a context and then
setting and getting the attribute from it. This has several distinct design
shortcomings:

The field has too much responsibility by knowing about its implementations.

There is no way of redefining the method used to store and access data
other than rewriting fields.

Finding the right content/model to modify is an implicit policy: Find an
adapter for the field’s schema and then set the value there.

While implementing some real-world projects, we noticed that this approach is
too limiting and we often could not use the form framework when we wanted or
had to jump through many hoops to make it work for us. For example, if we want
to display a form to collect data that does not correspond to a set of content
components, we were forced to not only write a schema for the form, but also
implement that schema as a class. but all we wanted was a dictionary. For
edit-form like tasks we often also had an initial dictionary, which we just
wanted modified.

Data managers abstract the getting and setting of the data. A data manager is
responsible for setting one piece of data in a particular context.

While we think that implicitly looking up an adapter is not the cleanest
solution, it allows us to mimic the behavior of zope.formlib. We think
that we will eventually provide alternative ways to accomplish the same in a
more explicit way.

Another implementation of the data manager interface is provided by the
dictionary field manager, which does not expect an instance with attributes as
its context, but a dictionary. It still uses a field to determine the key to
modify.

The data converter is the component that converts an internal data value as
described by a field to an external value as required by a widget and vice
versa. The goal of the converter is to avoid field and widget proliferation
solely to handle different types of values. The purpose of fields is to
describe internal data types and structures and that of widgets to provide one
particular mean of input.

The only two discriminators for the converter are the field and the widget.

The field data converter is a generic data converter that can be used for all
fields that implement IFromUnicode. If, for example, a Date field
– which does not provide IFromUnicode – is passed in, then a type error
is raised:

However, the FieldDataConverter is registered for IField, since many
fields (like Decimal) for which we want to create custom converters
provide IFromUnicode more specifically than their characterizing interface
(like IDecimal).

The converter can now convert any integer to a the value the test widget deals
with, which is an ASCII string:

>>> conv.toWidgetValue(34)
u'34'

When the missing value is passed in, an empty string should be returned:

>>> conv.toWidgetValue(age.missing_value)
u''

Of course, values can also be converted from a widget value to field value:

>>> conv.toFieldValue('34')
34

An empty string means simply that the value is missing and the missing value
of the field is returned:

>>> age.missing_value = -1
>>> conv.toFieldValue('')
-1

Of course, trying to convert a non-integer string representation fails in a
conversion error:

As hinted on above, the package provides a specific data converter for each of
the three main numerical types: int, float, Decimal. Specifically,
those data converters support full localization of the number formatting.

By default the converter converts missing input to the NOT_CHANGED value:

>>> fudc.toFieldValue('')
<NOT_CHANGED>

This allows machinery later to ignore the field without sending all the data
around.

If we get an empty filename in a FileUpload obejct, we also get the
missing_value. But this really means that there was an error somewhere in
the upload, since you are normaly not able to upload a file without a filename:

When the file upload widget is not used and a text-based widget is desired,
then the regular field data converter will be chosen. Using a text widget,
however, must be setup manually in the form with code like this:

For widgets and fields that work with choices of a sequence, a special data
converter is required that works with terms. A prime example is a choice
field. Before we can use the converter, we have to register some adapters:

For widgets and fields that work with a sequence of choices, another data
converter is required that works with terms. A prime example is a list
field. Before we can use the converter, we have to register the terms adapters:

As an optimization of this converter, the converter actually does not look up
the terms itself but uses the widget’s terms attribute. If the terms are
not yet retrieved, the converter will ask the widget to do so when in need.

As an optimization of this converter, the converter actually does not look up
the terms itself but uses the widget’s terms attribute. If the terms are
not yet retrieved, the converter will ask the widget to do so when in need.

The conversion from any field to the single checkbox widget value is a special
case, because it has to be defined what selecting the value means. In the case
of the boolean field, “selected” means True and if unselected, False
is returned:

Finally the API allows you to check whether a particular value is available in
the terms:

>>> 0 in terms
True
>>> 3 in terms
False

Now, there are several terms implementations that were designed for particular
fields. Within the framework, terms are used as adapters with the follwoing
discriminators: context, request, form, field, vocabulary/source and widget.

This function takes any unicode name and coverts it into an id that
can be easily referenced by CSS selectors. Characters that are in the
ascii alphabet, are numbers, or are ‘-‘ or ‘_’ will be left the same.
All other characters will be converted to ordinal numbers:

Now we can setup the stub form. Note this form is just a fake it’s not a real
implementation. We just provide a form like class which simulates the
FileUpload object in the a widget. See z3c.form.browser.file.txt for a real
file upload test uscase:

There is also a method which is able to extract the content type for a given
file upload. We can use the stub form from the previous test.

Not sure if this an error but on my windows system this test returns
image/pjpeg (progressive jpeg) for foo.jpg and image/x-png for foo.png. So
let’s allow this too since this depends on guess_content_type and is not
really a part of z3c.form.

Bug: Remove errors for cases where the key field of a dict field uses a
sequence widget (most notably choices). The sequence widget always returns
lists as widget values, which are not hashable. We convert those lists to
tuples now within the dict support.

Bug: Only add the ‘required’ CSS class to widgets when they are in input mode.

Bug: Catch bug where if a select value was set as from hidden input or
through a rest url as a single value, it won’t error out when trying to
remove from ignored list. Probably not the 100% right fix but it catches
core dumps and is sane anyways.

Feature: Missing terms in vocabularies: this was a pain until now.
Now it’s possible to have the same (missing) value unchanged on the object
with an EditForm after save as it was before editing.
That brings some changes with it:

MAJOR: unchanged values/fields do not get validated anymore
(unless they are empty or are FileUploads)

A temporary SimpleTerm gets created for the missing value
Title is by default “Missing: ${value}”. See MissingTermsMixin.

Feature: Added IForm.ignoreRequiredOnValidation,
IWidgets.ignoreRequiredOnValidation,
IWidget.ignoreRequiredOnValidation.
Those enable extract and extractData to return without errors in
case a required field is not filled.
That also means the usual “Missing value” error will not get displayed.
But the required-info (usually the *) yes.
This is handy to store partial state.

Fixed broken release, my python 2.7 windows setup didn’t release the new
widget.zcml, widget_layout.pt and widget_layout_hidden.pt files. After
enhance the pattern in MANIFEST.in everything seems fine. That’s probably
because I patched my python version with the *build exclude pattern patch.
And yes, the new files where added to the svn repos! After deep into this
again, it seems that only previous added *.txt, *.pt files get added to
the release. A fresh checkout sdist release only contains the *.py and *.mo
files. Anyway the enhanced MANIFEST.in file solved the problem.

Feature: Implemented widget layout concept similar to z3c.pagelet. The new
layout concept allows to register layout templates additional to the widget
templates. Such a layout template only get used if a widget get called.
This enhacement is optional and compatible with all previous z3c.form
versions and doesn’t affect existing code and custom implementations
except if you implemented a own __call__ method for widgets which
wasn’t implemented in previous versions. The new __call__ method will lookup
and return a layout template which supports additional HTML code used as
a wrapper for the HTML code returned from the widget render method.
This concept allows to define additional HTML construct provided for all
widget and render specific CSS classes arround the widget per context, view,
request, etc discriminators. Such a HTML constuct was normaly supported in
form macros which can’t get customized on a per widget, view or context base.

Summary; the new layout concept allows us to define a wrapper CSS elements
for the widget element (label, widget, error) on a per widgte base and skip
the generic form macros offered from z3c.formui.

Note; you only could get into trouble if you define a widget in tal without
to prefix them with nocall: e.g. tal:define=”widget view/widgets/foo”
Just add a nocall like tal:define=”widget nocall:view/widgets/foo” if your
rendering engine calls the __call__method by default. Also note that the
following will also call the __call__ method tal:define=”widget myWidget”.

Fixed content type extraction test which returned different values. This
probably depends on a newer version of guess_content_type. Just allow
image/x-png and image/pjpeg as valid values.

Remove zope34 extra, use an older version of z3c.form if you need to
support pre-ZTK versions.

Require at least zope.app.container 3.7 for adding support.

Avoid dependency on ZODB3.

Added IField.showDefault and IWidget.showDefault
That controls whether the widget should look for field default values
to display. This can be really helpful in EditForms, where you don’t
want to have default values instead of actual (missing) values.
By default it is True to provide backwards compatibility.

Remove “:list” from radio inputs, since radio buttons can be only one value
by definition. See LP580840.

Changed radio button and checkbox widget labels from token to value (wrapped
by a unicode conversion) to make it consistent with the parent
SequenceWidget class. This way, edit and display views of the widgets
show the same label. See LP623210.

Remove dependency on zope.site.hooks, which was moved to zope.component in
3.8.0 (present in ZTK 1.0 and above).

Make zope.container dependency more optional (it is only used in tests)

Properly escape JS code in script tag for the ordered-select widget. See
LP829484.

Cleaned whitespace in page templates.

Fix IGroupForm interface and actually use it in the GroupForm
class. See LP580839.

Note: z3c.pt and chameleon are not fully compatible right now with TAL.
Traversing the repeat wrapper is not done the same way. ZPT uses the
following pattern:
<tal:block condition=”not:repeat/value/end”>, </tal:block>

The z3c.ptcompat package no longer provides template classes, or ZCML
directives; you should import directly from the ZTK codebase.

Also, note that the PREFER_Z3C_PT environment option has been
rendered obsolete; instead, this is now managed via component
configuration.

Attention: You need to include the configure.zcml file from z3c.ptcompat
for enable the z3c.pt template engine. The configure.zcml will plugin the
template engine. Also remove any custom built hooks which will import
z3c.ptcompat in your tests or other places.

You can directly use the BoundPageTemplate and ViewPageTempalteFile from
zope.browserpage.viewpagetemplatefile if needed. This templates will implicit
use the z3c.pt template engine if the z3c.ptcompat configure.zcml is
loaded.

Adjust test for the contentprovider feature to not depend on the
ContentProviderBase class that was introduced in zope.contentprovider 3.5.0.
This restores compatibility with Zope 2.10.

Security issue, removed IBrowserRequest from IFormLayer. This prevents to
mixin IBrowserRequest into non IBrowserRequest e.g. IJSONRPCRequest.
This should be compatible since a browser request using z3c.form already
provides IBrowserRequest and the IFormLayer is only a marker interface used
as skin layer.

Since version 2.3.4 applyChanges required that the value exists
when the field had a DictionaryField data manager otherwise it
broke with an AttributeError. Restored previous behavior that
values need not to be exist before applyChanges was called by
using datamanager.query() instead of datamanager.get() to
get the previous value.

Added missing dependency on zope.contentprovider.

No longer using deprecated zope.testing.doctest by using
python’s built-in doctest module.

Feature: mix fields and content providers in forms. This allow to enrich
the form by interlacing html snippets produced by content providers.
Adding html outside the widgets avoids the systematic need of
subclassing or changing the full widget rendering.

The last discriminator of the ‘message’ IValue adapter used in the
ErrorViewSnippet is called ‘content’, but it was looked up as the error view
itself. It is now looked up on the form’s context.

Don’t let util.getSpecification() generate an interface more than once.
This causes strange effects when used in value adapters: if two adapters
use e.g. ISchema[‘some_field’] as a “discriminator” for ‘field’, with one
adapter being more specific on a discriminator that comes later in the
discriminator list (e.g. ‘form’ for an ErrorViewMessage), then depending on
the order in which these two were set up, the adapter specialisation may
differ, giving unexpected results that make it look like the adapter
registry is picking the wrong adapter.

Don’t invoke render() when publishing the form as a view if the HTTP status
code has been set to one in the 3xx range (e.g. a redirect or not-modified
response) - the response body will be ignored by the browser anyway.

Handle Invalid exceptions from constraints and field validators.

Don’t create unnecessary self.items in update() method of
SelectWidget in DISPLAY_MODE. Now items is a property.

Reverted changes made in the previous release as the getContent
method can return anything it wants to as long as a data manager can
map the fields to it. So context should be used for group
instantiation. In cases where context is not wanted, the group
can be instantiated in the update method of its parent group or
form. See also
https://mail.zope.org/pipermail/zope-dev/2010-January/039334.html

Feature: The DictionaryFieldManager now allows all mappings
(zope.interface.common.mapping.IMapping), even
persistent.mapping.PersistentMapping and
persistent.dict.PersistentDict. By default, however, the field
manager is only registered for dict, because it would otherwise get
picked up in undesired scenarios.

Bug: Updated code to pass all tests on the latest package versions.

Bug: Completed the Zope 3.4 backwards-compatibility. Also created a buidlout
configuration file to test the Zope 3.4 compatibility. Note: You must use
the ‘latest’ or ‘zope34’ extra now to get all required
packages. Alternatively, you can specify the packages listed in either of
those extras explicitely in your product’s required packages.

KGS 3.4 compatibility. This is a real hard thing, because z3c.form tests
use lxml >= 2.1.1 to check test output, but KGS 3.4 has lxml
1.3.6. Therefore we agree on that if tests pass with all package versions
nailed by KGS 3.4 but lxml overridden to 2.1.1 then the z3c.form package
works with a plain KGS 3.4.

Removed hard z3c.ptcompat and thus z3c.pt dependency. If you have
z3c.ptcompat on the Python path it will be used.

Added nested group support. Groups are rendered as fieldsets. Nested
fieldsets are very useful when designing forms.

WARNING: If your group did have an applyChanges() (or any added(?)) method
the new one added by this change might not match the signature.

Added labelRequired and requiredInfo form attributes. This is useful for
conditional rendering a required info legend in form templates. The
requiredInfo label depends by default on a given labelRequired message
id and will only return the label if at least one widget field is required.

Add support for refreshing actions after their execution. This is useful
when button action conditions are changing as a result of action
execution. All you need is to set the refreshActions flag of the form to
True in your action handler.

Added support for using sources. Where it was previosly possible to use a
vocabulary it is now also possible to use a source. This works both for
basic and contextual sources.

IMPORTANT: The ChoiceTerms and CollectionTerms in z3c.form.term
are now simple functions that query for real ITerms adapters for field’s
source or value_type respectively. So if your code inherits the old
ChoiceTerms and CollectionTerms classes, you’ll need to review and adapt
it. See the z3c.form.term module and its documentation.

The new z3c.form.interfaces.NOT_CHANGED special value is available to
signal that the current value should be left as is. It’s currently handled
in the z3c.form.form.applyChanges() function.

When no file is specified in the file upload widget, instead of overwriting
the value with a missing one, the old data is retained. This is done by
returning the new NOT_CHANGED special value from the
FileUploadDataConvereter.

Preliminary support for widgets for the schema.IObject field has been
added. However, there is a big caveat, please read the object-caveat.txt
document inside the package.

A new objectWidgetTemplate ZCML directive is provided to register widget
templates for specific object field schemas.

Implemented the MultiWidget widget. This widget allows you to use simple
fields like ITextLine, IInt, IPassword, etc. in a IList or ITuple
sequence.

Implemented TextLinesWidget widget. This widget offers a text area element
and splits lines in sequence items. This is usfull for power user
interfaces. The widget can be used for sequence fields (e.g. IList) that
specify a simple value type field (e.g. ITextLine or IInt).

Added a new flag ignoreContext to the form field, so that one can
individually select which fields should and which ones should not ignore the
context.

Added support for z3c.pt. Usage is switched on via the “PREFER_Z3C_PT”
environment variable or via z3c.ptcompat.config.[enable/diable]().

The TypeError message used when a field does not provide IFormUnicode
now also contains the type of the field.

Add support for internationalization of z3c.form messages. Added Russian,
French, German and Chinese translations.

Sphinx documentation for the package can now be created using the new docs
script.

The widget for fields implementing IChoice is now looked up by querying
for an adapter for (field, field.vocabulary, request) so it can be
differentiated according to the type of the source used for the field.

Move formErrorsMessage attribute from AddForm and EditForm to the
z3c.form.form.Form base class as it’s very common validation status
message and can be easily reused (especially when translations are
provided).

IMPORTANT - The signature of z3c.form.util.extractFileName function
changed because of spelling mistake fix in argument name. The
allowEmtpyPostFix is now called allowEmptyPostfix (note Empty instead
of Emtpy and Postfix instead of PostFix).

IMPORTANT - The z3c.form.interfaces.NOVALUE special value has been
renamed to z3c.form.interfaces.NO_VALUE to follow the common naming
style. The backward-compatibility NOVALUE name is still in place, but the
repr output of the object has been also changed, thus it may break your
doctests.

When dealing with Bytes fields, we should do a null conversion when going
to its widget value.

FieldWidgets update method were appending keys and values within each
update call. Now the util.Manager uses a UniqueOrderedKeys
implementation which will ensure that we can’t add duplicated manager
keys. The implementation also ensures that we can’t override the
UniqueOrderedKeys instance with a new list by using a decorator. If this
UniqueOrderedKeys implementation doesn’t fit for all use cases, we should
probably use a customized UserList implementation. Now we can call
widgets.update() more then one time without any side effect.

ButtonActions update where appending keys and values within each update
call. Now we can call actions.update() more then one time without any
side effect.

The CollectionSequenceDataConverter no longer throws a TypeError:
'NoneType' object is not iterable when passed the value of a non-required
field (which in the case of a List field is None).

The SequenceDataConverter and CollectionSequenceDataConverter converter
classes now ignore values that are not present in the terms when converting
to a widget value.

Use nocall: modifier in orderedselect_input.pt to avoid calling list
entry if it is callable.

SingleCheckBoxFieldWidget doesn’t repeat the label twice (once in <div
class="label">, and once in the <label> next to the checkbox).

Don’t cause warnings in Python 2.6.

validator.SimpleFieldValidator is now able to handle
interfaces.NOT_CHANGED. This value is set for file uploads when the user
does not choose a file for upload.

Feature: Use the query() method in the widget manager to try extract a
value. This ensures that the lookup is never failing, which is particularly
helpful for dictionary-based data managers, where dictionaries might not
have all keys.

Feature: Changed the get() method of the data manager to throw an error
when the data for the field cannot be found. Added query() method to
data manager that returns a default value, if no value can be found.

Feature: Deletion of widgets from field widget managers is now possible.

Feature: The widget manager’s extract() method now supports an optional
setErrors (default value: True) flag that allows one to not set errors
on the widgets and widget manager during data extraction. Use case: You want
to inspect the entered data and handle errors manually.

Bug: The ignoreButtons flag of the z3c.form.form.extends() method
was not honored. (Thanks to Carsten Senger for providing a patch.)

Bug: Group classes now implement IGroup. This also helps with the
detection of group instantiation. (Thanks to Carsten Senger for providing a
patch.)

Bug: The list of changes in a group were updated incorrectly, since it was
assumed that groups would modify mutually exclusive interfaces. Instead of
using an overwriting dictionary update() method, a purely additive merge
is used now. (Thanks to Carsten Senger for providing a patch.)

Bug: Added a widget for IDecimal field in testing setup.

Feature: The z3c.form.util module has a new function, createCSSId()
method that generates readable ids for use with css selectors from any
unicode string.

Bug: The applyChanges() method in group forms did not return a changes
dictionary, but simply a boolean. This is now fixed and the group form
changes are now merged with the main form changes.

Bug: Display widgets did not set the style attribute if it was
available, even though the input widgets did set the style attribute.

Bug: Fixed a bug that prohibited groups from having different contents than
the parent form. Previously, the groups contents were not being properly
updated. Added new documentation on how to use groups to generate
object-based sub-forms. Thanks to Paul Carduner for providing the fix and
documentation.

Feature: Added integration tests for form interfaces. Added default class
attribute called widgets in form class with default value None. This
helps to pass the integration tests. Now, the widgets attribute can also
be used as a indicator for updated forms.

Feature: Implemented additional createAndAdd hook in AddForm. This
allows you to implement create and add in a single method. It also supports
graceful abortion of a create and add process if we do not return the new
object. This means it can also be used as a hook for custom error messages
for errors happen during create and add.

Feature: Add a hidden widget template for the ISelectWidget.

Feature: Arrows in the ordered select widget replaced by named entities.

Feature: Added CollectionSequenceDataConverter to setupFormDefaults.

Feature: Templates for the CheckBox widget are now registered in
checkbox.zcml.

Feature: If a value cannot be converted from its unicode representation to a
field value using the field’s IFromUnicode interface, the resulting type
error now shows the field name, if available.

Bug: createId could not handle arbitrary unicode input. Thanks to
Andreas Reuleaux for reporting the bug and a patch for it. (Added
descriptive doctests for the function in the process.)

Bug: Interface invariants where not working when not all fields needed for
computing the invariant are in the submitted form.

Feature: The AttributeField data manager now supports adapting
the content to the fields interface when the content doesn’t implement
this interface.

Feature: Implemented single checkbox widget that can be used for boolean
fields. They are not available by default but can be set using the
widgetFactory attribute.

Bug: More lingual issues have been fixed in the documentation. Thanks to
Martijn Faassen for doing this.

Bug: When an error occurred during processing of the request the
widget ended up being security proxied and the system started
throwing TraversalError-‘s trying to access the label attribute of
the widget. Declared that the widgets require the zope.Public
permission in order to access these attributes.

Bug: When rendering a widget the style attribute was not honored. Thanks
to Andreas Reuleaux for reporting.

Bug: When an error occurred in the sub-form, the status message was not set
correctly. Fixed the code and the incorrect test. Thanks to Markus
Kemmerling for reporting.

Bug: Several interfaces had the self argument in the method
signature. Thanks to Markus Kemmerling for reporting.

Feature: An event handler for ActionErrorOccurred events is registered
to merge the action error into the form’s error collectors, such as
form.widgets.errors and form.widgets['name'].error (if
applicable). It also sets the status of the form. (Thanks to Herman
Himmelbauer, who requested the feature, for providing use cases.)

Feature: Action can now raise ActionExecutionError exceptions that will
be handled by the framework. These errors wrap the original error. If an
error is specific to a widget, then the widget name is passed to a special
WidgetActionExecutionError error. (Thanks to Herman Himmelbauer, who
requested the feature, for providing use cases.)

Feature: After an action handler has been executed, an action executed event
is sent to the system. If the execution was successful, the event is
ActionSuccessfull event is sent. If an action execution error was
raised, the ActionErrorOccurred event is raised. (Thanks to Herman
Himmelbauer, who requested the feature, for providing use cases.)

Feature: The applyChanges() function now returns a dictionary of changes
(grouped by interface) instead of a boolean. This allows us to generate a
more detailed object-modified event. If no changes are applied, an empty
dictionary is returned. The new behavior is compatible with the old one, so
no changes to your code are required. (Thanks to Darryl Cousins for the
request and implementation.)

Feature: A new InvalidErrorViewSnippet class provides an error view
snippet for zope.interface.Invalid exceptions, which are frequently used
for invariants.

Feature: When a widget is required, HTML-based widgets now declare a
“required” class.

Feature: The validation data wrapper now knows about the context of the
validation, which provides a hook for invariants to access the environment.

Feature: The BoolTerms term tokens are now cosntants and stay the same, even
if the label has changed. The choice for the token is “true” and “false”. By
default it used to be “yes” and “no”, so you probably have to change some
unit tests. Functional tests are still okay, because you select by term
title.

Feature: BoolTerms now expose the labels for the true and false values
to the class. This makes it a matter of doing trivial sub-classing to
change the labels for boolean terms.

Feature: Exposed several attributes of the widget manager to the form for
convenience. The attributes are: mode, ignoreContext, ignoreRequest,
ignoreReadonly.

Feature: Provide more user-friendly error messages for number formatting.

Refactoring: The widget specific class name was in camel-case. A converntion
that later developed uses always dash-based naming of HTML/CSS related
variables. So for example, the class name “textWidget” is now
“text-widget”. This change will most likely require some changes to your CSS
declarations!

Documentation: The text of field.txt has been reviewed linguistically.

Documentation: While reviewing the form.txt with some people, several
unclear and incomplete statements were discovered and fixed.

Bug (IE): In Internet Explorer, when a label for a radio input field is only
placed around the text describing the choice, then only the text is
surrounded by a dashed box. IE users reported this to be confusing, thus we
now place the label around the text and the input element so that both are
surrounded by the dashed border. In Firefox and KHTML (Safari) only the
radio button is surrounded all the time.

Bug: When extracting and validating data in the widget manager, invariant
errors were not converted to error view snippets.

Bug: When error view snippets were not widget-specific – in other words,
the widget attribute was None – rendering the template would fail.

Feature: Added a span around values for widgets in display mode. This allows
for easier identification widget values in display mode.

Feature: Added the concept of widget events and implemented a particular
“after widget update” event that is called right after a widget is updated.

Feature: Restructured the approach to customize button actions, by requiring
the adapter to provide a new interface IButtonAction. Also, an adapter
is now provided by default, still allowing cusotmization using the usual
methods though.

Feature: Added button widget. While it is not very useful without
Javascript, it still belongs into this package for completion.

Feature: All IFieldWidget instances that are also HTML element widgets
now declare an additional CSS class of the form “<fieldtype.lower()>-field”.

Feature: Added addClass() method to HTML element widgets, so that adding
a new CSS class is simpler.

Feature: Renamed “css” attribute of the widget to “klass”, because the class
of an HTML element is a classification, not a CSS marker.

Feature: Reviewed all widget attributes. Added all available HTML attributes
to the widgets.

Documentation: Removed mentioning of widget’s “hint” attribute, since it
does not exist.

Optimization: The terms for a sequence widget were looked up multiple times
among different components. The widget is now the canonical source for the
terms and other components, such as the converter uses them. This avoids
looking up the terms multiple times, which can be an expensive process for
some applications.

Bug/Feature: Correctly create labels for radio button choices.

Bug: Buttons did not honor the name given by the schema, if created within
one, because we were too anxious to give buttons a name. Now name assignment
is delayed until the button is added to the button manager.

Feature: The select widget grew a new prompt flag, which allows you to
explicitely request a selection prompt as the first option in the selection
(even for required fields). When set, the prompt message is shown. Such a
prompt as option is common in Web-UIs.

Feature: Internationalized data conversion for date, time, date/time,
integer, float and decimal. Now the locale data is used to format and parse
those data types to provide the bridge to text-based widgets. While those
features require the latest zope.i18n package, backward compatibility is
provided.

Feature: All forms now have an optional label that can be used by the UI.

Feature: Implemented groups within forms. Groups allow you to combine a set
of fields/widgets into a logical unit. They were designed with ease of use
in mind.

Feature: Button Actions – in other words, the widget for the button field
– can now be specified either as the “actionFactory” on the button field or
as an adapter.

Feature: In an edit form applying the data and generating all necessary
messages was all done within the “Apply” button handler. Now the actual task
of storing is factored out into a new method called “applyChanges(data)”,
which returns whether the data has been changed. This is useful for forms
not dealing with objects.

Feature: Added support for hidden fields. You can now use the hidden
mode for widgets which should get rendered as <input type="hidden"
/>.

Note: Make sure you use the new formui templates which will avoid rendering

labels for hidden widgets or adjust your custom form macros.

Feature: Added missing_value support to data/time converters

Feature: Added named vocabulary lookup in ChoiceTerms and
CollectionTerms.

Feature: Implemented support for FileUpload in FileWidget.

Added helper for handling FileUpload widgets:

extractContentType(form, id)

Extracts the content type if IBytes/IFileWidget was used.

extractFileName(form, id, cleanup=True, allowEmtpyPostFix=False)

Extracts a filename if IBytes/IFileWidget was used.

Uploads from win/IE need some cleanup because the filename includes also
the path. The option cleanup=True will do this for you. The option
allowEmtpyPostFix allows you to pass a filename without
extensions. By default this option is set to False and will raise a
ValueError if a filename doesn’t contain an extension.

Created afile upload data converter registered for
IBytes/IFileWidget ensuring that the converter will only be used
for fiel widgets. The file widget is now the default for the bytes
field. If you need to use a text area widget for IBytes, you have to
register a custom widget in the form using:

fields['foobar'].widgetFactory = TextWidget

Feature: Originally, when an attribute access failed in Unauthorized or
ForbiddenAttribute exceptions, they were ignored as if the attribute would
have no value. Now those errors are propagated and the system will fail
providing the developer with more feedback. The datamanager also grew a new
query() method that returns always a default and the get() method
propagates any exceptions.

Feature: When writing to a field is forbidden due to insufficient
priviledges, the resulting widget mode will be set to “display”. This
behavior can be overridden by explicitely specifying the mode on a field.

Feature: Added an add form implementation against IAdding. While this is
not an encouraged method of adding components, many people still use this
API to extend the ZMI.

Feature: The IFields class’ select() and omit() method now
support two ketword arguments “prefix” and “interface” that allow the
selection and omission of prefixed fields and still specify the short
name. Thanks to Nikolay Kim for the idea.

Feature: HTML element ids containing dots are not very good, because then
the “element#id” CSS selector does not work and at least in Firefox the
attribute selector (“element[attr=value]”) does not work for the id
either. Converted the codebase to use dashes in ids instead.

Bug/Feature: The IWidgets component is now an adapter of the form
content and not the form context. This guarantees that vocabulary factories
receive a context that is actually useful.

Bug: The readonly flag within a field was never honored. When a field is
readonly, it is displayed in “display” mode now. This can be overridden by
the widget manager’s “ignoreReadonly” flag, which is necessary for add
forms.

Bug: The mode selection made during the field layout creation was not
honored and the widget manager always overrode the options providing its
value. Now the mode specified in the field is more important than the one
from the widget manager.

Bug: It sometimes happens that the sequence widget has the no-value token as
one element. This caused displayValue() to fail, since it tried to find
a term for it. For now we simply ignore the no-value token.

Bug: Fixed the converter when the incoming value is an empty string. An
empty string really means that we have no value and it is thus missing,
returning the missing value.

Bug: Fix a slightly incorrect implementation. It did not cause any harm in
real-world forms, but made unit testing much harder, since an API
expectation was not met correctly.

Bug: When required selections where not selected in radio and checkbox
widgets, then the conversion did not behave correctly. This also revealed
some issues with the converter code that have been fixed now.

Bug: When fields only had a vocabulary name, the choice terms adaptation
would fail, since the field was not bound. This has now been corrected.

Documentation: Integrated English language and content review improvements
by Roy Mathew in form.txt.