Interestingly, the underlying VirtualDom can prevent a message being sent...

http://package.elm-lang.org/packages/elm-lang/virtual-dom/1.0.2/VirtualDom#on

> If the decoder succeeds, it will produce a message and route it to
yourupdate function.

But what happens if the decoder fails? Probably doesn't rollback in the
same way as Dan's workaround... Turns out, nothing!

https://github.com/elm-lang/virtual-dom/blob/1.0.2/src/Native/VirtualDom.js#L451

Let's add some logic when the decoder fails to rollback the input to the
old value, just like in Dan's workaround. Or maybe be conservative and use
a Maybe, or a new type with three options Rollback | NoOp | Message msg.

Anyway I think this solves it :-)

Huh, is this the problem that the NoOp message is supposed to solve?

It's obviously not working.

In cases like this, we need to determine locally that the effect on the app
is semantically "no operation", and ignore the event by synchronously
rolling back the local state and terminate without propagating.
On Jun 19, 2016 7:19 PM, "John Mayer" <[email protected]> wrote:

> What if:
>
> Html.Events.onInput : (String -> Maybe msg) -> Attribute msg
>
> We could run the validation logic before the DOM event is sent to the
> global effect system.
> On Jun 19, 2016 6:47 PM, "Alexey Shamrin" <[email protected]> wrote:
>
>> Follow up to my example. Json.Decode is not necessary:
>>
>> view content =
>>   input [ type' "number", onInput handleInput, value content ] []
>>
>> handleInput : String -> Msg
>> handleInput s =
>>     if String.length s <= 2 then NewContent s else NoOp
>>
>> (annoying flashing is still there)
>>
>> https://gist.github.com/shamrin/f29672717fc0df775486a7ece0650412
>>
>> On Monday, June 20, 2016 at 1:30:52 AM UTC+3, Alexey Shamrin wrote:
>>>
>>> Here's how I would implement it in React:
>>>
>>> var App = React.createClass({
>>>   getInitialState: function() {
>>>     return {value: ''};
>>>   },
>>>   render: function() {
>>>     return <input type="number" onInput={this.handleInput}
>>>               value={this.state.value} />;
>>>   },
>>>   handleInput: function(e) {
>>>     var v = e.target.value;
>>>     if (v.length <= 2) {
>>>       this.setState({value: v});
>>>     }
>>>   }
>>> });
>>>
>>>
>>> https://jsfiddle.net/axqjjrt2/
>>>
>>> It works correctly because <input value=…> is a controlled component
>>> <https://facebook.github.io/react/docs/forms.html#controlled-components>:
>>> user input
>>> has no effect on the rendered element, until we set the value with
>>> setState.
>>>
>>> By the way, it is possible to write similar code in Elm:
>>>
>>> import Html exposing (Html, Attribute, text, div, input)
>>> import Html.App exposing (beginnerProgram)
>>> import Html.Attributes exposing (..)
>>> import Html.Events exposing (onInput, on)
>>> import String
>>> import Json.Decode as Json
>>>
>>> main =
>>>   beginnerProgram { model = "", view = view, update = update }
>>>
>>> -- UPDATE
>>>
>>> type Msg
>>>   = NewContent String
>>>   | NoOp
>>>
>>> update msg oldContent =
>>>   case msg of
>>>     NewContent content ->
>>>       content
>>>     NoOp ->
>>>       oldContent
>>>
>>> -- VIEW
>>>
>>> view content =
>>>   input [ type' "number", on "input" decodeInput, value content ] []
>>>
>>> decodeInput : Json.Decoder Msg
>>> decodeInput =
>>>   Json.at ["target", "value"] Json.string
>>>     |> Json.map (\s -> if String.length s <= 2 then NewContent s else
>>> NoOp)
>>>
>>> Unfortunately, it doesn't help. Annoying flashing of extra digits is
>>> still there.
>>> It seems to me Elm (elm-html?) doesn't support controlled components.
>>>
>>> Is there a discussion about adding controlled inputs to elm-html?
>>>
>>> Alexey
>>>
>>> On Sunday, June 19, 2016 at 6:55:25 PM UTC+3, Max Goldstein wrote:
>>>>
>>>> Is this a problem that React or other vdom-based rendering systems
>>>> have? If so, what's their workaround? If not, why not?
>>>>
>>> --
>> You received this message because you are subscribed to the Google Groups
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to