Cela a été demandé plusieurs fois, et pour autant que je sache, il n'est pas possible d'ajouter des validateurs sans le classeur. Vous pouvez vérifier this answer pour une description complète de la fonctionnalité et de la résonance.
Il y a aussi des discussions sur les Vaadin forum et github, et les 2 suggestions principales utilisent un classeur, ou un écouteur de changement de valeur où vous appelez manuellement un validateur. Cependant, cette dernière solution ne semble pas fonctionner et je suppose que c'est parce qu'un événement de changement de valeur n'est déclenché que lorsque la valeur réelle change, ce qui ne se produit probablement pas lorsque vous tapez quelque chose de non valide.
Le latest suggestion on github demande une méthode binder.noBind()
pour faciliter ces cas, mais jusqu'à ce que cela soit implémenté, vous pouvez utiliser quelque chose de similaire à l'exemple de code ci-dessous. J'ai aussi haï l'idée d'utiliser un champ pour lier la valeur, donc je suis allé avec un pas setter & pas getter concept:
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
};
}
}
}
Résultat:
Mise à jour ultérieure:
J'y ai réfléchi un peu plus, et si c'est acceptable, vous pouvez désactiver le bouton d'envoi si la valeur est nulle ou qu'une erreur d'analyse survient pour une valeur non valide. Cela peut être facilement mis en œuvre avec un ValueChangeListener
et un ErrorHandler
comme ci-dessous. Vous pouvez également enregistrer le message d'exception dans une variable et cliquer sur le bouton pour vérifier s'il existe un message d'erreur ou si la valeur est nulle, dans cet ordre, car si vous entrez une date non valide, la valeur du champ sera défini sur null.
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);
}
}
Résultat:
Comment utiliser 'Binder' (https://vaadin.com/api/8.0.1/com/vaadin/data/Binder.html)? 'Binder' vient avec des méthodes comme' validate() 'et' isValid() '. – Thibstars
Parfois, Binder ne fonctionne pas. Par exemple, mon formulaire n'a peut-être pas de POJO, etc. derrière lui, peut-être que j'utilise simplement le formulaire pour faire un calcul rapide sur une étiquette et que je ne veux pas le sauvegarder avec quoi que ce soit. –