-
Create a new static class in the annotation class that implements the interface
ComponentDefinitionCreator
.-
Use your annotation type as generic type.
-
Implement the
create
method. You can use a lambda directly and then reuse the implemention ofnewComponent()
of yourBindingDefinition
.
-
-
In the annotation class, replace
BindingDefinitonComponentDefinition.Creator.Class
with the new implementation ofComponentDefinitionCreator
.
Release Notes
Version 1.4.8
Bugfixes
-
Enable the usage of Vaadin icons within the HTML content mode of
@UILabel
by whitelisting the attributesclass
andstyle
for the HTML tag<span>
.
Version 1.4.7
Bugfixes
Sanitization of HTML content
Using @UILabel
with htmlContent = true
previously did not sanitize the content. To make the behaviour of htmlContent = true
more secure by default, the HTML is now automatically sanitized, removing potentially dangerous tags and attributes. Note that the img
tag is whitelisted.
When user-supplied strings are included in HTML content, they have to be escaped to prevent them from being interpreted as HTML. This can be achieved by using |
Version 1.4.6
Bugfixes
-
Sanitization of HTML content in notifications and dialogs
Version 1.4.5
Bugfixes
-
UILabel
in tables now wrap instead of being cut off if the column was not wide enough to display the whole text.
Version 1.4.4
The Vaadin version was updated to 8.14.3.
Version 1.4.3
The Vaadin version was updated to 8.14.2.
Bugfixes
Combo boxes with more than 500 values did not work since vaadin 8.14.1 to prevent DoS attacks. To work around this problem, linkki enables paging for all combo boxes with more than 500 values. This also improves the performance for combo boxes with a lot of values.
Version 1.4.2
The Vaadin version was updated to 8.14.1.
Bugfixes
-
@UILink
behaves like a label if the link location (href) is empty.
Version 1.4.1
Bugfixes
-
Fixed the bug in
IpsPropertyDispatcher
that fields with an empty value set are set as required.
Version 1.4.0
New features and improvements
New aspect annotation: @BindVisible
For the annotation @BindVisible, the VisibleType
is set to DYNAMIC
, determining the visible state from the PMO by invoking a method named is[PropertyName]Visible()
. Using this annotation, it is no longer necessary to specify the visible
property with VisibleType.DYNAMIC
in components, e.g. @UILabel
. The @BindVisible can be used on any PMO, including any PMO classes that implement the ContainerPmo
interface (i.e. TableSections
). Using @BindVisible will overrule the existing visible
property.
New BoundPropertyCreator
: ModelBindingBoundPropertyCreator
The annotation @LinkkiBoundProperty
now has a default value of the type ModelBindingBoundPropertyCreator
. Using this BoundPropertyCreator
it is very simple to create a new @UI-Field Annotation with model binding support. For more information read the corresponding documentation about BoundProperty.
Concept of BindingDefinition
is deprecated
The concept of BindingDefinition
is deprecated as it has already been replaced by new machenisms described in Creating a custom UI element. Therefore, the following classes and interfaces are deprecated and should not be used anymore.
-
org.linkki.core.binding.descriptor.bindingdefinition.BindingDefinition
and all extending classes -
org.linkki.core.binding.descriptor.bindingdefinition.annotation.LinkkiBindingDefinition
-
org.linkki.core.uicreation.BindingDefinitionComponentDefinition
-
org.linkki.core.ui.element.annotation.FieldAspectDefinitionCreator
Migration of custom annotations based on BindingDefinition
At the end of the migration, your custom UI annotation should not use LinkkiBindingDefinition
anymore. In addition, all of the logic in the impelementation of BindingDefinition
should have been moved to other classes so that the class can be removed.
The BindingDefinition
interface consists of the following methods whose content have to be moved to new classes:
- Component creation method
Object newComponent()
-
This method defines how a UI component should be created. To migrate its content:
Table 1. Example Before After ... @LinkkiComponent(BindingDefinitionComponentDefinition.Creator.class) //2 public @interface UIFancy { ... }
... @LinkkiComponent(FancyComponentCreator.class) //2 public @interface UIFancy { ... static class FancyComponentCreator implements ComponentDefinitionCreator<UIFancy> { //1 public LinkkiComponentDefinition create(UIFancy annotation, AnnotatedElement annotatedElement) { return pmo -> { // Creates new component from annotation }; } } }
public class FancyBindingDefinition implements BindingDefinition { private UIFancy annotation; public Object newComponent() { // Creates new component from annotation } ... }
- Model binding methods
String modelObject()
andString modelAttribute()
-
These methods define how the model object and model attribute names should be derived from the annotation. To support model binding without
BindingDefinition
:-
In the annotation class, remove the argument
BindingDefinitionBoundPropertyCreator
-
Annotate the annotation attribute that defines the model object name with
LinkkiBoundProperty.ModelObject
-
Annotate the annotation attribute that defines the model attribute name with
LinkkiBoundProperty.ModelAttribute
Table 2. Example Before After ... @LinkkiBoundProperty(BindingDefinitionBoundPropertyCreator.class) //1 public @interface UIFancy { String modelObject() ... ; String modelAttribute() ... ; ... }
... @LinkkiBoundProperty //1 public @interface UIFancy { @LinkkiBoundProperty.ModelObject //2 String modelObject() ... ; @LinkkiBoundProperty.ModelAttribute //3 String modelAttribute() ... ; ... }
If your annotation doesn’t support model binding, you should use
SimpleMemberNameBoundPropertyCreator
instead. -
- Aspect methods
String label()
,EnabledType enabled()
,VisibleType visible()
,RequiredType required
-
These methods define values that are necessary for the aspects. The aspects that were supported by default are:
-
label
-
enabled
-
visible
-
required
-
value
-
derived read-only (readonly if setter method is missing)
To support these aspects without
BindingDefinition
:-
Create a new implementation of
ApsectDefinitionCreator
-
Use the annotation type as generic type
-
In the create method, create a new
CompositeAspectDefinition
that contains the apsects above (see example below).
-
-
Replace
FieldAspectDefinitionCreator
with the new customAspectDefinitionCreator
Table 3. Example Before After ... @LinkkiAspect(FieldAspectDefinitionCreator.class) //2 public @interface UIFancy { String label() ... ; EnabledType enabled() ... ; VisibleType visible() ... ; RequiredType required() ... ; ... }
... @LinkkiAspect(FancyAspectDefinitionCreator.class) //2 public @interface UIFancy { ... static class FancyAspectDefinitionCreator implements AspectDefinitionCreator<UIFancy> { //1 @Override public LinkkiAspectDefinition create(UIFancy annotation) { EnabledAspectDefinition enabledAspectDefinition = new EnabledAspectDefinition(annotation.enabled()); RequiredAspectDefinition requiredAspectDefinition = new RequiredAspectDefinition( annotation.required(), enabledAspectDefinition); return new CompositeAspectDefinition(new LabelAspectDefinition( annotation.label()), enabledAspectDefinition, requiredAspectDefinition, new VisibleAspectDefinition(annotation.visible()), new DerivedReadOnlyAspectDefinition()); } }
-
Faktor-IPS Property Dispatcher uses the value set information to set field properties in the UI
The IpsPropertyDispatcher
can now derive the required
, visible
and enabled
state of a field based on the value set of its model attribute. This functionality is described in the section about IpsPropertyDispatcher. If the IpsPropertyDispatcher
is already in use, this new feature will automatically come into effect with the new version.
Update all binding contexts in BindingManager
BindingManager
now has a new method updateAll
which updates all BindingContexts
that are managed by the BindingManager
. This is a costly operation that should be used with caution.
Dependencies updated
Dependencies used by linkki have been updated.
Different date format for English locale
The short date format (1/1/21) in DateFormats
has been replaced with a date format displaying the full year and leading zeroes (01/01/2021).
linkki for Vaadin 14
linkki now includes modules using Vaadin version 14 for a first developer preview.
Bugfixes
-
Fixed typo in ReadOnlyBehaviorType#INVISIBLE
-
Fixed log warnings due to depreacted method call in
SidebarLayout
. SidebarLayout.SelectionListener is now serializable, consider adding a serialVersionUID.
-
Fixed tooltip on labels not showing HTML content
-
Fixed an error when entering a year with five or more digits
-
Fixed UIDateField always showing english error message