info.magnolia.ui.field.MultiFieldDefinition renders a complex field composed of
one or more field sets (for example, three sets of two text fields). Magnolia provides
four preconfigured multi field definitions:
info.magnolia.ui.field.JcrMultiValueFieldDefinition:
allows you to enter multiple values of a single type to be stored as an
array in a single JCR property (jcrMultiValueField).
info.magnolia.ui.field.JcrMultiLinkFieldDefinition:
allows you to select multiple values of a single type in a chooser
dialog to be stored as an array in a single JCR property (jcrMultiLinkField).
info.magnolia.ui.field.JcrMultiFieldDefinition:
allows you to create multiple JCR fields (jcrMultiField).
info.magnolia.rest.ui.field.JsonMultiFieldDefinition:
allows you to create multiple JSON fields to be used in an app with its own
JSON
data source (jsonMultiField).
These multi field definitions are part of the Magnolia 6 UI framework.
Their fully qualified class names are:
In the Magnolia 5 UI framework, the field functionally parallel to the JCR fields is
Multivalue
field. There is no corresponding 5 UI implementation for the JSON
multi field.
ByMultiValueProperties for JcrMultiValueFieldDefinition
MultiFieldEntryResolution for JcrMultiFieldDefinition
MultiJcrBlockEntryResolution for MultiJcrBlockDefinition
JsonMultiFieldEntryResolver for JsonMultiFieldDefinition
Implementation class that defines how the child entries of a multi field
should be resolved.
MultiFieldEntryResolution of JcrMultiFieldDefinition extends ByIndexedChildNodes, which resolves entry nodes regardless of node names. To enable this non-strict resolution behavior, there is a strict property that is set to false by default.
Setting strict to true is necessary in certain compatibility configurations (for example, when porting configurations that use Magnolia 5 UI multi field transformers).
In problematic configurations, strict will fall back to the required value and that change will appear in the Definitions app.
orderHandler
optional, default is
MultiValuePropertyOrderHandler for JcrMultiValueFieldDefinition
DefaultJcrNodeOrderHandler for JcrMultiFieldDefinition
MultiJcrBlockOrderHandler for JcrMultiFieldDefinition
Implementation class that sorts nodes and ensures that the suffixes in
index names correspond to the order in which they are stored.
When MultiFormDefinition$OrderHandlerDefinition$Noop is used, the order of the items of a multi field cannot be changed retroactively.
canRemoveItems
optional, default is true for JcrMultiValueFieldDefinition and
JcrMultiFieldDefinition
When false, the items of a multi field cannot be removed from a
dialog.
buttonSelectAddLabel
optional, default is translated buttons.add key (translated dialogs.buttons.select.multiple key for JcrMultiLinkFieldDefinition)
Button label for adding an item. The value is
i18n-able.
buttonSelectRemoveLabel
optional, default is translated buttons.delete key
Button label for removing an item. The value is
i18n-able.
minItems
optional, default is 0
Specifies the minimum number of items to be added.
maxItems
optional, default is Integer.MAX_VALUE
Specifies the maximum number of items to be added.
If minItems is greater than maxItems, item count validation will be disabled.
itemCountErrorMessage
optional, default is translated validators.multi.itemCount.errorMessage key
Error message shown when the number of items is less than
minItems or greater than maxItems. The value can be literal or a
key of a
message
bundle.
required
optional, default is false
Makes the field required. An asterisk is displayed next to the field
label.
requiredErrorMessage
optional, default is translated validation.message.required key
Error message shown when required is set to true and
the user saves an empty field. The value can be literal or a
key of a
message
bundle.
Common complex field properties
Property
Description
name
required
Name of the field definition item. Derived from the configured node
name. Use alphanumeric characters without spaces.
class
required (unless $type is used)
Type of the field definition item. The value must be a fully qualified
class name and a subtype of info.magnolia.ui.field.FieldDefinition.
See
Field
types for possible values.
$type
You can use this as a shortcut for class if the definition class is
annotated with info.magnolia.ui.field.FieldType. The proper value is
defined by the annotation.
Do not use JcrMultiValueFieldDefinition with any item provider other than the default JcrPropertyProvider.
description
optional
Help text displayed when the user clicks the help icon. The value can be
literal or a
key
of a
message
bundle.
i18n
optional, default is false
Enables i18n
authoring support, which allows editors to write foreign-language or
regionally targeted content. A two-letter language identifier (en,
de, fr, etc.) is displayed on controls where i18n is set to
true.
When defining the property for a multi field,
the following configurations are possible:
To translate a unique set of entries, set i18n to false for the multi field and to true for its inner fields.
To translate different sets of entries, set i18n to true for the multi field and to false for its inner
fields (no fallback here between languages).
We do not recommend setting i18n to true on both levels.
label
optional
Field label displayed to editors. The value can be literal or a
key
of a
message
bundle.
If you do not provide the property, Magnolia will fall back to a
generated i18n key.
If you do not want to have any label, set the property to an empty
string such as label: "" in YAML.
styleName
optional
Additional style information for an editor property definition item applied to the element when the form is rendered.
The value can be a CSS class or a list of CSS classes separated by white spaces.
The style name will be rendered as an HTML class name, which can be used in a CSS definition.
The class name is added to the field by calling the Vaadin method addStyleName.
To validate that jcrMultiValueField has only unique values, you can create UniqueValuesMultiFormView
as an implementation class that extends MultiFormView.
publicclassUniqueValuesMultiFormView<T> extendsMultiFormView<T> {
@InjectpublicUniqueValuesMultiFormView(MultiFormDefinition<T> definition, LocaleContext localeContext, Datasource<T> datasource){
super(definition, localeContext, datasource);
}
@Overridepublic List<BinderValidationStatus<?>> validate() {
final List<BinderValidationStatus<?>> validate = super.validate();
if (validate.stream().allMatch(BinderValidationStatus::isOk)) {
List<String> valuesStringList = validate.stream()
.map(v -> v.getBinder().getFields().findFirst().get().getValue()) // could be any data type other than string
.map(String::valueOf)
.collect(Collectors.toList());
if (new HashSet<>(valuesStringList).size() != valuesStringList.size()) {
final Binder.Binding<?, ?> binding = validate.stream()
.flatMap(binderValidationStatus -> binderValidationStatus.getFieldValidationStatuses().stream())
.map(BindingValidationStatus::getBinding)
.findFirst()
.orElse(null);
final BindingValidationStatus<?> validationStatus = new BindingValidationStatus<>(Result.error("All values has to be unique"), binding);
binding.getValidationStatusHandler().statusChange(validationStatus);
validate.add(new BinderValidationStatus<>(null, Collections.singletonList(validationStatus), new ArrayList<>()));
}
}
return validate;
}
}Copy