How to override alert message in integer-only textfield. Textfield addValueChangeListener does not work

Using Cuba 6.9.1
lane_id has an integer as an Entity attribute type

Problem:
• User can enter string but we want to validate that only integer input is allowed. I need to change message in the bottom corner to different message instead of “Alert Input Error”
• Textfield addValueChangeListener doesn’t work but addTextChangeListener does work. but we want user to enter the whole string and then click on different field
• Cannot find what method or approach to detect out of focus for textField or FieldGroup

when I enter letters nothing happens.
image

As soon as I leave the input box, the input error appears in the bottom right corner and the text got erased
image

Attempt 1: Doesn’t solve exactly what I need but at least it shows different message every time user enters letter. I still want to use the “Alert Input Error” message box with different message like “Must be integer”

LanesEdit.xml
image

lanesEdit.java

public class LanesEdit extends AbstractEditor<Lanes> {
    
    @Named("fieldGroup.laneID")
    protected TextField laneID;
    
    @Override
    public void init(Map<String, Object> params) {
        laneID.addTextChangeListener( event -> {
            String laneIDInput = event.getText();
            System.out.println(laneIDInput);
            if (!NumberUtils.isNumber(laneIDInput)) {
                throw new ValidationException(getMessage("Must be integer "));
            }
        });

    }
}

result:
image

Attempt 2: to detect datasource item change. However this method obtains the value only after user clicks ok button. This does not work as well.

Attempt 3: called all the methods in AbstractEditor. None of those methods can detect textfield out of focus

Textfield addValueChangeListener doesn’t work

Other good solution is to turn off the validation on the lane_id textfield and use postValidate method when user clicks okay. This allows me to have different message in the Alert box. However, I could not find how to turn it off.

Can someone have any idea how to solve or approach this issue?

Hi,

Unfortunately, it is not that easy to show a custom message depending on a field type, but possible with a small hack. You need to register a custom exception handler and handle com.vaadin.data.Validator.InvalidValueException.

  1. Create a class com.company.demo.web.CustomInvalidValueExceptionHandler in web module:
public class CustomInvalidValueExceptionHandler extends AbstractExceptionHandler {

    public CustomInvalidValueExceptionHandler() {
        super(Validator.InvalidValueException.class.getName());
    }
    
    @Override
    protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
    }
  1. Register this class in web-spring.xml:
<bean id="cuba_exceptionHandlersConf" class="com.haulmont.cuba.web.exception.ExceptionHandlersConfiguration">
    <property name="handlerClasses">
        <list>
            <value>com.company.demo.web.CustomInvalidValueExceptionHandler</value>
        </list>
    </property>
</bean>
  1. Depending on UI component datatype show a custom message
// Finds the original source of the error/exception
AbstractComponent component = DefaultErrorHandler.findAbstractComponent(event);
if (component != null) {
    component.markAsDirty();

    if (component instanceof CubaTextField) {
        CubaTextField textField = (CubaTextField) component;

        if (textField.getConverter() instanceof StringToDatatypeConverter) {
            Datatype datatype = getDatatype(textField);

            if (Integer.class.equals(datatype.getJavaClass())) {
                app.getWindowManager().showNotification(
                        "Input error",
                        "Must be integer",
                        Frame.NotificationType.TRAY
                );

                customErrorMessage = true;
            }
        }
    }
}

See the complete demo here: GitHub - cuba-labs/input-error-message

We understand that it should be simpler and will improve this in the near future. See Github issue.

1 Like

Thank you so much. This solves what I need