Step 10: Validation in dialogs
This step shows you how to validate user input in dialogs. |
As you may have noticed, you can add an empty address to the addresses table. This can be considered invalid, and it can be avoided by using Validation, which is a way to tell the user whether the input fits the domain model logic.
Marking input fields as required
To inform the user which fields have to be filled in, the fields can be visually marked as required. Set the property required
to RequiredType.REQUIRED
for all fields in AddressPmo
.
Specifying the RequiredType will only display a blue point. It does not prevent the user from leaving the field empty, nor will it display the validation rule that is violated by doing so.
|
The finished implementation should look like this:
@UITextField(..., required = RequiredType.REQUIRED)
public void street() {
...
@UITextField(..., required = RequiredType.REQUIRED)
public void streetNumber() {
...
@UITextField(..., required = RequiredType.REQUIRED)
public void postalCode() {
...
@UITextField(..., required = RequiredType.REQUIRED)
public void city() {
...
@UITextField(..., required = RequiredType.REQUIRED)
public void country() {
...
If you run your application, you should see a blue point next to the label of each field:
Validating the input fields
Validations typically have a justification in the domain model. If for example an attribute is mandatory, this information should be handled by the implementation in the domain model so that all applications that use the same model follow the same logic.
In this case, the domain model class Address
implements a method validate()
. This method returns a list of validation messages that contain the justification as well as which attributes of which objects they refer to. The only thing left for you to do is to transfer these messages to the fields in the UI.
In linkki, displaying and distributing validation messages are handled by so-called ValidationServices
. Whenever a dialog is created with the help of a PmoBasedDialogFactory
, it is possible to pass a ValidationService
that is used in all dialogs created by that factory.
Implement the validation in the method AddressPage.createNewAddress
:
-
Assign a lambda expression, in which
address.validate()
is passed toorg.linkki.ips.messages.MessageConverter.convert()
, to a variablevalidationService
of typeValidationService
. -
Assign a new instance of
PmoBasedDialogFactory
, withvalidationService
passed as the argument, to a variabledialogFactory
of typePmoBasedDialogFactory
. -
Use
dialogFactory
when creating theOkCancelDialog
.
To be able to use the MessageConverter
you need to add the following dependency:
<dependency>
<groupId>org.linkki-framework</groupId>
<artifactId>linkki-ips-vaadin-flow</artifactId>
<version>${linkki.version}</version>
</dependency>
The finished implementation should look like this:
public void createNewAddress() {
...
ValidationService validationService = () -> MessageConverter.convert(address.validate());
PmoBasedDialogFactory dialogFactory = new PmoBasedDialogFactory(validationService);
OkCancelDialog addressDialog =
dialogFactory
.newOkCancelDialog("Add Address", okHandler, dialogPmo);
...
}
If you run your application and try to add an address without filling in all the fields, you should get an error saying e.g. "The field Street must not be empty.".