Validation
ValidationService
A ValidationService
is a simple functional interface that creates a MessageList containing validation result messages. In order to make use of a ValidationService
in a BindingManager
, it must be passed as an argument to the BindingManager's constructor. As described in Binding, BindingContext, BindingManager it is part of the BindingManager
and not of a BindingContext
because validation violations may refer to other input fields that are not part of the current BindingContext
.
As mentioned in Binding to the Domain Model a linkki application consists of multiple layers.
Most validations work on the domain model because the goal of the validation is to validate the data of the domain model itself. Other components, like services or batch processes can then also make use of those validations.
In most applications the validation service simply calls the domain model validation and collects all messages. In order to avoid a dependency from the domain model to linkki it is good practice to use an own implementation for messages in the domain model. In this case the validation service is also responsible for converting from domain layer messages to a linkki MessageList
.
ValidationDisplayState
When a user enters a page containing required fields, it is usually not desirable to greet him with a lot of validation error messages without a chance to enter the values first. linkki supports a more pleasant experience with the ValidationDisplayState
: HIDE_MANDATORY_FIELD_VALIDATIONS
filters all messages with a ValidationMarker returning true
for isRequiredInformationMissing()
while SHOW_ALL
does not filter messages.
The ValidationService
can return a ValidationDisplayState
via getValidationDisplayState()
and offers the method getFilteredMessages()
that takes the messages from getValidationMessages()
and applies the ValidationDisplayState’s `filter
method. It is good practice to switch the ValidationDisplayState
once the user has triggered a submit button or another page advancement mechanism.
Message and MessageList
A Message
has a human readable text, an error code and a Severity
(one of INFO
, WARNING
, ERROR
). It may also contain a set of ObjectProperties to refer to specific invalid properties of an object. Additionally there may be ValidationMarkers to distinguish different kinds of validation messages.
The easiest way to create a Message
is to use its builder (via the builder()
method). Alternatively, a Message
can also be created using the static factory methods (newError(String, String)
, newWarning(String, String)
, newInfo(String, String)
) or by directly calling the constructor.
Message message = Message.builder(getValidationMessage("Info validation message"), Severity.INFO)
.invalidObjectWithProperties(invalidObject, PROPERTY_COMBO_BOX_VALUE)
.invalidObjectWithProperties(invalidObject, PROPERTY_READ_ONLY_TEXT_FIELD)
.create();
A MessageList
is a container for a list of messages and provides an API to access the messages, for example by using filters.
ObjectProperties
A linkki message uses a set of ObjectProperty
to identify which properties and objects the message refers to. An ObjectProperty
consists of a reference to the bound object as well as the property’s name. If the property has an indexed type, the ObjectProperty
can additionally contain the index of the referred value in its collection.
ValidationMarker
ValidationMarkers
are used to group and categorize messages. By default, linkki can differentiate between mandatory-field validations and other messages using the validation marker ValidationMarker#REQUIRED
. UI elements referring to messages that use this marker are not highlighted as long as a user hasn’t had a chance to enter any values (see ValidationDisplayState). The method isMandatoryFieldMessage
on a Message
can be used to check if any of the message’s markers return true
for isRequiredInformationMissing
:
Applications can introduce their own specialized validation markers by implementing the ValidationMarker
interface. That way special meaning can be attached to messages and they can be categorized and processed accordingly, if required.