Toolbelt.Blazor.HotKeys
Toolbelt.Blazor.HotKeys copied to clipboard
Update binding before invoking hot key? (Blazor Server)
Hi. I would think that a typical use case is to enable a hot key like ctrl+s to quickly allow the user to save changes. With the AllowedIn argument you can enable this even when the focus is set to an input field:
HotKeys.CreateContext().Add(ModKeys.Ctrl, Keys.S, Save, "Save.", AllowIn.Input | AllowIn.NonTextInput | AllowIn.TextArea);
Good. However, the default behavior for Blazor (Server) is to only update a two-way binding when the focus of an input is lost. Meaning: when the hot key is invoked, the current change to the bound field is not yet applied, resulting in outdated data.
How can we force a binding update, without switching the binding to update on key press (unreasonable for many situations)? Maybe we should have the option to let the JS part of your library force a blur?
@MisterGoodcat
Thank you for that proposal!
Maybe we should have the option to let the JS part of your library force a blur?
That might be a good idea, I think, but doing that may not be the area of responsibility of this package.
Maybe as you already know, I may recommend you to use @bind:event="oninput" at first.
But if we can't use @bind:event="oninput" for this scenario, as you said, we have to fire an onchange event manually with small JavaScript code, I think.
I implemented the sample code of this topic.
You can try it out on the live demo site that's URL is below.
- https://jsakamoto.github.io/Toolbelt.Blazor.HotKeys/save-text
Please see also the following commit.
- https://github.com/jsakamoto/Toolbelt.Blazor.HotKeys/commit/23d292d4fe4206a7870b077198855a273cc6a871
I'll be keeping to consider about that idea you proposed, but the above is my opinion at this time.
I hope this determination makes sense.
The JavaScript helper sounds like a good solution for me. Using oninput for the binding is not feasible in my scenario, because I'm moving back and forth larger amounts of text that are pre-processed when changed (think: markdown editor). Thanks again!
@MisterGoodcat: this is how I have done it in javascript:
document.body.addEventListener('keydown', e => {
//save on CTRL+S
if (e.ctrlKey && e.key === 's') {
e.preventDefault();
var element = document.activeElement;
if (element.matches('input, textarea')) {
element.blur();
element.focus();
}
let form = element.closest('form');
form && setTimeout(() => {
form.dispatchEvent(new SubmitEvent('submit', { submitter: form }));
}, 1);
};
});
however, you might invoke blur/focus from your Save method (HotKeyEntry action):
const MyApp = {
updateBinding() {
var element = document.activeElement;
if (element.matches('input, textarea')) {
element.blur();
element.focus();
}
}
}
async Task Save() {
await JSRuntime.InvokeAsync('MyApp.updateBinding');
}