I try to handle a multiple form select option, in ReactJS. I have tried to be inspire of javascript classic code to handle that, but I fail.
My code just don't send me the values selected. How handle that ?
Here my code :
class ChooseYourCharacter extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.option});
}
handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite La Croix flavor:
<select multiple={true} value={this.state.value} 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>
);
}
}
ReactDOM.render(
<ChooseYourCharacter/>,
document.getElementById('root')
)
Of my basic understanding, when you try to handle a Select form element in reactJS you generates an object in HTMLOptionsCollection.
The fundamental root to this object methods and properties is e.target.options.
Your items are stored in e.target.options.value property.
To access to a value stored in the options.value object, you can use the [i] loop value, hence e.target.options[i].value property.
The e.target.options[i].value return strings data types.
Following what I have just said, I assume the objects are stored respecting a number increasing convention as following :
e.target.options[i].value where { [i] : value, [i +1] : value (...)}...
By using e.target.options[i].selected you can control if there is a value stored at a specific location.
e.target.options[i].selected return you a boolean value, useful to handle the code flow.
It's up to you now.
Here my code to handle multiple select form in JSX with javascript code :
// Create the React Component
class ChooseYourCharacter extends React.Component {
// Set the constructor
constructor(props) {
super(props);
this.state = {value: 'coconut'};
// bind the functions
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
// extract the value to fluently setState the DOM
handleChange (e) {
var options = e.target.options;
var value = [];
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
value.push(options[i].value);
}
}
this.setState({value: value});
}
// display in client-side the values choosen
handleSubmit() {
alert("you have choose :" + this.state.value);
}
(...)
Here is how to get the options selected by the user using a functional component and the useState hook rather than a class component:
import React, { useState } from "react";
const ChooseYourCharacter = function(props) {
const [selectedFlavors, setSelectedFlavors] = useState([]);
const handleSelect = function(selectedItems) {
const flavors = [];
for (let i=0; i<selectedItems.length; i++) {
flavors.push(selectedItems[i].value);
}
setSelectedFlavors(flavors);
}
return (
<form>
<select multiple={true} value={selectedFlavors} onChange={(e)=> {handleSelect(e.target.selectedOptions)}}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</form>
);
};
export default ChooseYourCharacter;
Currently learning React and I noticed this same code on the reactjs.org site. Below is my solution for handling multiple selected options.
in the constructor, use an array for the initial value for 'value' in the state
in the handleChange method, convert the event target's selectedOptions (HTMLOptionsCollection - array-like) to an array using Array.from(), and use a mapping function to get the value from each item
class ChooseYourCharacter extends React.Component {
constructor(props) {
super(props);
//this.state = {value: 'coconut'};
this.state = {value: ['coconut']};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
//this.setState({value: event.option});
this.setState({value: Array.from(event.target.selectedOptions, (item) => item.value)});
}
handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite La Croix flavor:
<select multiple={true} value={this.state.value} 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>
);
}
}
ReactDOM.render(
<ChooseYourCharacter/>,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
As you are using multi-select you should declare your state variable as an array
constructor(props) {
super(props);
this.state = {value: []};//This should be an array
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
I have created a blog for reactjs form posting with multi select control. You may go here for more details https://handyopinion.com/git-commands-cheat-sheet/
I am using react bootstrap 4 here
<Form.Group >
<Form.Label>Form Label</Form.Label>
<Form.Control
as="select"
multiple
// value={formCatState}
onChange={(event) => {
let target = event.target as HTMLSelectElement
console.log(target.selectedOptions);
}}
>
<option>example cat 1</option>
<option>Example cat 2</option>
<option>Example cat 3</option>
<option>Example cat 4</option>
</Form.Control>
<Form.Text muted> hold ctrl or command for multiple select</Form.Text>
</Form.Group>
I need your help !
I'm on a project for my compagny and I should create a select field that can be duplicate with React. So, I have a little problem when I want to save my selection, if I refresh the page, the default option still the same (and not the selected one). There is my code for select.js:
import React, { Component, PropTypes } from 'react';
class Select extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
}
handleChange(data) {
this.setState({value:data.value});
}
render() {
return (
<label>
<select className="widefat" name={this.props.name} 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>
);
}
}
export default Select;
I change the default value :
When i change the select option
After a refresh
I think it's because in select.js It initialize the value to '' and don't save the selection but I don't know how to save the selection.
Here's a way to accomplish this:
import React, { Component, PropTypes } from 'react';
class Select extends Component {
constructor(props) {
super(props);
this.state = { value: props.value }; // can be initialized by <Select value='someValue' />
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
return (
<label>
<select className="widefat" value={this.state.value} name={this.props.name} onChange={this.handleChange.bind(this)}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
);
}
}
export default Select;
Going further
You could iterate in a map in the render method to implement this like so:
render() {
const dictionary = [
{ value: 'grapefruit', label: 'Grapefruit' },
{ value: 'lime', label: 'Lime' },
{ value: 'coconut', label: 'Coconut' },
{ value: 'mango', label: 'Mango' }
];
return (
<label>
<select
className="widefat"
value={this.state.value}
name={this.props.name}
onChange={this.handleChange}
>
{dictionary.map(
// Iterating over every entry of the dictionary and converting each
// one of them into an `option` JSX element
({ value, label }) => <option key={value} value={value}>{label}</option>
)}
</select>
</label>
);
}
The target event property returns the element that triggered the event. It stores a lot of properties, print it to the console, that would familiarize with its capabilities
import React, { Component } from 'react';
class Select extends Component {
constructor(props) {
super(props);
this.state = { value: '' };
}
handleChange = e => this.setState({ value: e.target.value });
render() {
return (
<label>
<select className="widefat" name={this.props.name} 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>
);
}
}
export default Select;
After a long journey to search in documentation and in the depth of internet I found my answer. I forgot to add a "for" for my label. There is my final code :
import React, { Component, PropTypes } from 'react';
class Select extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: this.props.value});
}
render() {
return (
<label htmlFor={this.props.id}>{this.props.label}
<select defaultValue={this.props.value} id={this.props.id} className="widefat" name={this.props.name} onChange={this.handleChange.bind(this)}>
<option>Aucun</option>
<option value="55">Option 2</option>
<option value="126">Backend configuration & installation</option>
<option value="125">Frontend integration</option>
<option value="124">Graphic Design</option>
</select>
</label>
);
}
}
export default Select;
I'm using a dropdown box with ReactJS and I'm using the default values that I get from "this.state.whoIsChecked.allowDestroyAll". But when I use it as default value, I can't change the value anymore. Here follows the code I'm using:
<select
className="form-control"
id="ada"
value={this.state.whoIsChecked.allowDestroyAll}>
<option>true</option>
<option>false</option>
</select>
You are using the controlled element, using the value property (means controlling the value of selectfield by the state variable), you need to define the onchange method to update that state value otherwise selectfield will become read-only.
Write it like this:
<select
className="form-control"
id="ada"
value={this.state.whoIsChecked.allowDestroyAll}
onChange={this.change}
>
<option value='true'>true</option>
<option value='false'>false</option>
</select>
change = (e) => {
let whoIsChecked = Object.assign({}, this.state.whoIsChecked)
whoIsChecked.allowDestroyAll = e.target.value;
this.setState({whoIsChecked});
}
Note: You need to assign the unique value to each option.
You need to add an onChange event with the controlled input and update the state in order to change the value after providing a value to Option field like
handleChange(e) {
var whoIsChecked = {...this.state.whoIsChecked}
whoIsChecked.allowDestroyAll = e.target.value
this.setState({whoIsChecked})
}
render( ) {
return <select
className="form-control"
id="ada"
onChange={(e) => this.handleChange(e)}
value={this.state.whoIsChecked.allowDestroyAll}>
<option value="true">true</option>
<option value="false">false</option>
</select>
}
class App extends React.Component {
state= {
whoIsChecked: {
allowDestroyAll: "true"
}
}
handleChange(e) {
var whoIsChecked = {...this.state.whoIsChecked}
whoIsChecked.allowDestroyAll = e.target.value
this.setState({whoIsChecked}, ()=> {console.log(this.state)})
}
render( ) {
return <select
className="form-control"
id="ada"
onChange={(e) => this.handleChange(e)}
value={this.state.whoIsChecked.allowDestroyAll}>
<option value="true">true</option>
<option value="false">false</option>
</select>
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Whats the approved way to create select element in react, which is two way bound with the prop of selection containing component? The default selection should be the present attribute of the prop (may be generated, because the value is arbitrary, and on selection the prop attribute should reflect the selection. Also, it should be possible to write the value directly to the selection field.
There isn't an "approved" way as such, but you should note a couple of things:
The change event is triggered on the element, not the element.
Controlled and uncontrolled components defaultValue are set differently.
This is a generic example of a controlled dropdown menu
var MyDropdown = React.createClass({
getInitialState: function() {
return {
value: 'select'
}
},
change: function(event){
this.setState({value: event.target.value});
},
render: function(){
return(
<div>
<select id="fruit" onChange={this.change} value={this.state.value}>
<option value="select">Select</option>
<option value="Apples">Apples</option>
<option value="Mangoes">Mangoes</option>
</select>
<p></p>
<p>{this.state.value}</p>
</div>
);
}
});
React.render(<MyDropdown />, document.body);
and here's a working demo.
I add the options to an array on state and then map overthem,
try this code
import React, { Component } from 'react'
class SelectExample extends Component {
constructor() {
super()
this.state = {
options: ['One', 'Tow', 'Three'],
selectedOption: 'One',
}
}
handleChange = e => {
this.setState({
[e.target.name]: e.target.value,
})
}
render() {
return (
<select name='selectedOption' onChange={this.handleChange}>
{this.state.options.map(i => i == this.state.selectedOption ? (
<option value={i} selected>
{i}
</option>
) : (<option value={i}>{i}</option>) )}
</select>
)
}
}
In a React component for a <select> menu, I need to set the selected attribute on the option that reflects the application state.
In render(), the optionState is passed from the state owner to the SortMenu component. The option values are passed in as props from JSON.
render: function() {
var options = [],
optionState = this.props.optionState;
this.props.options.forEach(function(option) {
var selected = (optionState === option.value) ? ' selected' : '';
options.push(
<option value={option.value}{selected}>{option.label}</option>
);
});
// pass {options} to the select menu jsx
However that triggers a syntax error on JSX compilation.
Doing this gets rid of the syntax error but obviously doesn't solve the problem:
var selected = (optionState === option.value) ? 'selected' : 'false';
<option value={option.value} selected={selected}>{option.label}</option>
I also tried this:
var selected = (optionState === option.value) ? true : false;
<option value={option.value} {selected ? 'selected' : ''}>{option.label}</option>
Is there a recommended way of solving this?
React makes this even easier for you. Instead of defining selected on each option, you can (and should) simply write value={optionsState} on the select tag itself:
<select value={optionsState}>
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
For more info, see the React select tag doc.
Also, React automatically understands booleans for this purpose, so you can simply write (note: not recommended)
<option value={option.value} selected={optionsState == option.value}>{option.label}</option>
and it will output 'selected' appropriately.
You could do what React warns you when you try to set the "selected" property of the <option>:
Use the defaultValue or value props on <select> instead of setting selected on <option>.
So, you can use options.value on the defaultValue of your select
Here is a complete solution which incorporates the best answer and the comments below it (which might help someone struggling to piece it all together):
UPDATE FOR ES6 (2019) - using arrow functions and object destructuring
in main component:
class ReactMain extends React.Component {
constructor(props) {
super(props);
this.state = { fruit: props.item.fruit };
}
handleChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
}
saveItem = () => {
const item = {};
item.fruit = this.state.fruit;
// do more with item object as required (e.g. save to database)
}
render() {
return (
<ReactExample name="fruit" value={this.state.fruit} handleChange={this.handleChange} />
)
}
}
included component (which is now a stateless functional):
export const ReactExample = ({ name, value, handleChange }) => (
<select name={name} value={value} onChange={handleChange}>
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
)
PREVIOUS ANSWER (using bind):
in main component:
class ReactMain extends React.Component {
constructor(props) {
super(props);
// bind once here, better than multiple times in render
this.handleChange = this.handleChange.bind(this);
this.state = { fruit: props.item.fruit };
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
saveItem() {
const item = {};
item.fruit = this.state.fruit;
// do more with item object as required (e.g. save to database)
}
render() {
return (
<ReactExample name="fruit" value={this.state.fruit} handleChange={this.handleChange} />
)
}
}
included component (which is now a stateless functional):
export const ReactExample = (props) => (
<select name={props.name} value={props.value} onChange={props.handleChange}>
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
)
the main component maintains the selected value for fruit (in state), the included component displays the select element and updates are passed back to the main component to update its state (which then loops back to the included component to change the selected value).
Note the use of a name prop which allows you to declare a single handleChange method for other fields on the same form regardless of their type.
I was making a drop-down menu for a language selector - but I needed the dropdown menu to display the current language upon page load. I would either be getting my initial language from a URL param example.com?user_language=fr, or detecting it from the user’s browser settings. Then when the user interacted with the dropdown, the selected language would be updated and the language selector dropdown would display the currently selected language.
Since this whole thread has been giving fruit examples, I got all sorts of fruit goodness for you.
First up, answering the initially asked question with a basic React functional component - two examples with and without props, then how to import the component elsewhere.
Next up, the same example - but juiced up with Typescript.
Then a bonus finale - A language selector dropdown component using Typescript.
Basic React (16.13.1) Functional Component Example. Two examples of FruitSelectDropdown , one without props & one with accepting props fruitDetector
import React, { useState } from 'react'
export const FruitSelectDropdown = () => {
const [currentFruit, setCurrentFruit] = useState('oranges')
const changeFruit = (newFruit) => {
setCurrentFruit(newFruit)
}
return (
<form>
<select
onChange={(event) => changeFruit(event.target.value)}
value={currentFruit}
>
<option value="apples">Red Apples</option>
<option value="oranges">Outrageous Oranges</option>
<option value="tomatoes">Technically a Fruit Tomatoes</option>
<option value="bananas">Bodacious Bananas</option>
</select>
</form>
)
}
Or you can have FruitSelectDropdown accept props, maybe you have a function that outputs a string, you can pass it through using the fruitDetector prop
import React, { useState } from 'react'
export const FruitSelectDropdown = ({ fruitDetector }) => {
const [currentFruit, setCurrentFruit] = useState(fruitDetector)
const changeFruit = (newFruit) => {
setCurrentFruit(newFruit)
}
return (
<form>
<select
onChange={(event) => changeFruit(event.target.value)}
value={currentFruit}
>
<option value="apples">Red Apples</option>
<option value="oranges">Outrageous Oranges</option>
<option value="tomatoes">Technically a Fruit Tomatoes</option>
<option value="bananas">Bodacious Bananas</option>
</select>
</form>
)
}
Then import the FruitSelectDropdown elsewhere in your app
import React from 'react'
import { FruitSelectDropdown } from '../path/to/FruitSelectDropdown'
const App = () => {
return (
<div className="page-container">
<h1 className="header">A webpage about fruit</h1>
<div className="section-container">
<h2>Pick your favorite fruit</h2>
<FruitSelectDropdown fruitDetector='bananas' />
</div>
</div>
)
}
export default App
FruitSelectDropdown with Typescript
import React, { FC, useState } from 'react'
type FruitProps = {
fruitDetector: string;
}
export const FruitSelectDropdown: FC<FruitProps> = ({ fruitDetector }) => {
const [currentFruit, setCurrentFruit] = useState(fruitDetector)
const changeFruit = (newFruit: string): void => {
setCurrentFruit(newFruit)
}
return (
<form>
<select
onChange={(event) => changeFruit(event.target.value)}
value={currentFruit}
>
<option value="apples">Red Apples</option>
<option value="oranges">Outrageous Oranges</option>
<option value="tomatoes">Technically a Fruit Tomatoes</option>
<option value="bananas">Bodacious Bananas</option>
</select>
</form>
)
}
Then import the FruitSelectDropdown elsewhere in your app
import React, { FC } from 'react'
import { FruitSelectDropdown } from '../path/to/FruitSelectDropdown'
const App: FC = () => {
return (
<div className="page-container">
<h1 className="header">A webpage about fruit</h1>
<div className="section-container">
<h2>Pick your favorite fruit</h2>
<FruitSelectDropdown fruitDetector='bananas' />
</div>
</div>
)
}
export default App
Bonus Round: Translation Dropdown with selected current value:
import React, { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
export const LanguageSelectDropdown: FC = () => {
const { i18n } = useTranslation()
const i18nLanguage = i18n.language
const [currentI18nLanguage, setCurrentI18nLanguage] = useState(i18nLanguage)
const changeLanguage = (language: string): void => {
i18n.changeLanguage(language)
setCurrentI18nLanguage(language)
}
return (
<form>
<select
onChange={(event) => changeLanguage(event.target.value)}
value={currentI18nLanguage}
>
<option value="en">English</option>
<option value="de">Deutsch</option>
<option value="es">Español</option>
<option value="fr">Français</option>
</select>
</form>
)
}
An invaluable resource for React/Typescript
Here is the latest example of how to do it. From react docs, plus auto-binding "fat-arrow" method syntax.
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
}
handleChange = (event) =>
this.setState({value: event.target.value});
handleSubmit = (event) => {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} 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>
);
}
}
Main Point - Controlled Component
You are looking to set up a "Controlled Component". This will require you to set the value on the element as well as handle the on change event to update the value.
https://reactjs.org/docs/forms.html#controlled-components
Examples
https://codepen.io/codyswartz/pen/QWqYNrY
Simple Functional Component Select Example
This also includes a default and grays it out.
const defaultSelectValue = "Select a fruit"
const SelectExample = () => {
const [selected, setSelected] = useState(defaultSelectValue)
return (
<>
<label htmlFor="fruits">Fruits</label>{' '}
<select
id="fruits"
name="fruits"
defaultValue={selected}
style={{ color: selected === defaultSelectValue ? "gray" : "black" }}
onChange={e => setSelected(e.target.value)}
>
<option>{defaultSelectValue}</option>
<option>Banana</option>
<option>Apple</option>
<option>Orange</option>
</select>
<h2>Selected: {selected}</h2>
</>
)
}
// Usage
<SelectExample />
Dynamic Reusable Example with Default
This would take a collection of strings using the first as a default.
const SelectExample = ({ name, items }) => {
const defaultSelectValue = items[0]
const [selected, setSelected] = useState(defaultSelectValue)
return (
<>
<label htmlFor={name}>{name}</label>{' '}
<select
id={name}
name={name}
defaultValue={selected}
style={{ color: selected === defaultSelectValue ? "gray" : "black" }}
onChange={e => setSelected(e.target.value)}
>
{items.map(item => (
<option key={item} value={item}>
{item}
</option>
))}
</select>
<h2>Selected: {selected}</h2>
</>
)
}
// Usage
<SelectExample
name="fruits"
items={['Select a fruit', 'Banana', 'Apple', 'Orange']}
/>
With React 16.8. We can do this with hooks like the following example
Codesandbox link
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const options = [
"Monty Python and the Holy Grail",
"Monty Python's Life of Brian",
"Monty Python's The Meaning of Life"
];
const filmsByTati = [
{
id: 1,
title: "Jour de fête",
releasedYear: 1949
},
{
id: 2,
title: "Play time",
releasedYear: 1967
},
{
id: 3,
releasedYear: 1958,
title: "Mon Oncle"
}
];
const [selectedOption, setSelectedOption] = useState(options[0]);
const [selectedTatiFilm, setSelectedTatiFilm] = useState(filmsByTati[0]);
return (
<div className="App">
<h1>Select Example</h1>
<select
value={selectedOption}
onChange={(e) => setSelectedOption(e.target.value)}
>
{options.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
<span>Selected option: {selectedOption}</span>
<select
value={selectedTatiFilm}
onChange={(e) =>
setSelectedTatiFilm(
filmsByTati.find(film => (film.id == e.target.value))
)
}
>
{filmsByTati.map((film) => (
<option key={film.id} value={film.id}>
{film.title}
</option>
))}
</select>
<span>Selected option: {selectedTatiFilm.title}</span>
</div>
);
}
Simply add as first option of your select tag:
<option disabled hidden value=''></option>
This will become default and when you'll select a valid option will be setted on your state
***Html:***
<div id="divContainer"></div>
var colors = [{ Name: 'Red' }, { Name: 'Green' }, { Name: 'Blue' }];
var selectedColor = 'Green';
ReactDOM.render(<Container></Container>, document.getElementById("divContainer"));
var Container = React.createClass({
render: function () {
return (
<div>
<DropDown data={colors} Selected={selectedColor}></DropDown>
</div>);
}
});
***Option 1:***
var DropDown = React.createClass(
{
render: function () {
var items = this.props.data;
return (
<select value={this.props.Selected}>
{
items.map(function (item) {
return <option value={item.Name }>{item.Name}</option>;
})
}
</select>);
}
});
***Option 2:***
var DropDown = React.createClass(
{
render: function () {
var items = this.props.data;
return (
<select>
{
items.map(function (item) {
return <option value={item.Name} selected={selectedItem == item.Name}>{item.Name}</option>;
})
}
</select>);
}
});
***Option 3:***
var DropDown = React.createClass(
{
render: function () {
var items = this.props.data;
return (
<select>
{
items.map(function (item) {
if (selectedItem == item.Name)
return <option value={item.Name } selected>{item.Name}</option>;
else
return <option value={item.Name }>{item.Name}</option>;
})
}
</select>);
}
});
Use defaultValue to preselect the values for Select.
<Select defaultValue={[{ value: category.published, label: 'Publish' }]} options={statusOptions} onChange={handleStatusChange} />
if you store objects in a state.
class Studentinformation extends Component
{
constructor(props)
{
super(props);
this.handlechange=this.handlechange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
this.state={Studentinfo:{
Name:'',
Skill:'Java',
Address:''
}};
}
handlechange(event)
{
const name=event.target.name;
const value=event.target.value;
this.setState({ Studentinfo:
{
...this.state.Studentinfo,
[name]:[value]
}});
}
handleSubmit(event)
{
event.preventDefault();
}
render(){
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>Name: <input type="text" name="Name" value={this.state.Studentinfo.Name} onChange={this.handlechange}></input></label>
<br/>
<label>Skills:
<select value={this.state.Studentinfo.Skill} name="Skill" onChange={this.handlechange}>
<option value="C++" >C++</option>
<option value="C#">C#</option>
<option value="Java">Java</option>
</select>
</label>
<br/>
<textarea value={this.state.Studentinfo.Address} onChange={this.handlechange}/>
<br/>
<input type="submit" value="Submit"></input>
</form>
</div>
);
}
}
I've had a problem with <select> tags not updating to the correct <option> when the state changes. My problem seemed to be that if you render twice in quick succession, the first time with no pre-selected <option> but the second time with one, then the <select> tag doesn't update on the second render, but stays on the default first .
I found a solution to this using refs. You need to get a reference to your <select> tag node (which might be nested in some component), and then manually update the value property on it, in the componentDidUpdate hook.
componentDidUpdate(){
let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag);
selectNode.value = this.state.someValue;
}
Posting a similar answer for MULTISELECT / optgroups:
render() {
return(
<div>
<select defaultValue="1" onChange={(e) => this.props.changeHandler(e.target.value) }>
<option disabled="disabled" value="1" hidden="hidden">-- Select --</option>
<optgroup label="Group 1">
{options1}
</optgroup>
<optgroup label="Group 2">
{options2}
</optgroup>
</select>
</div>
)
}
I have a simple solution is following the HTML basic.
<input
type="select"
defaultValue=""
>
<option value="" disabled className="text-hide">Please select</option>
<option>value1</option>
<option>value1</option>
</input>
.text-hide is a bootstrap's class, if you not using bootstrap, here you are:
.text-hide {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
if you use Stateless then
const IndexPage =({states, selectedState}) => {
return(
<select id="states" defaultValue={selectedState} name="state">
{states.map(state=> (
<option value={state.id} key={state.id}>{state.name}</option>
))
}
</select>
)
}
I got around a similar issue by setting defaultProps:
ComponentName.defaultProps = {
propName: ''
}
<select value="this.props.propName" ...
So now I avoid errors on compilation if my prop does not exist until mounting.