How to add Validators in Vaadin 8?

时光怂恿深爱的人放手 提交于 2019-12-04 00:38:04

问题


In Vaadin 7 there was an addValidator function, but in Vaadin 8 it does not exist.

Vaadin 7 Example:

   TextField user = new TextField("User:");
   user.setRequired(true);
   user.setInputPrompt("Your username");
   user.addValidator(new NullValidator("Username can't be empty", false));
   user.setInvalidAllowed(false);

回答1:


I found the answer here: Whats New

Example:

new Binder<Person>().forField(tf)
    .withValidator(str -> str.length() == 4, "Must be 4 chars")
    .withConverter(new StringToIntegerConverter("Must be Integer"))
    .withValidator(integer -> integer.equals(2017), "Wrong date")
    .bind(Person::getBirthYear, Person::setBirthYear);




回答2:


The accepted Answer by Diego D looks correct. That code looks to be taken from this very brief (3 minutes) but very helpful video published by the Vaadin company, Type safe validation before and after converters. Shows the new Vaadin 8 approach to validation. I'll add some notes, show expanded syntax, and provide full example code for a full working app.

Validator + Binder

One big difference in Vaadin 8 is that validators require the use of a binder. In the old days, you attached a validator to a field, but now in Vaadin 8 you attach a validator only to a binder. The Vaadin team recognizes that for some simple situations this requirement of a binder may prove annoying, but for the most part they sensibly expect situations needing validation are quite likely also doing binding. A very logical re-think, I believe. Discussed in another Vaadin company video, Webinar: What's new in Vaadin 8?.

Validation & converters

We define two different validators, one to be called before a converter converts the user’s data-entry and another to be called after conversion. So the order of the fluent-style withValidator and withConverter method calls is key to correct behavior here. Of course beforeConversion and afterConversion are poor names for validator objects, but are done so to make clear the intent of running before or after converter in this demo.

Lambda synax optional

One validator uses conventional Java code style overriding a method. The other validator uses Lambda syntax. Watch the video and see the Diego D Answer for code further simplified with single-line Lambda arguments.

package com.example.valapp;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.data.Binder;
import com.vaadin.data.ValidationResult;
import com.vaadin.data.Validator;
import com.vaadin.data.ValueContext;
import com.vaadin.data.converter.StringToIntegerConverter;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.*;

import javax.servlet.annotation.WebServlet;


/**
 * This UI is the application entry point. A UI may either represent a browser window
 * (or tab) or some part of a html page where a Vaadin application is embedded.
 * <p>
 * The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
 * overridden to add component to the user interface and initialize non-component functionality.
 */
@Theme ( "mytheme" )
public class MyUI extends UI {

    @Override
    protected void init ( final VaadinRequest vaadinRequest ) {

        final TextField tf = new TextField ( "Enter year of birth:" );

        Validator<String> beforeConversion = new Validator < String > ( ) {
            @Override
            public ValidationResult apply ( String s, ValueContext valueContext ) {
               if(s.length ()!= 4) {
                   return  ValidationResult.error ( "Year must consist of 4 digits" );
               } else {
                   return  ValidationResult.ok () ;
               }
            }
        } ;

        Validator<Integer> afterConversion = Validator.from ( value -> value.equals ( 2017 ), "Wrong year." );

        new Binder < Person > ( )
                .forField ( tf )
                .withValidator ( beforeConversion )
                .withConverter ( new StringToIntegerConverter ( "Input must be Integer" ) )
                .withValidator ( afterConversion )
                .bind ( Person:: getYearOfBirth, Person:: setYearOfBirth );

        Button button = new Button ( "Tell me" );
        button.addClickListener ( event -> Notification.show("This is the caption", "This is the description", Notification.Type.HUMANIZED_MESSAGE) );

        setContent ( new VerticalLayout ( tf  , button ) );
    }

    @WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
    @VaadinServletConfiguration ( ui = MyUI.class, productionMode = false )
    public static class MyUIServlet extends VaadinServlet {
    }
}



回答3:


What if you don't have a binder due to creating a dynamic form?

Vaadin 8.1 supports removing the binder for a field which supports dynamic forms. If you make a field invisible then remove the binder for that field. Re-add the binder when you make the field visible.



来源:https://stackoverflow.com/questions/42491883/how-to-add-validators-in-vaadin-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!