Hello,
I am trying to dynamically change the validator of a TypedTextField<Double>
based on the value of another component. However, it doesn’t seem to be working because the validators appear to be stacking instead of replacing each other, causing multiple validations to be applied simultaneously.
How can I ensure that only one validator is active at a time?
Here is my code:
dialogs.createInputDialog(this)
.withHeader("Type de fichier")
.withParameters(
InputParameter.stringParameter("invoiceNumber").withLabel("Numéro de facture").withRequired(true)
.withRequiredMessage("Le numéro de facture est obligatoire"),
InputParameter.bigDecimalParameter("ht").withLabel("Montant HT").withRequired(true)
.withRequiredMessage("Le montant HT est obligatoire"),
InputParameter.bigDecimalParameter("ttc").withLabel("Montant TTC").withRequired(true)
.withRequiredMessage("Le montant TTC est obligatoire"),
parameter("certifType")
.withLabel("Type de certification")
.withField(() -> {
JmixComboBox<CertificationType> certifTypeCb = uiComponents.create(JmixComboBox.class);
certifTypeCb.setItems(certificationTypes);
certifTypeCb.setWidthFull();
certifTypeCb.setEnabled(!certificationTypes.isEmpty());
certifTypeCb.setRequired(!certificationTypes.isEmpty());
certifTypeCb.setRequiredMessage("Le type de certification est obligatoire");
if (!certificationTypes.isEmpty()) {
certifTypeCb.setValue(certificationTypes.getFirst());
}
return certifTypeCb;
}),
parameter("certifValue")
.withLabel("Valeur")
.withField(() -> {
TypedTextField<Double> certifValue = uiComponents.create(TypedTextField.class);
certifValue.setDatatype(datatypeRegistry.get(Double.class));
certifValue.setId("certifValueField");
certifValue.setTooltipText(productCertification.getTonDelivered() + " tonnes");
certifValue.setWidthFull();
certifValue.setRequired(!certificationTypes.isEmpty());
certifValue.setRequiredMessage("Le valeur est obligatoire");
JmixComboBox<String> unitCb = uiComponents.create(JmixComboBox.class);
unitCb.setItems(Arrays.asList("T", "%"));
unitCb.setId("unitCb");
unitCb.setValue("%");
createPourcentageValidator(certifValue);
unitCb.setWidth("70px");
unitCb.setAllowCustomValue(false);
certifValue.setSuffixComponent(unitCb);
certifValue.setEnabled(!certificationTypes.isEmpty());
unitCb.addValueChangeListener(changeEvent -> {
String selectedUnit = changeEvent.getValue();
if ("%".equals(selectedUnit)) {
createPourcentageValidator(certifValue);
} else if ("T".equals(selectedUnit)) {
// Supprimer la validation si l'unité n'est pas '%'
certifValue.addValidator(value -> {
if (value != null && (value < 0 || value > productCertification.getTonDelivered().doubleValue())) {
throw new ValidationException("La valeur de tonnes certifiées ne peut être supérieure à la quantité livrée.");
}
});
certifValue.setTypedValue(0.0);
} else {
unitCb.setValue("%");
}
});
return certifValue;
})
)
.withActions(DialogActions.OK_CANCEL)
.withCloseListener(closeEvent -> validateUpload(closeEvent, certificationTypes, productCertification, fileContent, fileName)).open();
public void createPourcentageValidator(TypedTextField<Double> certifValue) {
// Appliquer une restriction entre 0 et 100
certifValue.addValidator(value -> {
if (value != null && (value < 0 || value > 100)) {
throw new ValidationException("La valeur doit être comprise entre 0 et 100 si l'unité est '%'.");
}
});
certifValue.setTypedValue(0.0);
}
Thank you in advance for your help.
Best regards,
Thomas