Skip to end of metadata
Go to start of metadata
You are viewing an old version of this page. View the current version. Compare with Current  |   View Page History

Zend_Form has been accused of violating the principal of separation of concerns, due to the fact that it has Model-related logic (filtering and validation, metadata), as well as View-releated logic (rendering, decorators).

While Form objects may be used to provide validation to domain models, many do not like this linking of concerns, and would prefer the ability to attach validation chains from models to the form in order to provide validation error hinting; at the same time, many others feel that forms as simply collections of elements with no ability to validate makes them basically worthless.

Finally, the decoration system, while powerful and flexible, is also quite difficult for many to learn. Having it coupled to Zend_Form causes some issues, as it basically inverts the decorator principal, and is somewhat misnamed as it primarily acts as a filter chain.

Recommendations

Refactor Form view helpers to accept form/element/group objects

Currently, we use the ViewHelper decorator with most form elements as the first decorator. While this works well, it also complicates the issue when you want to build your markup manually; you are forced to use the ViewHelper decorator if you want to use a view helper to render the element.

One simple way to solve this is to modify the individual form*() view helpers to accept elements (or other Zend_Form objects), then we can simplify things greatly. As an example:

Use PubSub as basis for Decorator Chains

If we use the pubsub's filter() method, we can achieve the same effect as the current decorators. As an example:

We would provide some pre-formulated chains as part of this initiative. This would then entail simply setting the view and passing in the element.

The above promotes re-use of decorator chains with multiple elements, and also re-use of pre-defined chains.

The actual act of rendering would then be removed from Zend_Form itself.

Use PubSub as basis for Filter and Validation Chains

If we use the pubsub's filter() method, we have all the functionality of the current Zend_Filter and Zend_Validate chains. This can allow us to detach chains or attach chains. As such, we would define chains and attach them to the form elements.

This allows us to continue to perform validation and filtering as before, but offloads much of the code and functionality to other, reusable components.

Allow retrieving and setting all element validators and filter chains

In order to achieve full separation, we would need the ability to retrieve these for the entire form for re-use in Models to validate data sets, as well as to pull from Models in order to attach to Forms. In essence, we're talking about an update to Zend_Filter_Input.

The basics would work as follows:

The object structure would look as follows:

and would be used (roughly) as follows:

Make the metadata/behavior separation exlicit

The various classes in Zend_Form basically contains metadata and behavior. The metadata is typically consumed by decorators in order to determine how to render themselves; the behavior is generally related to validation and/or error message retrieval (which is a related task).

As such, we propose that all Form classes will define a "metadata" property that will contain key/value pairs, and a set of setter/getter methods for the metadata (with specific setters for metadata that requires normalization).

As an example:

No IDs by default

Currently, the various Zend_Form elements all generate IDs. With modern JS libraries, this is typically unnecessary, and having explicit IDs makes it very difficult to have forms with variable numbers of the same element or group of elements. Removing ID generation would solve a number of UI issues. (Note: IDs could be set manually as metadata; alternately, setName() could be overridden in order to set the ID as well.)

Translation

Translation should be moved to the view layer. The View and Decorator chains would receive the Translator object and use it to translate appropriate labels and metadata. As such, the form, its elements, and the individual validator and validator chains would need no such knowledge of this information.

BC Concerns

Configuration

Since the chains would be separate objects, and the interaction with those chains would no longer be part of the various Form objects, creation of the chains from configuration will no longer be possible.

One way to mitigate this would be to have a "form builder" class that can build the Form objects and all related objects from configuration. Decorators would be one of the exceptions to this, as the Decorator chains would no longer be contained within the various Form objects. As such, a "decorator chain" builder could be useful.

Metadata

If metadata is moved to an explicit "metadata" container, this may cause problems with existing configuration. A legacy builder class could alleviate this problem, however.

Removal of IDs

Removing IDs may have UI implications. In particular, the Dojo integration relies heavily on the IDs in order to work. As such, this feature may need to be configurable.

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.