Hello,
In Jmix you don’t typically “override” the built‑in addTypedValueChangeListener
directly, but you can replace or supplement it in several ways:
1. Switch from EAGER to LAZY or ON_BLUR mode
This immediately stops a network request on every keystroke (and the plain‑text value in each request):
// in your screen controller or init()
textField.setValueChangeMode(ValueChangeMode.LAZY);
textField.setValueChangeTimeout(300); // wait 300 ms after typing stops
// —or—
textField.setValueChangeMode(ValueChangeMode.ON_BLUR);
2. Unbind the default and bind manually with your own listener
If you need full control over when and how the value is reported to your backing data:
// 1) Remove the Jmix binder’s auto‑binding aka `com.vaadin.flow.data.binder.Binder`
binder.removeBinding(textField);
// 2) Re‑bind and attach your own ValueChangeListener
binder.forField(textField)
.withValidator( /* … */ )
.bind(OrderItem::getName, OrderItem::setName);
// 3) Add your custom listener
textField.addValueChangeListener(event -> {
// your logic here
});
3. Extend the component and wrap the listener registration
Create your own subclass of TextField
to intercept any listener that gets added:
public class CustomTextField extends TextField {
@Override
public Registration addValueChangeListener(ValueChangeListener<? super ComponentValueChangeEvent<TextField, String>> listener) {
ValueChangeListener<ComponentValueChangeEvent<TextField, String>> wrapped
= e -> {
// pre‑processing
listener.valueChanged(e);
// post‑processing or suppression
};
return super.addValueChangeListener(wrapped);
}
}
Then register it in Spring so views pick up CustomTextField
instead of the stock one (using a ComponentProvider
bean or a Jmix UI component alias).
4. (Advanced) Client‑side JS listener
If you really want to catch browser events before Vaadin’s wiring:
// in the screen controller
textField.getElement().executeJs(
"this.addEventListener('input', e -> $0.$server.onInput(e.target.value));",
getElement()
);
@ClientCallable
public void onInput(String value) {
// only your code runs—no Jmix binder involvement
}
In most cases switching to LAZY
or ON_BLUR
mode will solve the “plain‑text on every request” problem. If you still need custom handling, unbind/bind yourself or extend the component as shown above.
If you have more questions, reply this thread.
Best regards,
Dmitry