Search code examples
vaadinvaadin23

Vaadin 23: addPropertyChangeListener for JavaScript changes


Intended: In a Vaadin 23 application I'd like to get informed when the value of an HTML attribute is changed.

What I tried: I created this input formula:

Sample input form

    // Text input field
    Input input = new Input();
    input.setId("myInputField");
    Element textInput = input.getElement();
    
    // Change listener for property "value"
    // Works well for manual input
    // BUT doesn't work for JavaScript changes
    textInput.addPropertyChangeListener("value", "change", 
        e -> {System.out.println(e.getValue());}
    );
    
    // Button that changes the value of attribute "value"
    Button button = new Button("Change value");
    button.addClickListener(e -> {UI.getCurrent().getPage().executeJs(
        "document.getElementById('myInputField').setAttribute('value','hello');"
    );});

    this.add(input, button);

What does work: When the user types "something" into the input field then the server prints "something" to the console. This is intended and observed. OK.

What does NOT work: When the user pushes the button then the content of the input field is "hello" (OK). But the PropertyChangeListener does not fire an event, so the server does not print anything to the console.

Question: Is there a way to get the PropertyChangeListener fire an event, even if the attribute's value has been changed by JavaScript?


Solution

  • I see two problems here.

    First, the server-side property change listener in Vaadin Flow needs to be triggered by a client-side event. The <input> element fires events when the the user directly changes the value in the field, but not when the value is changed programmatically. If you change the value from code, then you need to also manually fire an event to trigger the update.

    Second, as pointed out in the comments, you should change the property rather than the attribute. In most cases, the attribute and the property with the same name are kept in sync, but the value of an input is an exception. Here, the attribute is the initial value and the property is the actual value. The stay the same if you only change the attribute, but diverge after the user edits through the UI or if the property is changed.