Values do have a different representation for different use cases. Very often the value which is used by the business logic needs some significant transformation for a sensible human-readable representation, and vice versa. A common example is a date or a decimal value, which is locale dependent. To support this capability a form object should be able to manage different representation of one value per item.
We are able to implement this feature by replacing the value of an item with a set of values. Each value of this set is called the value of an attribute and is provided by an identifier. This simple attribution of form values allows us to enhance the data processing workflow of the form component significantly.
The approach assumes that the user input or the human-readable version is always represented by the attribute text. Filter which guarantee the consistency of a value are always applied to the text attribute, e.g. check for valid email address, check for word Viagra (spam), check for a valid date input according to the current locale, etc. You will find several filters in the class Naos_Form_AttributeTextFilter.
If the consistency check succeeds the attribute transformation process is applied. The transformation process handles the text attribute and generates new attributes if required, e.g. isodate for a date input field. This allows us to use the machine-readable values in the business logic without caring about the real user input. You will find the transformation functions per input field type in the class Naos_Form_ValueTransformReceive.
The transformation process is applied vice versa if a user input field is about to be displayed. In this case e.g. a text attribute is generated from the isodate attribute according to the current locale. You will find the transformation functions per input field type in the class Naos_Form_ValueTransformPrepare.
Beside the above described attribution we need also support for indexed values. This means that we have to be able to address an array of values per item. This leads us in general to the following tree-like data structure of the form object:
In case the array feature is not required, the default index NULL is assumed. Furthermore if no attribute is specified the default attribute text is assumed, which is the raw user input.
Formally a value can be addressed with the tuple (item, index, attribute).
The following example shows how to deal with a form object in practice.
| Code | Description |
$form->getAttribute('comment', null, 'text') | Returns the attribute text of item comment with index null, which is the raw user input. |
$form->getAttribute('comment') | Equivalent to the statement above. |
$form->getAttribute('begin', 101, 'isodate') | Returns the attribute isodate of item begin with index 101, e.g. 2008-07-01. |
$form->getAttribute('begin', 101, 'text') | Returns the attribute text of item begin with index 101, which is the raw user input e.g. 1. Juli 2008 or July 1st 2008. |
$form->getAttribute('begin', 101) | Equivalent to the statement above. |
Error messages are defined on index level; this means that a set of error messages can be addressed by the tuple (item, index). Whereas it is possible to add an error message on index level only, it is possible to retrieve the error messages on index, item or form object level.
Error messages are generated either by the validation of the text attribute via Naos_Form_AttributeTextFilter or by the business logic. The output of the messages should be locale dependent; this means that the messages need to be translated. Furthermore the messages have to be parameterized, because they refer to a context specific value, e.g. an item title. This is archived by the utilization of the I18N component.
The following example of error messages illustrated the approach.
| Error message | Example output (localized) |
| Please enter a valid email address in '%{title}'! | Bitte geben Sie eine gültige E-Mail-Adresse in das Feld 'Private E-Mail' ein! |
| Please confirm the order with your name (%{name}) as electronic signature. | Bitte bestätigen Sie die Bestellung mit Ihrem Namen (Hofmann) als elektronische Unterschrift. |
Please see the concept and specification of the I18N component for further details.
To meet the requirements which result from the application of the AJAX technology we have to map the old form data transfer process to the XML request. This should be done transparently and without any additional effort for the developer of the business logic. This leads on client side to a JavaScript framework, which we do not want to examine in this place, and on server side to the concept of the abstract data sources.
Therefore the form component contains the class Naos_Form_AbstractSource which defines the interface of a data source. Additionally the two implementations Naos_Form_HttpPostSource for the traditional way and Naos_Form_XmlRequestSource for the AJAX approach are provided by default. Other data sources are imaginable.
In many cases we have the situation that we want to offer the user a set of predefined values for an item, e.g. if we consider a select box with the states of the USA, or if we consider a table of check boxes with a set of interests the user should choose from.
Therefore it is possible to define a set of predefined values for each item of a form. This is done in the form definition section. It is possible to define different sources for the predefined values, e.g. a php file with a static data set or a function which is able to gather the data dynamically.
Furthermore this approach is enriched with a pattern features. This feature allows the template designer to apply a pattern on a form input field, e.g. the developer of the business logic provides a source of predefined values for an item called interests and the template designer simply applies a standard pattern to display these interests with a set of checkboxes.
As shown in the section The data structure of a form in general the data structure of a form object can be considered as a tree structure. If we include the module identifier and the form identifier in this tree as well as the predefined values we get a structure like the following.
The tree can be considered as a multidimensional array, which allows us to address values in the form in an array fashion. This approach is implemented in the class Naos_Form_ArrayInterface.