Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

value attribute of textarea should be sent to browser only at creation of DOM element #55

Closed
pcarbonn opened this issue Jul 13, 2016 · 15 comments

Comments

@pcarbonn
Copy link

pcarbonn commented Jul 13, 2016

This is a follow-up on issue #52.

elm-lang/html should send the value attribute of textarea to the browser only at creation of the textarea DOM element, and ignored when the textarea is update'd and view'ed. This is to prevent the caret to be moved at the end of the textarea when typing, resulting in misplaced keyboard input. See issue #52 for an example.

Alternative : we could use a defaultValue attribute instead (as for the input), but the value attribute is worthless as it works now, so I see no need to create a separate attribute.

@process-bot
Copy link

Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

@pcarbonn
Copy link
Author

pcarbonn commented Jul 13, 2016

It's interesting to see what React has to say on this.

React developers have 2 options:

  • either use value and onchange to create "controlled elements". State is changed when textarea loses focus (not when user types).
  • or use defaultValue to create "uncontrolled elements". (With oninput, elm state is changed at every key entry, but not sent back to the browser.)
    For textarea, defaultValue does not exist, but the children text (enclosed by the textarea tag) behaves like defaultValue ("If you do decide to use children, they will behave like defaultValue.")

Contrary to what I wrote above, I would now suggest to align Elm with React:

  • the value attribute of the textarea is sent to the browser at creation and update of the textarea DOM node, to create "controlled elements" --> no change
  • the inner Html of the textarea node is sent only at DOM node creation --> to be changed in elm-lang/html

(Note that, in both cases, it is unfortunately not possible to interfere with user entry while he types.)

@evancz
Copy link
Member

evancz commented Jul 13, 2016

I think the two options you outline make a lot of sense.

As far as I understand, Elm already works such that you can use either approach right now.

  1. If you want to use value and onChange you can define onChange f = on "change" (Json.map f Json.string) and do things that way.
  2. You can just use defaultValue and do things that way.

Are there actually any implementation changes necessary? If so, what are they exactly? Do you think it is different in React or is it demonstrable?

If not, it sounds like we just need to document this choice more clearly. I'd suggest community blog posts / SO questions, and perhaps it can be folded in to my guide at some point. It definitely shouldn't block on that though.

@evancz
Copy link
Member

evancz commented Jul 13, 2016

As an aside, thank you for following up and bringing in relevant ideas and explaining them so clearly and concisely! You probably know you have this skill, but it can't hurt to say it out loud :)

@rtfeldman
Copy link
Member

rtfeldman commented Jul 13, 2016

Relevant React docs:

In HTML, the value of <textarea> is set via children. In React, you should use value instead.

I think the minimal change would be a PATCH change:

  • Make custom semantics for value and defaultValue when they're used on a textarea. (In plain HTML these attributes do nothing, but HTML's API is bad for virtual DOMs.)

A better change (long-term, if not necessarily anytime soon), I think, would be to codify this in the API instead of suggesting it. This would be a MAJOR change:

  • Remove the final argument of the textarea function. Instead of suggesting usingvalue or defaultValue instead of children, make it the only option.

Note that the MAJOR change would also require the PATCH change, since removing the children argument without introducing custom value and defaultValue attributes would make textareas useless. 😄

@pcarbonn
Copy link
Author

pcarbonn commented Jul 14, 2016

@evan : I agree with you on option 1, and I'll use this approach for my project.

For option 2, defaultValue works for input but not for textarea. This is confirmed by rtfeldman in issue #52.

So, the change request is to either add support for defaultValue to textarea (to be consistent with input, but it's not an official attribute of textarea in HTML), or to use the child data (inner Html) as default value instead (recommended, to be consistent with HTML and React).

@rtfeldman: the React page says the following in advanced topics : "If you do decide to use children, they will behave like defaultValue."

@evancz
Copy link
Member

evancz commented Jul 14, 2016

I like @rtfeldman's suggestion of changing the type of textarea. Simplest and least performance overhead. I'll add to #53. Thanks for explaining all this @pcarbonn and @rtfeldman!

@pcarbonn
Copy link
Author

pcarbonn commented Jul 14, 2016

Thank you Evan.
(I'm not sure I understand what "changing the type of textarea" exactly means, but I' trust you'll do it well. I think you mean "changing the type declaration of textarea" (aka function signature). It may be a good solution technically, but I don't think it is the solution of least surprise for the Elm developer.

@rtfeldman
Copy link
Member

rtfeldman commented Jul 19, 2016

Crazy update on this: pairing with @joneshf on some defaultValue stuff, we learned that:

  • If you use value and defaultValue with textarea, they already work the way we want them to. Very surprised to learn this, especially given that MDN doesn't list either in the docs for textarea! EDIT: MDN does, however, mention it in other docs
  • The spec for textarea confirms that both value and defaultValue are a real thing. However, textarea also has a content model of Text, meaning the spec supports setting both value and text children
  • The spec for input explicitly mentions that input elements have no content model—which is to say, they should never have children.

Based on this, I would recommend:

  1. Don't bother adding any features or special-casing to textarea, since defaultValue and value already work the same way with textarea as they do with input.
  2. Remove the children argument from textarea
  3. Also remove the children argument from input

@rtfeldman
Copy link
Member

Counterargument to myself: in the spirit of "don't make me think," there's a case to be made that the signatures of textarea and input (or for that matter more extreme cases like br and hr) should remain the same.

Part of this counterargument might go something like "you have access to both value and defaultValue, and knowing which to use is a matter of documentation." So maybe the best resolution here is to make no API changes and instead to change the docs for input and textarea to recommend using defaultValue unless you have a really good reason to use anything else.

@ghost
Copy link

ghost commented Jul 19, 2016

@rtfeldman Do value and defaultValue work consistently with textarea on "all" browsers?

@rtfeldman
Copy link
Member

I don't honestly know.

@malthejorgensen
Copy link

In many cases you want to clear the the textarea after the user has typed in it (e.g. after sending a chat message or submitting a comment).

defaultValue doesn't seem to support this functionality, and value has the cursor-jumping problem that originally started this issue. With the current options, there seems to be no easy way to solve this.

@adamdicarlo
Copy link

FWIW, using defaultValue with value doesn't help the cursor jumping problem for me (Chrome 58, macOS). It's easy to reproduce by pushing three or more keys on the keyboard at once. The cursor never jumps for me with React, no matter how I mash the keys.

Elm demo: https://embed.ellie-app.com/3nNBvZrTcK2a1/4
React demo: https://codepen.io/adamdicarlo/project/full/AnnWoL/

@arnauorriols
Copy link

In many cases you want to clear the the textarea after the user has typed in it (e.g. after sending a chat message or submitting a comment).
defaultValue doesn't seem to support this functionality, and value has the cursor-jumping problem that originally started this issue. With the current options, there seems to be no easy way to solve this.

I've been stuck for a while on this problem @malthejorgensen exposes until I've found this comment in evancz/elm-html#81 explaining a work around. I thought it convenient to reference it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants