Skip to content

Wrapping NumberField within CustomField ignores ValueChangeMode #8806

@DarioViva42

Description

@DarioViva42

Describe the bug

Using the methods setValueChangeMode and setValueChangeTimeout do work as expected on a Numberfield. But when the NumberField is wrapped within a CustomField the event handling is suddenly always Eager. Why? What do we need to change to achieve the expected behaviour.
The same bug probably happens with other fields as well, but we just happened to notice it with the NumberField.
Is our approach to this completly wrong and this is the expected behaviour? If so, we did not find the relevant section in the docs that specifies how to mitigate this. Is there maybe a way to turn the complete CustomField lazy (so all Fields wrapped in the CustomField become lazy)?

Expected-behavior

The behaviour of the change listeners for the NumberField does not change when wrapped within a CustomField.

Reproduction

Add the following View to your Project. Then change the value of the NumberField and see that the action (printing “hello” in this example) defined in the listener is executed after 2 seconds. Changing the number with the keyboard also changes the value after 2 seconds.
But changing the value of the NumberField wrapped in a CustomField instantly triggers the event instead of after the specified timeout. But only when using the step buttons or on blur. When using the keyboard to change the number in the wrapped NumberField nothing happens at all.

Note

This example might seem a little silly, but of course it’s just for demonstrating purposes. Normally we would have multiple fields within one CustomField, just as one would expect.
We are aware that the documentation for CustomField states the following.

Custom Field is a component for wrapping multiple components as a single field.

import com.vaadin.flow.component.customfield.CustomField;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.Route;

@Route
public class NumberView extends VerticalLayout {
	public NumberView() {
		NumberField numberField = new NumberField();
		numberField.setLabel("NumberField");

		numberField.setStepButtonsVisible(true);
		numberField.setValueChangeMode(ValueChangeMode.LAZY);
		numberField.setValueChangeTimeout(2000);

		numberField.addValueChangeListener(e -> {
			System.out.println("hello");
		});
		add(numberField);

		CustomNumberField customNumberField = new CustomNumberField();
		customNumberField.setLabel("CustomNumberField");
		customNumberField.addValueChangeListener(e -> {
			System.out.println("hello");
		});
		add(customNumberField);
	}

	static class CustomNumberField extends CustomField<Double> {

		NumberField numberField = new NumberField();

		public CustomNumberField() {
			numberField.setStepButtonsVisible(true);
			numberField.setValueChangeMode(ValueChangeMode.LAZY);
			numberField.setValueChangeTimeout(2000);

			add(numberField);
		}

		@Override
		protected Double generateModelValue() {
			return numberField.getValue();
		}

		@Override
		protected void setPresentationValue(Double aDouble) {
			numberField.setValue(aDouble);
		}
	}
}

System Info

Vaadin Version:

  • 24.7.15 with SpringBoot 3.5.11
  • 24.8.17 with SpringBoot 3.5.11
  • 24.9.12 with SpringBoot 3.5.11
  • 25.0.6 with SpringBoot 4.0.3

OS does not matter. Browser does not matter.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions