virtual-dom: Event onWithOptions doesn't allow selective behaviour on events
Sometimes its necessary to stopPropogation and preventDefault on certain events and not others. For instance it may be desired to restrict certain key-presses in a text-input field. Examples include:
Credit card entry, numbers and spaces Phone numbers with international codes () and + Hex editor, restrict to A-Z 0-5 and many more… Currently Elm doesn’t allow this behaviour because stopPropogation and preventDefault are specified at the time the event listener is registered, and before the event listener has received any events.
I suggest adding a new Options type, something like this:
type alias EventOptions = { stopPropagation : Json.Decoder Bool , preventDefault : Json.Decoder Bool }
and a companion method:
onWithEventOptions
This will allow stopPropogation and preventDefault flags to be based on the content of the event received.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 16
- Comments: 27 (2 by maintainers)
The upcoming API in 0.19 has
onBubbleandonCapturethat allow more flexibility.In particular, they both take a
Handlerthat gives you the ability to dostopPropagationandpreventDefaultconditionally. This design also means we can create “passive” listeners automatically, making scrolling smoother in touch devices.If you think there are cases that the new API will not cover, please share them here. If others validate that the new API would not cover them, please open a new issue outlining the scenario before 0.19 comes out!
Here’s the work-around we’ve been using to
preventDefaulton only certain"keydown"events.First, on the intended target element, do a “normal”
on "keydown"with a message for which yourupdatefunction will identify the desired keystrokes and respond to them, and ignore keystrokes that are not of interest to you. This listener allows all"keydown"events to continue propagating with their default action enabled.Then, wrap the target element in a parent element with its own
"keydown"event listener, this time usingonWithOptionsto prevent the default action for all successfully decoded events. The trick, then (with thanks to @opsb for this tip) is to only decode successfully the keycodes for which we wish to prevent the default action:Note that successfully-decoded events result in
NoOpmessages, which do nothing in theupdatefunction.All
"keydown"events will therefore be processed by the event listener on the target element, and then those events will bubble up to the parent element, where only those"keydown"events for which you want topreventDefaultwill be processed withpreventDefault = True.It’s a little kludgey, but it works.
I can’t make any judgement on the proposed way/solution, but
is a super-essential, must-have, uber-needed feature.
This seems like a sweet API! Since this is an unusual and advanced feature, I’d personally just replace the existing API with this one.
It wouldn’t be much trouble to call
onWithOptionspassing{ stopPropagation = Decode.succeed True }in the current case.The work around I ended up using was to add an inline JavaScript event handler like so: Runnable example: https://ellie-app.com/3t42RzdkDQRa1/7
Another case here: an autocomplete field needs to support ‘up’ and ‘down’ to navigate through result, while keeping the cursor position in the input field. Currently pressing ‘up’ would make the cursor goes to the leftmost position. You need a conditional
stopPropgation()here to allow typing of character but ‘up’ and ‘down’@sentience Brilliant!!! (https://stackoverflow.com/questions/42390708/elm-content-editable-with-enter-key/42446875#42446875)
My use case for this feature is with contenteditable divs. I want to trap an
<enter>and instead of entering achar 13into the text, use this as a trigger to blur the selected node and save theevt.target.textvalue back to the model@inactivist that’s a sarcastic comment, it means we shouldn’t hope to see this feature anytime soon. “Compilation into WebAssembly” is used to crude how long it might take because, obviously, WebAssembly is not even on the roadmap either.
I’ve heard that it will be implemented natively in WebAssembly release
On Sun, Jan 15, 2017 at 10:06 PM, Matthias Urlichs <notifications@github.com
One for the examples list:
I have a textarea and I want to trigger an update when the enter key is hit but prevent the newline from being added to the textarea.
Hi guys!
We get into situation where we have an Elm widget inside a form and which should process
Enter key pressevent in its inputs, perform custom logic and prevent form submission. The thing is that we can’t select event on which we want topreventDefaultand effectively blocking all input in those inputs.I think another possible signature could be
onAGoodName : String -> Json.Decoder (Options, msg) -> Html.Attribute msgAnother scenario I came across recently: application hotkeys, you only want to
preventDefaultfor certain keys.Is this on the road-map for Elm 0.18? This would be the most important feature for me to have.
Basically, preventing the default for input elements is not possible, because as of now it will prevent Tab navigation. Preventing browser actions conditionally is all over the JS world and a must-have.