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.

Reply via email to