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

Setting select value to null or undefined does not change to placeholder-like option #4085

Closed
blainekasten opened this Issue Jun 10, 2015 · 8 comments

Comments

Projects
None yet
4 participants
@blainekasten
Copy link
Contributor

commented Jun 10, 2015

Maybe this is just an ugly pattern of the web, but it's pretty typical to have the first option of a select be a sort of placeholder like item.

<select>
  <option value=''>Select a thing</option>
  ....more options
</select>

When implemented with react, I would expect if i set the prop value of the select to null || undefined it would change to the placeholder-like option. But it seems you have to pass an empty string value to pull it off. I'm not sure if this is something React should mask/handle or not. It seems more like an oddity of the browser.. So I am suggesting one of two things:

  1. Have null || undefined value props choose an empty value option.
  2. invariant warn passing null || undefined is non-effective.

jsbin example

@sophiebits

This comment has been minimized.

Copy link
Collaborator

commented Jun 10, 2015

Intended. null/undefined aren't the same as the empty string so if you want to select the value with value="", that's what you should pass.

We interpret <select value={null}> to mean an uncontrolled component (similar to #2533).

@sophiebits sophiebits closed this Jun 10, 2015

@blainekasten

This comment has been minimized.

Copy link
Contributor Author

commented Jun 11, 2015

That seems reasonable. I think we should through an invariant then when props is null || undefined and an onChange is specified. Seeing how many people it affected in your referenced issue, and how much time I wasted trying to figure out what was happening, it would be nice if we were warned in these situations.

@sophiebits

This comment has been minimized.

Copy link
Collaborator

commented Jun 11, 2015

@blainekasten Interesting idea. Unfortunately it's fairly common to have an uncontrolled component but also listen to onChange so I don't know if that can work.

@blainekasten

This comment has been minimized.

Copy link
Contributor Author

commented Jun 11, 2015

@spicyj hmm. I guess I can think of situations where that might happen.

So, if interested, I think I have an idea. We could get really crazy and have the jsx parser do lookahead things to flag react with information to help debug further.

ie, lookahead parser could do this:

// this
<input value={this.state.something} onChange{ ... } />
// to this
React.createElement("input", {value: ..., onChange: ..., __controlled: true}, ....)

Then react could be able to throw up additional warnings for __controlled inputs based on things. like null || undefined values.

This would only happen in the dev mode only also.

@blainekasten

This comment has been minimized.

Copy link
Contributor Author

commented Jun 11, 2015

We could move this to a discussion idea in react-future too if ya'll think it's worth discussing.

@sophiebits

This comment has been minimized.

Copy link
Collaborator

commented Jun 11, 2015

We don't want to add DOM-specific logic into the JSX transform. It's more likely that we'd split out ControlledInput and UncontrolledInput into separate components which would also solve the problem, but honestly this probably isn't tripping up enough people for it to be worth making that change for us now.

@tkrotoff

This comment has been minimized.

Copy link

commented Nov 25, 2016

If someone pass by, here what I do to have a select "placeholder":

<select name="month"
        value={this.props.month ? this.props.month : ''}
        onChange={handleChange}>
  <option value="" disabled>Month</option>
  <option value="1">Jan</option>
  <option value="2">Feb</option>
  <option value="3">Mar</option>
  <option value="4">Apr</option>
  <option value="5">May</option>
  <option value="6">Jun</option>
  <option value="7">Jul</option>
  <option value="8">Aug</option>
  <option value="9">Sep</option>
  <option value="10">Oct</option>
  <option value="11">Nov</option>
  <option value="12">Dec</option>
</select>

If month is null or undefined => value is '' (empty string).

You could also write:

  • value={this.props.month ? this.props.month : '0'} + <option value="0" disabled>Month</option>
  • or value={'' + this.props.month} + <option value="undefined">Month</option>

But I don't recommend it and you should stay with <option value="" ...> instead because HTML5 validation with attribute required only works if the value of the first option element in the select element's list of options (if any) is the empty string.

Visually:

screen shot 2016-11-25 at 17 07 28

screen shot 2016-11-25 at 17 07 40

Since Month is disabled, the user cannot select it. If you don't want Month to be displayed in the list, used the hidden attribute (works perfectly under Chrome 54 and Firefox 47; not/partially under IE 11, Edge 38 and Safari 10).

@mahadehassan34

This comment has been minimized.

Copy link

commented Nov 25, 2016

05 10 1995

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.