javascriptvaadin-flowvaadin10

Vaadin 14, Safari 13: Textfield with input event listener does not trigger ValueChangeListener


In a Vaadin 14.3.2 application I created my own number field that formats the (numerical) input.

Therefore I created a class like this:

@Tag("my-number-field")
@JsModule("./js/my-number-field.js")
public class MyNumberField extends TextField {
[...]
}

and some JavaScript in the my-number-field.js (see below) that does the formatting. This formatting works fine in Chromium, Chrome, Edge, Firefox and also in Safari 13.1.3.

BUT in Safari the ValueChangeListener is not triggered at the server side when this occurs:

inputElement.value = [newValue];

This is some minimal snippet of my code that still shows the behavior:

(function() {

customElements.whenDefined('vaadin-text-field').then(() => {
    class MyNumberField extends customElements.get('vaadin-text-field') {

        constructor() {
            super();
        }

        static get is() {
            return 'my-number-field';
        }

        ready() {
            super.ready();
            this.addEventListener('input', this.formatInput, true);
        }
        
        formatInput (event) {
            const inputElement = this.inputElement;
            const originalInputValue = inputElement.value;
            // this is the re-formatting
            inputElement.value=originalInputValue+'0';
        };

    }
    customElements.define(MyNumberField.is, MyNumberField);
});

})();

When I comment the line inputElement.value = [newValue]; then the ValueChangeListener at server side gets the entered value. With that line activated the ValueChangeListener does not get the entered/newly formatted value.

Is there a trick to also trigger the ValueChangeListener in Safari?


Solution

  • Update (and maybe the solution for my case): Setting the ValueChangeMode of MyNumberField to ON_BLUR works:

    public MyNumberField(...) {
        this.setValueChangeMode(ValueChangeMode.ON_BLUR);
    }
    

    EAGER also works. And LAZY also works. And TIMEOUT works.

    Only ON_CHANGE does not work which is set as default in the TextField constructor.