kweb-core
kweb-core copied to clipboard
Add preventDefault() ability while handling events
Hi I'm experimenting a bit with KWeb on my side project and I'd like to create custom keyboard shortcuts, but unfortunately on Ctrl+P there is browser print function.
I did this:
doc.body.on.keyup {
if (it.ctrlKey && it.key == "p") {
println("ctrl+p pressed")
}
}
The message is shown, but also browser print dialog pops up.
For now I kinda hacked around with custom events. I just register regular JS shortcut with Mousetrap which sends my action event:
Mousetrap.bind('ctrl+p', function(e) {
var event = new CustomEvent('searchPageAction');
document.dispatchEvent(event);
return false;
});
Then in KWeb I can catch that and do what needs to be done. The best part of coming up with this is that I can actually use onImmediate
to show the dialog without a lag (which would not be an option with preventDefault on server):
doc.body.onImmediate.event("searchPageAction") {
// show search dialog
}
doc.body.on.event("searchPageAction") {
// do things that should be done on the server (if any)
}
Actually I've made a little plugin for that:
import kweb.WebBrowser
import kweb.plugins.KwebPlugin
import org.jsoup.nodes.Document
class MousetrapPlugin : KwebPlugin() {
override fun decorate(doc: Document) {
doc.head().appendElement("script")
.attr("src", "//cdnjs.cloudflare.com/ajax/libs/mousetrap/1.4.6/mousetrap.min.js")
}
}
private fun makeEventName(eventName: String) = "action_$eventName"
public fun WebBrowser.registerAction(shortcut: String, actionName: String) {
evaluate(
"""
Mousetrap.bind("$shortcut", function() {
var event = new CustomEvent("${makeEventName(actionName)}");
document.body.dispatchEvent(event);
return false;
});
""".trimIndent()
)
}
public fun WebBrowser.onAction(actionName: String, callback: () -> Unit) {
doc.body.on.event(makeEventName(actionName)) {
callback()
}
}
public fun WebBrowser.onImmediateAction(actionName: String, callback: () -> Unit) {
doc.body.onImmediate.event(makeEventName(actionName)) {
callback()
}
}
And usage:
Kweb(port = 12345, plugins = listOf(MousetrapPlugin()) {
registerAction("ctrl+p", "myAction")
onAction("myAction") {
println("Do my action")
}
}
Very cool, just trying to figure out what the most general version of this is.
Is the main need here the ability to call preventDefault() from within the event handler on the client before the event is reported to the server?
Could this be achieved with something like:
element.on(preventDefault = true).click {
println("Element clicked")
}
(onImmediate
would have similar functionality).
@sanity I guess it depends on what the user wants to achieve. In my case that would totally work, but I can imagine that someone would want to cancel an event based on some data from within the event.
Yes, that's a possibility - although hopefully a rare use-case in practice.
I've to little experience with frontend development to tell. It's your call :)
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
Not sure if this is still relevant.
Apparently fixed 7/17/2021