Hi,
So there are a few approaches to this that I can think of.
Use valueChangeEvent.isFromClient()
In most cases, you only care about value changes that are initiated by client, so within a change / selection event you would ignore server initiated changes (such as when you use checkboxGroup.setValue(..) or checkboxGroup.select(..))
checkboxGroup.addValueChangeListener(event -> {
if (event.isFromClient()) { // Client initiated change
// Do your thing
}
});
// ... later
checkboxGroup.select("2"); // event.isFromClient() will be false.
Register the value change listener after value is set.
If you have the initial value available when creating the checkbox group, you can first make a selection / set value, and only then add a listener, so that the listener is not triggered with the initial value.
var checkboxGroup = new CheckboxGroup<String>();
checkboxGroup.setLabel("Checkbox");
checkboxGroup.setItems("1", "2", "3");
checkboxGroup.select("1"); // initial value, does not trigger value change
checkboxGroup.addValueChangeListener(event -> {
// Do your thing
});
Have a class variable, that controls whether change listener code executes
class variable:
private boolean checkboxGroupInitialized = false;
var checkboxGroup = new CheckboxGroup<String>();
checkboxGroup.setLabel("Checkbox");
checkboxGroup.setItems("1", "2", "3");
checkboxGroup.addValueChangeListener(event -> {
if (checkboxGroupInitialized) {
// Do your thing
}
});
// ... later
checkboxGroup.select("1"); // initial selection ignored.
checkboxGroupInitialized = true;
It’s a bit more messier in my opinion than the other options, since you have to have the listener code separated from the rest if the CheckboxGroup creation code.
Option number 3 is fairly similar to that approach, but will allow the value change code to stay close to initialization code.
So whenever you would want to update the selection, you would:
I think you’re right about Karibu, there might be a workaround. I think in the past I mocked a select event, with isFromClient = true, and then fired it trough the component. But it has been a while, not 100% sure about it.
UI Unit Tests (from Vaadin 24.8.1 / Vaadin 24.7.8) had a fix for this with the test(textField).setValue("New value") that will result in isFromClient = true. UI Unit testing is a commercial feature, so if you have a commercial license, you might prefer that, since its directly inspired by Karibu.