Как программно показать сообщение об ошибке в поле редактора сетки?(Ваадин 13) - PullRequest
2 голосов
/ 24 апреля 2019

У меня есть сетка для редактирования bean-компонентов, для которых реализована проверка уровня bean-компонента JSR-303. Поскольку BeanValidationBinder не поддерживает проверку на уровне bean, у нас есть собственная реализация для проверки этих ограничений между полями и отображения сообщений об ошибках проверки на недопустимых полях.

Теперь, у нас это хорошо работает в других случаях, но теперь у меня проблема с отображением сообщений об ошибках для полей внутри редактора сетки.

Вот упрощенный пример, где все строки проверяются при нажатии кнопки «Сохранить». Имя продукта считается недействительным, если оно не «Продукт». Только первая ошибка, которая встречается, это нормально.

Похоже, все сводится к productGrid.getEditor (). EditItem (p) -call в методе validate (Список продуктов). Если я пропущу это, сообщение об ошибке будет показано в редактируемом в данный момент поле. Конечно, это может быть не тот, который имеет недопустимые данные.

Сначала я попробовал более элегантное решение, в котором пользователь не мог оставить неверный ряд, но в данный момент я был бы готов согласиться на это, если бы смог заставить его работать. Мы использовали BenValidationBinder в исходном коде, который обрабатывает проверку единого поля JSR-303.

Я создал пример кода с использованием последней версии приложения Project Base (https://vaadin.com/start/latest/project-base), отредактировав класс MainView, как показано ниже. Запуск с Vaadin версии 13.0.3

У кого-нибудь еще были такие же проблемы и, надеюсь, решение для этого?

@Route("")
@PWA(name = "Project Base for Vaadin Flow", shortName = "Project Base")
public class MainView extends VerticalLayout {

    private Grid<Product> productGrid;
    private TextField code = new TextField();
    private TextField name= new TextField();


    public MainView() {

        List<Product> products = Arrays.asList(new Product("1", "Product"), new Product("2", "Product"));

        productGrid = new Grid<MainView.Product>();
        productGrid.addColumn(Product::getCode)
        .setHeader("Product code")
        .setFlexGrow(1);
        productGrid.addColumn(Product::getName)
        .setEditorComponent(name)
        .setHeader("Product name")
        .setFlexGrow(1);

        Binder<Product> binder = new Binder<>(Product.class);
        binder.bindInstanceFields(this);
        productGrid.getEditor().setBinder(binder);

        productGrid.addItemClickListener(event -> productGrid.getEditor().editItem(event.getItem()));
        productGrid.setItems(products);
        Button save = new Button("Save",
                event -> save(products));

        add(save);
        add(productGrid);
    }



    private void save(List<Product> products) {
        if(validate(products)) {
            Notification.show("Saved: " + String.join(", ", products.stream().map(Product::toString).collect(Collectors.toList())));
        }else {
            Notification.show("Invalid data");
        }
    }

    private boolean validate(List<Product> products) {
        // this only mocks the JSR-303 validation call
        for(Product p:products) {
            if(!p.getName().equals("Product")) {
                productGrid.getEditor().editItem(p);
                name.setErrorMessage("Invalid name, should be: Product");
                name.setInvalid(true);
                return false;
            }
        }
        return true;
    }

    public class Product{

        String code;
        String name;

        public Product(String code, String name) {
            super();
            this.code = code;
            this.name = name;
        }
        public String getCode() {
            return code;
        }
        public void setCode(String code) {
            this.code = code;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }

        public String toString() {
            return code + " " + name;
        }
    }

}

...