Skip to content

Dedicated API for controlled inputs #79

@raquo

Description

@raquo

See gitter for previous discussion and some proposed solutions.

Basically, if you have a "controlled" input element (to borrow a React.js term), and you want to change its value (e.g. remove non-digits) after the user types, the most straightforward way to do that in Laminar doesn't work if input value is feeding from a signal or a var. Two compounding reasons for this:

  1. you can't preventDefault onInput, it's not a cancelable event in the JS DOM, and

  2. signal doesn't emit a value that is == to previous value.

So when user types in an "invalid" character like "n", the browser updates the input value, but the desired input value, controlled by the signal, doesn't change (if it was "12" and the user typed an invalid character like "n", it will remain "12"), so the signal doesn't emit anything, and so what the user typed is allowed to remain in the input, and the input's value diverges from the Var that is supposed to feed it.

I'm trying to find a reasonable solution to this. My latest thinking is, broadly speaking, to force-set the input's value to the controlling signal's current state after the onInput event has "finished processing" (unless at this point the input's value already matches the controlling signal's current value of course, in which case we don't need to do anything).

I think, if we define "finished processing" as "the transaction in which onInput event happened, and any descendant transactions created from it have completed", which in turn probably resolves to "wait until the transaction queue is empty" in case of transactions started from browser events, this should net us the right outcome. I'm still experimenting, and might run into issues, e.g. with multiple onInput listeners (because each onInput listener will create a separate transaction...), but at least it's looking promising.

After looking into this, I am rather annoyed by the status quo, so I'll try to get this into 0.12.0, although I might publish 0.12.0-m1 before that.


If you're wondering how React does controlled inputs, their state does not have a == check, which is a prerequisite for this problem. Also their event system is custom built so they have more control over it (Laminar just uses native DOM events). But if you're curious you can start here I think.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions