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

Input type 'email' as controlled component does not control white spaces #6368

Closed
marcolanaro opened this issue Mar 29, 2016 · 14 comments
Closed

Comments

@marcolanaro
Copy link

A controlled input filed of type email behave differently from a controlled field of type text.
If you manage a controlled input field of type email, the actual state and the rendered DOM are different if the user digit spaces, e.g. ' '.

With an input element like this:
<input type="text" value={'stringFromTheState'} />
if you try to digit letters or spaces, you will always get rendered the string 'stringFromTheState'.

With an input element like this:
<input type="email" value={'stringFromTheState'} />
if you try to digit letters you will always get rendered the string 'stringFromTheState'.
if you try to digit spaces you will get a new rendered string that compose the state with the spaces.

This is problematic is before saving the state you need to validate the field and force it to do something smart like strip the white spaces.

@gaearon
Copy link
Collaborator

gaearon commented Mar 29, 2016

Would you mind creating a JSFiddle reproducing the issue? It’s preferable that you use React 15 RC2 to verify it happens with the latest code. Thank you for reporting!

@gaearon gaearon added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Mar 29, 2016
@aweary
Copy link
Contributor

aweary commented Mar 29, 2016

Hey @marcolanaro @gaearon I put together a JSFiddle attempting to reproduce what you're describing with 15.0.0-rc.2. It doesn't seem that the two controlled inputs behave differently at all onChange from what I can see--at least not in Chrome.

If there is no onChange event handler attached to the input component then I can reproduce the behavior you're describing. Whitespace can be entered in the <input> with type='email' but not with type='text'.Though a controlled input should require an onChange handler, I agree that the behavior should be likely be the same. But doing this does throw a warning:

Failed form propType: You provided a `value` prop to a form field without an `onChange` handler.
This will render a read-only field. If the field should be mutable use `defaultValue`.
Otherwise, set either`onChange` or `readOnly`.Check the render method of `ControlledTestComponent`.

@marcolanaro
Copy link
Author

@gaearon @aweary Our goal is to validate the email field striping out the spaces as soon as the user is typing.
This is the jsfiddle:
https://jsfiddle.net/marcolanaro/j38zgdum/5/

You'll see that the two controlled input fields behave differently if you type spaces.
Thank a lot for your help.

@aweary
Copy link
Contributor

aweary commented Mar 30, 2016

@marcolanaro I see. It seems like both examples demonstrate a root issue with how <input> elements handle email vs. text.

@yangshun
Copy link
Contributor

I tested the fiddle in Firefox 45.0.1 and both controlled inputs behave correctly (but it seems like due to a bug in Mozilla); Mozilla does not trim the input.value. In Chrome, event.target.value is already trimmed according to https://html.spec.whatwg.org/multipage/forms.html#e-mail-state-(type=email), hence React does not detect a difference between the DOM state and its internal state and hence no updates.

This issue is similar to redux-form/redux-form#417.

@marcolanaro
Copy link
Author

I tested it with chrome 49 and the email input does not behave correctly.

@zpao
Copy link
Member

zpao commented Mar 31, 2016

Just to clarify - is this a new issue with 15 or was this happening in 14 as well?

Edit: I tried myself - looks like this isn't new to 15 so we'll have to come back to this and see if there's anything we can possibly do after we ship. Thanks for filing and the repro!

@zpao zpao added Status: New and removed Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug labels Mar 31, 2016
@jimfb
Copy link
Contributor

jimfb commented Mar 31, 2016

This type of thing is literally the worst. Engineers try to be "helpful" by automatically trimming the value, and end up making life more difficult. This is why code should only ever do the trivially simple thing and just pass values along.

Ironically, if we fired an onChange when the user hit the space bar, all controlled email inputs would necessarily strip spaces (even if that wasn't the desired behavior).

I suppose we could try to track keystrokes and derive our own backing state, but @sebmarkbage said that supporting i18n makes the custom handling of text input incredibly difficult (borderline impossible) to get right.

I'm almost tempted to say this is a "won't fix", unless someone has an idea for what we could reasonably do in this situation.

@marcolanaro
Copy link
Author

This type of things is not something that the engineer does because he likes to push the library to the edge; it's a business requirement to decrease friction and increase conversion.

The fact that all this things are working with the only exception of the spaces on an email input field let me think that is a gotcha in the library.

@jimfb
Copy link
Contributor

jimfb commented Apr 5, 2016

The browser DOM node returns a value that does not accurately reflect what the user sees. That's what I was complaining about. It's a gotcha in the spec that propagates to become a gotcha in the browser that propagates to become a gotcha in the library.

@marcolanaro When I said "Engineers trying to be 'helpful'", I was referring to the engineers who wrote the W3C spec, not to you and other users of React. My commentary was intended to apply to infrastructure code (browsers/react/etc) and not to application code. Sorry for the ambiguity.

@nhunzaker
Copy link
Contributor

Circling back to this after 2 years, it seems like the root of the problem remains that the input value reports with trimmed spaces, without any way to detect additional white space.

As far as I see it, this is out of our control, and an implementation that tracked user input through a sophisticated key-press system feels fraught with edge cases.

I'm going to close this out, but let's keep the conversation going if a new idea for how to approach this comes up.

@jon617
Copy link

jon617 commented Mar 1, 2019

Same problem as nhunzaker in 2019.

On <input> tag, with type="email" any spacebar keystrokes are not registered to onChange. With type="text" they are.

Quick fix for me was adding onKeyDown to the <input> tag, like: <input onKeyDown={ this.onKeyDown }, then onKeyDown function to ignore the spacebar keystrokes:

onKeyDown = (e) => {
  if ( e.key === " " ) {
    e.preventDefault();
  }
}

@ShyamRaj
Copy link

ShyamRaj commented Aug 6, 2019

Anyone have a fix for this issue. I'm still having this problem!

@AregbesolaOJ
Copy link

Thank you very much @jon617 found your solution really helpful

DASenkiv pushed a commit to ONLYOFFICE/DocSpace that referenced this issue Oct 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants