Introduction
Magnolia 5.1 introduce a new way to handle properties bound to a dialog field. Until Magnolia 5.1 the only way to modify the default behavior (a field is bound to a simple property) was to override the FieldBuilder.getOrCreateProperty(..
method.
Now by configuration we have the possibility to define custom way to read and write a value or values from a property linked to a field. This is us full for complex fields like MultiValueField
or CompositeField
that needs more than one simple property bound to them.
Basic Concept
A Field
is linked to a Property
used to store the field value. This Property
:
- is set by the
FieldBuilder
based on the passedItem
. - has a name and a value.
- name of the property is generally the name used to store the property
- value contains the user input.
In other words a field has a property, this property has a value.
The field property is normally simply linked to an Item property. Let's take a simple example. Assume that we have a Form displaying five fields. The following schema display the Jcr representation (1), his equivalent Item representation (2) (used in Magnolia UI and also to build the form) and the form view (3).
A form is build by the form builder using the Item (2). Each individual form field are build by the field builder. This builder used the field definition (that contains the field class, name,...) and the related item property to create an individual field.
In the previous example, (2.1) the field definition says that we have to create a field of type Text that has a value coming from a property called 'firstName'. The field builder, request from the Item (2) the property 'firstName'. It create a text field, a new property set as property datasource of the field, and associate the value of (2.1) to this property datasource (3.1).
The transformation dome between (1) and (2) is performed by the Actions (Open Dialog action and Save Dialog action). All changes done in the item (2) will be propagated to the Jcr structure once a user click to the save button (adding/removing/changing a property, or adding a sub item, ....)
Until Magnolia 5.1, the transformation between (2) and (3) was a 1:1 translation, meaning that the individual fields where directly accessing the Item. Now Magnolia 5.1 introduce a new layer between (2) and (3) allowing to perform complexer mapping. This layer is called Transformer.
Now for a MultiField,
the related Property
can no more be a simple Property
but rather a ListProperty
. This ListProperty
will be populated with the individual field Property
values.
This is the first information needed in order to handle complex fields: The PropertType
(Basic, List, Composite,...)
The way values of the ListProperty
are set and retrieve from the related Item
is also something we would like to configure. For example I may want to have a MultiField
composed of DateField
stored in a single multi value.
The same field may be used in another place but the values have to be stored as sub item (nodes) elements. PropertyHandler
is the second information needed. PropertyHandler
handle the way property element are retrieve and set to an Item
.
Configuration
These configurations are done in the common fields Properties.
Property | Description | Default value | Valid values |
---|---|---|---|
propertyBuilder | Concrete property Type and Handler definition. Optional. | ||
propertyHandler | Implementation class of PropertyHandler set to the propertyType used to set and get values in certain format. | ||
propertyType | Implementation class of CustomPropertyType set as Field PropertyDatasource . |
Default behavior
Basic Property
By default BasicProperty
and BasicPropertyHandler
are used.
The field is created based on the related form Item
. BasicPropertyHandler
will:
- Retrieve the
Item.property
if thisproperty
already exist on theItem
.property
is search based on the Field name defined as name property on the field definition. - Create the
Item.property
if thisproperty
do not yet exist on theItem
.property
is created based on the following field definition:type
:property
will get the desiredtype
defaultValue
: if define, the string representation of the default field value is converted to a newtyped value.
Composite Property
Composite Property (CompositeProperty
) are used by the following fields:
CompositeField
SwitchableField
CompositeField
This field is by default bound with SimplePropertyCompositeHandler
. This handler will store each single field part of the CompositeField
as single suffixed property.
Assume that your CompositeField
is called 'composite' and contains two fields: a text field called 'simpleText' and a date field called 'simpleDate'. The values will be stored as following:
Node name | Value |
---|---|
compositesimpleText | some text value |
compositesimpleDate | 2006-05-01T21:47:58.230+02:00 |
SwitchableField
This field is by default bound with SwitchableSimplePropertyCompositeHandler
. This handler will store each single field part of the SwitchableField
as single suffixed property.
Assume that your SwitchableField
is called 'switchable' and contains two fields: a text field called 'simpleText' and a date field called 'simpleDate'. The values will be stored as following:
Node name | Value |
---|---|
switchable | text (last tab selected) |
switchablesimpleText | some text value |
switchablesimpleDate | 2006-05-01T21:47:58.230+02:00 |
List Property
List Property (ListProperty
) are used by the following field:
MultiField
MultiField
This field is by default bound with MultiValuesPropertyMultiHandler
. This handler will store each single field part of the MultiField
as a multiValue property (Basically a JCR multiValue property represented a a Typed List property).
i18n
All default implementation support the i18n definition.
If for example you have two language defined ('en', 'de') with 'en' set as default language:
Node name | Value |
---|---|
formNode |
|
simpleText | Simple English Text |
simpleText_de | Einfache deutsche Text |
multiValueText | English1,English2,English3 |
multiValueText_de | Deutsche1,Deutsche2 |
If you want to implement your own implementation of PropertyHandler
that support i18n, your implementation will need to:
- return
true
forPropertyHandler.hasI18NSupport()
- implement a compatible Magnolia i18n logic.
Implemented
Implemented Property
Hierarchy
BaseProperty
BaseProperty
implements the following basic mechanism:
- Handle i18n support.
- Delegate the configured
handler
the request whenproperty.getValue()
andproperty.setValue()
are called.
Implemented Handlers
BasicPropertyHandler
Overview
BasicPropertyHandler
The property
linked to a field is retrieved and stored based on the Field's property name
defined in the field definition.
A new property
is created in case id does not yet exist.
- As
property
are typed, the createdproperty
will be of the type defined by the property namedtype
coming from the field definition. (type=Date
the property will be aDate Object
). Default type isString
- If the property
defaultValue
is defined in the field definition, this value will be converted to the appropriatetype
and assigned to the newly createdproperty
. Otherwise the property will have anull
value.
If the related field support i18n
a language suffix is added to the property
name:
For example, a field is called 'simpleText' and has support for 'en, de, fr'. Default language is 'en'
Node name | Value |
---|---|
simpleText | Simple English Text |
simpleText_de | Einfache deutsche Text |
simpleText_fr | Simple text en francais |
OptionGroupPropertyHandler
In case of an OptionGroup
field is defined as multiselect
, the selected values are stored as a JCR multi-value-property. This JCR multi-value-property is normally handled as a List,
but the underlying Vaadin field is only working with Set
. This handler simply convert List
to Set
.
TextCodePropertyHandler
Simple TextCode Handler that return an empty String
instead of a null property
value.
TwinSelectPropertyHandler
Like for the OptionGroup
field, the underlying Vaadin Field need additional convertor between List
to Set
.
CompositeHandler
In addition to the CompositeField
and SwitchableField
default Handler
, we provide two additional CompositeHandler:
SubNodeCompositeHandler
SubNodeCompositeHandler
will store the property
values of the fields composing the composite field under the following format:
Node name | Element name | Value |
---|---|---|
formNode |
| |
composite | Composite field name | |
field1 | First field name composing the Composite field | Typed value in the First field |
field2 | Second field name composing the | Typed value in the Second field |
field3 | Third field name composing the | Typed value in the Third field |
This Handler
do not support i18n
(in Magnolia 5.1).
NoOpCompositeHandler
NoOpCompositeHandler
is useful if you want to combine a Multi filed storing individual field value into sub nodes with composite field as Multi field component.
In this case, the Multi field handler will create/read the node structure and pass a properties as PropertysetItem to the NoOpCompositeHandler
. This handler just act as a property container.
MultiHandler
MultiValuesPropertyMultiHandler
This is the default Handler
set for Multi fields. The fields values are stored in a JCR multi-value-property.
This will only work for simple fields like text/date/radio...
CommaSeparatedMultiHandler
Handler
storing the fields values as a String
with ',' as separator.
This will only work for simple fields like text/date/radio... and values are stored as String
.
SubNodesMultiHandler
Handler
storing the fields values in sub node property:
Node name | Element name | Value |
---|---|---|
formNode |
| |
00 | Incremental child node name | |
multi | Multi field name | Typed value in the First field |
01 | Incremental child node name | |
multi | Multi field name | yped value in the Second field |
02 | Incremental child node name | |
multi | Multi field name | Typed value in the Third field |
SubNodesMultiPropertysetItemHandler
Based on the previous NoOpCompositeHandler
o example:
Node name | Element name | Value |
---|---|---|
formNode |
| |
multi | Multi field name | |
00 | Incremental child node name | |
text | Text field name composing the | Typed value in the Text field |
date | Date field name composing the Composite field | Selected date |
select | Select field name composing the Composite field | Selected selection |
01 | Incremental child node name | |
text | Text field name composing the | Typed value in the Text field |
date | Date field name composing the Composite field | Selected date |
select | Select field name composing the Composite field | Selected selection |
02 | Incremental child node name | |
text | Text field name composing the | Typed value in the Text field |
date | Date field name composing the Composite field | Selected date |
select | Select field name composing the Composite field | Selected selection |
SubNodesMultiIdentifierHandler
Handler
creating first a child node (named as the multi field) and storing the fields values in sub node property:
Node name | Element name | Value |
---|---|---|
formNode |
| |
multi | Multi field name | |
038a2c75-2638-48e6-a | Incremental child node name | |
multi | Multi field name | 038a2c75-2638-48e6-a6ba-9bd2a9fe6c78 |
72e2ef55-6c11-4b0e-8 | Incremental child node name | |
multi | Multi field name | 72e2ef55-6c11-4b0e-8e02-d47c4ad41083 |
11bbf78b-4ecf-4e9f-a | Incremental child node name | |
multi | Multi field name | 11bbf78b-4ecf-4e9f-a06e-6181ef56d98c |
Limitation
How to
Open Issue
Default value handling
The field definition allows to define a default value as a String:
- Text field, type is String default value is 'default value'
- Text field, type is Long default value is 1000l
- ....
This default value should be displayed in the related form field if ????
- It is a new Form
- easy to implement
- if a field is added to an existing form, this default value will never be displayed.
- chooses solution
- If the property related to a form is null (currently if a property has an empty value, this property is removed or not saved)
- easy to implement
- if a user remove the default value associated to a field --> no property saved. When he will reopen this form, the default value will be displayed again
- ??