Related issue
DEV-883
-
Getting issue details...
STATUS
Goal
We want to provide users with a simple, modern API to build arbitrarily complex fields.
Problem
All is good, as long as a simple value is bound to a simple field, e.g. TextField → String.
But what if I need a field manage a complex nested value, i.e. if I have to manage hierarchical data?
Currently Magnolia does provide such ability through custom multi fields (see AbstractCustomMultiField) but they have several shortcomings, both in terms of internal implementation and from a client developer's perspective (see for instance MGNLUI-2542 - Getting issue details... STATUS ).
Proposal
Assume the field is simple and atomic
When you need to manage many related values - it is another form within a form
Complex fields are like forms but with stripped layout
Layouting
Form (or editor) layout should be separated from the binding mechanism and should be flexible
first we produce the field/sub-form components and bind them to the binder
then we pass the mapping of e.g. the property names and the resulting components (fields/sub-forms) to a layout producer
the layout producer could yield a tabbed layout that we have currently or any other type of layout based on the configured definition
A class diagram from the current PoC and a description of their main responsibilities
FormDefinition
- is a ComponentDefinition
- is registered and mapped to a factory class like any other form field
- has FieldDefinition(s)
- has a
LayoutDefinition
LayoutDefinition
- has a list of field names composing the layout. Their names match those of the FieldDefinition(s)
- specifies
LayoutProducer
implementation class
LayoutProducer
- is instantiated from a LayoutDefinition
- createLayout(LayoutDefinition, Map<String, Component>) creates the actual layout (a Vaadin Component) from
- LayoutDefinition
- a mapping of field names and actual field components
Form
is a plain Java class
- it stores
- its Binder
- its own Layout (including sub-form layouts)
- its sub-forms
- can save and validate self and its sub-forms recursively (should this functionality move away from Form?)
FormPresenter
- is currently the orchestrator of the form building process
- creates the final form view (a Vaadin Layout)
- instantiates a Form from a FormDefinition
returns the form view to the caller
TODO
We now have the basic infrastructure to build and bind form components (including arbitrarily nested, complex sub-forms). We can also read and write them without the need for special transformers.
What is left to do.
- Form
- styling
set labels, help messages and descriptions: use something like info.magnolia.ui.dialog.formdialog.FormView?
update forms/fields based on Locale? See info.magnolia.ui.dialog.formdialog.FormPresenterImpl.updateForm()
pass FormPresenter to DetailPresenter(..) which takes care of initializing actions and other stuff before calling and setting the form view?
- Fields
- implement them or harden the ones which we began to implement (TextField, SelectField)
- populating select options based on the value of another field
- validating a field depending on the value of another field (including within a composite field itself)
- enabling/disabling fields conditionally
- potentially custom handling of any field, via plain Vaadin code
- properly highlighting validation on sub-fields.
- FormBinder/FormContext
- currently saving a new item fails cause the node id we get is null.
- Layout
- naming
- naming