Trouble with text inputs and double update roundtrips

As I see it, there are two problems here:

  • Atomic updates
  • The cursor jumps

My (partial) understanding of your problem with atomic updates is that you need both a string and a time. In other words, you need to unambiguously pair a text with the corresponding timestamp.

The cursor jumping problem occurs when the virtual dom updates the content of the text area. As far as I understand, this only happens if the value in the model is different from the <textarea value=""> in the DOM. The vdom only updates the textarea if the values are different. When using tasks with Time.now the resulting update seems to happen in the next animation frame.

My guess is that the flow of events would look something like this:

  1. User changes the input and an event fires.
  2. update in elm app is called and returns a Cmd to get the current time
  3. view is executed but the text in the DOM differs from the text in the elm model since the model was not updated.
  4. update in elm is called with the new time and the text is updated in the model.
  5. view is called and changes the textarea again

Maybe a solution could be to separate your Doc type and the view state for the textarea? Something along these lines:

type alias Model =
    { text : String -- populate this with the string represantation from Doc when it changes?
    , doc : Doc
    }

type Msg
    = TextareaChanged String
    | GotTimeFor String Time.Posix

update msg model =
    case msg of
        TextareaChanged text ->
            ( { model | text = text }
            , Task.perform (GotTimeFor text) Time.now
            )

        GotTimeFor text time ->
            handle your atomic update
1 Like