Skip to content

Commit

Permalink
Added an example on how to use <select multiple>
Browse files Browse the repository at this point in the history
The short info segment that is currently provided is insufficient to use an `<select multiple={true}>` element.  

This is especially confusing and frustraring with the sentence **"this makes it so that `<input type="text">`, `<textarea>`, and `<select>` all work very similarly"** right before it: In the case of using the `multiple` attribute, you *do* need to change your code a little bit more.

The linked anonymous codepen is from me, feel free to copy/paste/modify it as you like; afaik all codepen example are owned by @gaearon?  

There is an [alternative codepen example](https://codepen.io/anon/pen/VOEezB?editors=0011) which also deals with writing a more suitable alert message, depending on how many options are selected, but in my opinion it adds unnecessary noice.

This issue has also been addressed in #531, #984.
  • Loading branch information
0xnoob authored May 29, 2019
1 parent 6e79d08 commit 0bfdfa4
Showing 1 changed file with 52 additions and 7 deletions.
59 changes: 52 additions & 7 deletions content/docs/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,58 @@ class FlavorForm extends React.Component {

Overall, this makes it so that `<input type="text">`, `<textarea>`, and `<select>` all work very similarly - they all accept a `value` attribute that you can use to implement a controlled component.

> Note
>
> You can pass an array into the `value` attribute, allowing you to select multiple options in a `select` tag:
>
>```js
><select multiple={true} value={['B', 'C']}>
>```
### Selecting multiple options {#selecting-multiple-options}

You can pass an array into the `value` attribute, allowing you to select multiple options in a `select` tag:

```javascript{4,10-15,18,27-30}
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = { values: ['coconut'] };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const options = Array.from(event.target);
const selectedOptions = options.filter(option => option.selected);
const selectedValues = selectedOptions.map(option => option.value);
this.setState({ values: selectedValues });
}
handleSubmit(event) {
alert('Your favorite flavors are: ' + this.state.values);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select
multiple={true}
value={this.state.values}
onChange={this.handleChange}
>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
```

[**Try it on CodePen**](https://codepen.io/anon/pen/pmxJRd?editors=0011)

Notice that [Array.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) is used to transform `event.target` into an array, so we can use the [filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) and [map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) functions to obtain the values from the selected options.

## The file input Tag {#the-file-input-tag}

Expand Down

0 comments on commit 0bfdfa4

Please sign in to comment.