Custom validation not using default message

Hi

I made a custom validation class as described in the doc and violations are filtered by ScreenValidation.

Hereunder the code of the method the validator uses to publish a violation, maybe that is where the issue is.

 protected void addViolation(ConstraintValidatorContext ctx, String field, String message) {
        ok = false;
        if (wrongFields.contains(field))
            return; // already reported
        wrongFields.add(field);
        ctx.disableDefaultConstraintViolation();
        ctx.buildConstraintViolationWithTemplate(message)
                .addPropertyNode(field)
                .addConstraintViolation();
    }

In platform screen validation, my violations are filtered because I guess I use addPropertyNode but if I use addBeanNode I cannot define property name.

My goal is that the violations are then processed by CUBA so that it can display in red all incorrect fields.

ScreenValidation of the platform:

    public ValidationErrors validateCrossFieldRules(@SuppressWarnings("unused") FrameOwner origin, Entity item) {
        ValidationErrors errors = new ValidationErrors();

        Validator validator = beanValidation.getValidator();
        Set<ConstraintViolation<Entity>> violations = validator.validate(item, UiCrossFieldChecks.class);

        violations.stream()
                .filter(violation -> {
                    Path propertyPath = violation.getPropertyPath();

                    Path.Node lastNode = Iterables.getLast(propertyPath);
                    return lastNode.getKind() == ElementKind.BEAN;
                })
                .forEach(violation -> errors.add(violation.getMessage()));

        return errors;
    }

Regards
Michael

Hi

Sorry for double post, solved the 1st point (getting errors not filtered by ScreenValidation) by calling addBeanNode() in validator code.

However now, I would like all components to be circle in red as in standard validation. Not sure how to that with a cross fields check validator.

        ctx.buildConstraintViolationWithTemplate(message)
                .addPropertyNode(field)
                .addBeanNode()
                .addConstraintViolation();

Regards
Michael

Hi, @michael.renaud!

Yes, cross field validation checks only Bean nodes as you can see in the validateCrossFieldRules().

About highlighting fields. Unfortunately, it is not possible to indicate which fields are invalid using cross-field validation. Cross-field validation is used for validating entity before commit in general. It can be used not only from editor and we cannot track which fields should be highlighted. Moreover, error state in fields is internal and it can be changed only by validating.

Possibly, in addition to your cross-field validating class, you can add field validator from the controller where it is possible to get access to the edited entity. In this case, it will be highlighted with the given message.

@Inject
private DateField<Date> endDateField;

@Subscribe
public void onInit(InitEvent event) {
    endDateField.addValidator(endDate -> {
        if (endDate.getTime() < getEditedEntity().getDate().getTime()) {
            throw new ValidationException("Incorrect date range");
        }
    });
}

Thanks @Pinyazhin

It could be an interesting feature to add to cuba: allow us to set a field in error or in red circled.

Because in my cross-check validator I take care to add all violations for all fields concerned with the propertyNode being defined.

E.g: a product in SOLD state should have sellDate and sellPrice properties defined. If none of the fields are defined my validator will raise a set of 2 violations on these properties.

Afterwards, my plan was to read the properties concerned in the set of violations, retrieve the Field they are bound to in editor UI and highlight them in red. Letting the error message being displayed genuinely by cuba.

For a form with more than twenty fields, it is quite helpful to the user to visually see it has to fill/modify all fields in red. Form organizing helps of course, but that is a real plus.

Regards
Michael