Intention: In an existing Vaadin 23 form I'd like to add a shortcut Ctrl+S to trigger a save action.
Code: This is a reduced (but running) code:
@Route("sandbox")
public class SandboxView extends VerticalLayout {
public SandboxView() {
TextField textField = new TextField();
Shortcuts.addShortcutListener(this, new ShortcutEventListener() {
@Override
public void onShortcut(ShortcutEvent event) {
System.out.println("Saving value ... "+textField.getValue());
}
}, Key.KEY_S, KeyModifier.CONTROL).listenOn(this);
this.add(textField);
}
Problem: When the user types some text into the Textfield and then hits Ctrl+S (without escaping the focus from the TextField), then textField.getValue() within the ShutcutEventListener returns the value that was in the TextField bevore the user focused the TextField.
Workarounds:
- Workaround A is that the user moves the focus out of the TextField and then hits Ctrl+S. Works but that is error-prone because not every user will remember every time to do so.
- Workaround B is to set the valueChangeMode to EAGER:
textField.setValueChangeMode(ValueChangeMode.EAGER);
. Works fine but this would cause more traffic and more server load (because there are some valueChangeListeners at every field that do validation and some recalculation of some formulas) - so this is not the way I want to go.
Question: Is there a way to sync all fields in the form to the backend within the ShortcutEventListener?
What I tried:
- The working workarounds above
- Calling textfield.blur() triggers the JavaScript "blur" method, but the synchronization happens after the ShortcutEventListener execution.
- Using a Binder and explicitly call
binder.writeBeanIfValid(binder.getBean());
in the ShortcutEventListener. The bean still contains the old TextField value.