Reputation: 795
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:
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:
binder.writeBeanIfValid(binder.getBean());
in the ShortcutEventListener. The bean still contains the old TextField value.Upvotes: 0
Views: 101
Reputation: 10633
One option is to trigger blur in client side and and read the field in then call back of the call. This will ensure that field is not read before, but after the roundtrip.
TextField field = new TextField();
field.setValueChangeMode(ValueChangeMode.ON_BLUR);
Shortcuts.addShortcutListener(field, e -> {
field.getElement().executeJs("this.blur()").then(result -> Notification.show("field: " + field.getValue()));
}, Key.ENTER).listenOn(field);
Upvotes: 2