Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vaadin 14: Mark error message at TextField as warning

with Vaadin 14.1.23 TextFields I would like to differentiate visually between red error messages (e.g. "This value is too big.") and yellow warnings (e.g. "System will round your input to two decimals."). And optionally maybe blue info messages.

Therefore I created a TextField with a validator like in this example ( https://vaadin.com/components/vaadin-text-field/java-examples/validation ): When you type "1" into the field with label "Min 2 characters" then the field gets red and shows an error: "Minimum 2 characters".

Vaadin TextField with error message

How about showing a (yellow) warning message like this?

Wanted Vaadin TextField with warning message

What I tried is this: In the apply method of my validator I created a validation result with ErrorLevel WARNING like this:

ValidationResult.create("System will round the decimals.", ErrorLevel.WARNING);

But Vaadin generated still a div with part="error-message":

<div part="error-message" aria-live="assertive" aria-hidden="false" id="my-field-error-44">System will round your input to two decimals.</div>
like image 222
S. Doe Avatar asked Apr 04 '20 16:04

S. Doe


1 Answers

There is a way to achieve this effect.

First you need to create theme for vaadin-text-field. Create text-field-theme.css file in frontend/styles folder with content:

:host([class="warn"]) [part="error-message"] {
    color: orange;
}

:host([invalid][class="warn"]) [part="input-field"] {
    background-color: rgba(255, 166, 0, 0.1);
    box-shadow: inset 0 0 0 1px orange;
}

With this code you said: when text field has class "warn" error message is orange and box around input field is orange and input field background is transparent (0.1) orange.

Then import it in your view:

@CssImport(value = "./styles/text-field-theme.css", themeFor = "vaadin-text-field")

Then you bind field with 2 validators, one with error condition, and second with warning condition:

TextField textField = new TextField();
binder.forField(textField)
      .withValidator(e -> {
         textField.removeClassName("warn");
         return e.length() > 3;
      }, "You must enter more than 3 characters", ErrorLevel.ERROR)
      .withValidator(e -> {
         textField.addClassName("warn");
         return e.length() > 5;
      }, "Maybe you should enter more than 5 characters", ErrorLevel.WARNING)
      .bind(Person::getName, Person::setName);

This will work with binder.validate().isOk() as expected. For example when you enter 3 or less characters you will see red error message and binder.validate().isOk() will return false.

error example

And when you enter 4 or 5 characters you will see yellow warning message and binder.validate().isOk() will return true.

warning example

For blue info message process is same. Just duplicate code in .css file for "info" class and choose blue color. Then create third validator for info condition. Don't forget to add "info" class, and remove it in other validator conditions (error, warning).

like image 195
nemojmenervirat Avatar answered Oct 10 '22 20:10

nemojmenervirat