Skip to content

fix: skip patching focused input/textarea elements during DOM update #31

Description

@adnaan

Problem

When the server re-renders a textarea (or input) that the user is actively typing in, the client's DOM patcher replaces the element's content, causing:

  1. Cursor resets to position 0 — each patch moves the cursor to the start
  2. Reversed text — typing "hello" renders as "olleh" because each character is inserted at position 0 after the cursor reset
  3. Content wipe — on form submit, the patched content may be stale or empty

This makes Change() method (live-as-you-type updates) unusable with textareas.

Expected behavior

Phoenix LiveView's client skips patching form elements that have focus. The focused element's value is left untouched during the DOM diff/patch cycle. Only unfocused elements are updated.

Reproduction

  1. Create a controller with a Change() method that reads a textarea value
  2. The template has <textarea name="content">{{.Content}}</textarea>
  3. Type in the textarea — each keystroke triggers Change() → server re-renders → client patches textarea → cursor resets

Proposed fix

In the DOM patcher, before updating an element's text content or value:

  • Check if the element is document.activeElement
  • If it is, skip the update (the user's local state is authoritative while they're typing)
  • Only apply server-sent values to unfocused elements

This matches LiveView's behavior and enables Change()-based live preview patterns.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions