如何确定是否将DateField在Vaadin 8

问题描述:

是有效的,我有:如何确定是否将DateField在Vaadin 8

DateField dateField = new DateField("Date"); 
Button submitButton = new Button("Submit"); 
submitButton.addClickListener(click -> handleClickListener()); 

其中handleClickListener()我希望阻止提交如果在DateField验证错误。我知道我可以使用一个活页夹,然后binder.validate()但这种形式没有支持对象,我只是想要一个简单的形式。我怎么可以这样做:

if(!dateField.isValid()) 
    // no further processing 
else 
    // process 

我找不到允许检查,看看是否在输入值是有效的DateField中的任何代码。显然in Vaadin 7 you could !dateField.validate() which would throw an exception,但这不再是似乎是这种情况...

我也知道有可能做dateField.isEmpty()或测试为null,但这是行不通的,因为一个值是不需要的。换句话说,它可以是空的,或者如果你输入一个值,那么它必须是一个有效的条目。

+0

如何使用'Binder'(https://vaadin.com/api/8.0.1/com/vaadin/data/Binder.html)? 'Binder'带有'validate()'和'isValid()'方法。 – Thibstars

+0

有时候,Binder不起作用。例如,我的表单可能没有POJO等,也许我只是使用表单对标签进行快速计算,而不想用任何东西来支持它。 –

这已被问过好几次了,据我所知,不可能在没有活页夹的情况下添加校验器。您可以检查this answer以了解功能和谐振的全面描述。

也有关于Vaadin forumgithub的讨论,并且2个主要建议是使用活页夹或值更改侦听器(您在其中手动调用验证程序)。然而,后一种解决方案似乎并不奏效,我怀疑这是因为价值变化事件只有在实际值发生变化时才会触发,当您输入无效时可能不会发生这种情况,但我没有花太多时间进行调查。

latest suggestion on github请求binder.noBind()方法来促进这些情况,但在实现该方法之前,您可以使用类似于以下代码示例的方法。我也讨厌使用字段的值绑定的想法,所以我用就没有setter & 没有消气概念:

public class DateFieldWithValidator extends VerticalLayout { 

    public DateFieldWithValidator() { 
     // date field with binder 
     Binder<LocalDate> binder = new Binder<>(); 
     DateField dateField = new DateField("Date"); 
     binder.forField(dateField) 
       .asRequired("Please select a date") 
       .bind(No.getter(), No.setter()); 

     // validity status 
     TextField validityField = new TextField("Status:", "N/A"); 
     validityField.setReadOnly(true); 
     validityField.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS); 
     validityField.setWidth("100%"); 

     // submit button 
     Button submitButton = new Button("Submit"); 
     submitButton.addClickListener(event -> { 
      BinderValidationStatus<LocalDate> status = binder.validate(); 
      if (status.isOk()) { 
       validityField.setValue("OK: " + dateField.getValue().toString()); 
      } else { 
       validityField.setValue("KO: " + status.getValidationErrors().stream().map(ValidationResult::getErrorMessage).collect(Collectors.joining(","))); 
      } 
     }); 

     addComponents(dateField, submitButton, validityField); 
    } 

    // convenience empty getter and setter implementation for better readability 
    public static class No { 
     public static <SOURCE, TARGET> ValueProvider<SOURCE, TARGET> getter() { 
      return source -> null; 
     } 

     public static <BEAN, FIELDVALUE> Setter<BEAN, FIELDVALUE> setter() { 
      return (bean, fieldValue) -> { 
       //no op 
      }; 
     } 
    } 
} 

结果:

date field validation with binder


稍后更新:

我一直在想更多,如果它是可以接受的,你可以禁用提交按钮,如果该值为空或解析错误发生无效值。这可以通过如下的ValueChangeListenerErrorHandler来轻松实现。

或者,您可以将异常消息保存在变量中,并且当您单击该按钮时,检查是否存在错误消息或值为空,按此顺序,因为如果输入的日期无效,则字段的值将被设置为空。

public class DateFieldWithValidator extends VerticalLayout { 
    public DateFieldWithValidator() { 
     DateField dateField = new DateField("Date"); 
     Button submitButton = new Button("Submit"); 
     submitButton.setEnabled(false); 
     submitButton.addClickListener(event -> Notification.show("Selected date: " + dateField.getValue())); 
     dateField.setRequiredIndicatorVisible(true); 
     dateField.setErrorHandler(event -> submitButton.setEnabled(false)); 
     dateField.addValueChangeListener(event -> submitButton.setEnabled(event.getValue() != null)); 
     addComponents(dateField, submitButton); 
    } 
} 

结果:

vaadin date field validation

+0

这与我所做的非常接近。您基本上创建了一个假的POJO(或类似的东西)来绑定到Binder,然后在单击Submit按钮时使用绑定器的验证。 –

+0

@StephaneGrenier是的,这是非常想法,至少暂时...... – Morfic

+0

@StephaneGrenier第二种方法怎么样? – Morfic

即使你说你不希望使用一个支持对象,我会建议使用Binder反正。@Morfic提供的No类在我看来非常出色(我倾向于在许多验证实现中重用这个)。

所以我会做的是在你的粘结剂添加addStatusChangeListener和启用/禁用有按钮:

binder.addStatusChangeListener(event -> { 
      if (event.hasValidationErrors()) { 
       submitButton.setEnabled(false); 
      } else { 
       submitButton.setEnabled(true); 
      } 
     }); 

省略Binder对象的实例,因为@Morfic在他的回答提供了一个很好的例子已经。

我之所以建议使用的Binder是因为Vaadin suggests to use it for validation,你不需要难以维持值变化监听,你可以很容易地扩大与新Validator是你绑定如果需要的话以后。也许你会希望在一个点上将该字段绑定到一个对象上。