I have a select with options and want to get the value of the option without submitting a form or using button or input.
for example, if I choose USD I want the function return USD,
for EUR, should return EUR
<select value={this.state.value} onChange={this.handleChange}>
<option value="EUR">EUR</option>
<option value="USD">USD</option>
<option value="RUR">RUR</option>
<option value="GBP">GBP</option>
</select>
<select value={this.state.value} onChange={this.handleChange}>
<option value="EUR">EUR</option>
<option value="USD">USD</option>
<option value="RUR">RUR</option>
<option value="GBP">GBP</option>
</select>
You can access to the selected value inside handleChange like so:
handleChange(e) {
console.log(e.target.value); // for ex. will print USD
}
create a function displayUsd() then in the onChange event of the select element use
this.displayUsd.
You can do something like this in onChange={this.handleChange}
handleChange = (e) => {
// e.target.value will USD
}
or
handleChange: function(event){
// event.target.value
}
assuming you are using a class here and extending react.
constructor() {
this.state = { value: 'default Value' }
}
this.handleChange(e) {
this.setState({ value: e.target.value});
}
Related
So basically if I set country in second dropdown to let's say Spain and then want to change the option in first select dropdown, how can I set second dropdown to go back to default value, in this case All Countries?
<select onClick={handleRankingsRange}>
<option value='top 100'>top 100</option>
<option value='top 200'>top 100-200</option>
<option value='top 200+'>top 200+</option>
</select>
<select onClick={handleFilterCountry}>
<option defaultValue='All Countries'>All Countries</option>
{countries
.filter((country) => country !== '')
.sort()
.map((country, index) => {
return (
<option value={country} key={index}>
{country}
</option>
);
})}
</select>
You need to convert your select components to controlled components by using value and onChange like this:
import { useState } from "react";
const countries = ["Spain", "France", "Portugal", "Germany"];
export default function App() {
const [selectedRange, setSelectedRange] = useState();
const [selectedCountry, setSelectedCountry] = useState();
const handleRankingsRange = (e) => {
setSelectedRange(e.target.value);
setSelectedCountry("");
};
const handleFilterCountry = (e) => {
setSelectedCountry(e.target.value);
};
return (
<div>
<select value={selectedRange} onChange={handleRankingsRange}>
<option value="top 100">top 100</option>
<option value="top 200">top 100-200</option>
<option value="top 200+">top 200+</option>
</select>
<select value={selectedCountry} onChange={handleFilterCountry}>
<option value="">All Countries</option>
{countries
.filter((country) => country !== "")
.sort()
.map((country, index) => {
return (
<option value={country} key={index}>
{country}
</option>
);
})}
</select>
<br />
selectedRange = {selectedRange}
<br />
selectedCountry = {selectedCountry}
</div>
);
}
You can take a look at this sandbox for a live working example of this solution.
[Edit] Added the second part of your question to set back to default "all countries"
if using a list (the list in my example will be an array with objects)
let list = [
{
country: "Spain",
options: ["one", "two", "three"],
},
...
]
you could create a state (useState hook) based on the array.
Mapping that list for the options as you have done, you can also map the first selection based on the array that you would set in your state.
My render would look like this:
return (
<>
<select name="rankings" id="selectRankings">
{ranking.map((rank, index) => {
return (
<option key={index} value={rank}>{rank}</option>
)
})}
</select>
<br/>
<select onChange={(e)=>{handleSelection(e)}} name="countries" id="selectCountry">
<option value="All">All Countries</option>
{list.map((item, index) => {
return(
<option key={index} value={item.country}>{item.country}</option>
)
})}
</select>
< />
);
when selecting a country, on change it will execute handleSelection which will find the correct options and update them to your state.
secondly, if you want to reset the value of the second selection element, you can just set it back to "All" (see code below)
const [ranking, setRanking] = useState(["-- select country first --"]);
const handleSelection = (e) => {
list.find(item => {
if (item.country === e.target.value) {
setRanking(item.options)
}
})
e.target.value = "All";
}
sandbox example
In my react app i have an endpoint that returns user details and another on that returns countries and I'm calling both of them in the componentDidMount, i have a country dropdown and it's default value/option should be the country returned from the user details endpoint and it's options should be the countries list returned from the countries endpoint, the problem is when i use the value attribute to set the default value for the select it's always null and it doesn't show a value, so i tried using the <option selected="selected">{this.state.country}</option> but the onChange function doesn't work when i use it, so what's the best approach to achieve that, here is the code:
Using the value attribute:
<select value={this.state.country} onChange={this.handleChange}>{this.renderCountries()}</select>
Using the selected option:
<select onChange={this.handleChange}>
<option selected="selected">{this.state.country}</option>
{this.renderCountries()}
</select>
OnChange function:
handleChange = event => {
this.setState({ selectedOption: event.target.value });
};
Rendering options:
renderCountries() {
return this.state.countries.map(country => (
<option key={country.id} value={country.id}>
{country.name}
</option>
));
}
Set this.state.country to the value returned from the endpoint.
<select value={this.state.country} onChange={this.handleChange}> .
{this.renderCountries()}
</select>
The handleChange needs to setState for country not selectedOption. This is because the value attribute on select is this.state.country
handleChange = event => {
this.setState({ country: event.target.value });
};
renderCountries = () => {
return this.state.countries.map(country => (
<option key={country.id} value={country.id}>
{country.name}
</option>
));
};
Hopefully this should fix your issue.
I am trying to create a simple drop down in react and I am facing two issues. The code that I have is:
import React from "react";
class EditEmployee extends React.Component {
constructor() {
super();
this.state={
salary:''
}
}
validateSalary=(e)=>{
// e.persist();
var val=e.target.value;
this.setState((prevState)=>{prevState.salary=val})
}
render() {
return (
<form>
<div className="form-group">
<label>Salary:</label>
<select onChange={this.validateSalary} className="form-control" value={this.state.salary}>
<option value="20000">20000</option>
<option value="30000">30000</option>
<option value="40000">40000</option>
<option value="50000">50000</option>
</select>
</div>
</form>
);
}
}
export default EditEmployee
Issue 1 - When I select an option, I am able to get the value in the console, but the drop down is not showing the selected value. I am setting the state properly and I am not sure why is it not updating the view.
Issue 2 - If I directly access the event inside setState I get an warning about synthetic event and the code does not work. Why do I need e.persist() to avoid it?
validateSalary(e){
// e.persist();
var val=e.target.value;
this.setState({
salary = val
});
}
<select onChange={e => this.validateSalary(e)} className="form-control" value={this.state.salary}>
<option value="20000">20000</option>
<option value="30000">30000</option>
<option value="40000">40000</option>
<option value="50000">50000</option>
</select>
OR
you need to change your function
validateSalary=(e)=> {
var val = e.target.value;
this.setState({
salary = val
});
}
Can you try this code. I think it is problem in some callback
Try with this change
validateSalary=(e)=> {
let val = e.target.value;
this.setState({salary:val})
}
This will solve your both the issues.
import React from "react";
class EditEmployee extends Component {
constructor(props) {
super(props);
this.state = {
salary: ""
};
}
validateSalary = e => {
// e.persist();
const { name, value } = e.target;
this.setState({ [name]: value }, function() {
console.log(this.state);
});
};
render() {
return (
<form>
<div className="form-group">
<label>Salary:</label>
<select
name="salary"
onChange={this.validateSalary}
className="form-control"
value={this.state.salary}
>
<option value="">Please select salary</option>
<option value="20000">20000</option>
<option value="30000">30000</option>
<option value="40000">40000</option>
<option value="50000">50000</option>
</select>
</div>
</form>
);
}
}
export default EditEmployee;
i'm consoling the state after state is updated, because if you console the state outside you will get previous state value.
I would like to get the data attribute from option using react but for some reason I am unable and I am getting null.
<select onChange={(e) => this.onIndustryChangeOption(e)} value={this.props.selectedIndustry}>
<option value="" data-industry="industry1">Select Industry</option>
<option value="" data-industry="industry2">Select Industry 2</option>
</select>
onIndustryChangeOption(event, index, value) {
console.log(event.target.getAttribute('data-industry'));
this.props.setRootState({selectedIndustry: event.target.value});
}
This is not working, I am sure there should be some other way of doing this!
event.target is the select, not the option. You need to get the option:
onIndustryChangeOption(event, index, value) {
const {target} = event;
const option = target.options[target.selectedIndex];
if (option) {
console.log(option.getAttribute('data-industry'));
//this.props.setRootState({selectedIndustry: event.target.value});
}
}
Live Example:
class Example extends React.Component {
render() {
return <select onChange={(e) => this.onIndustryChangeOption(e)} value={this.props.selectedIndustry}>
<option value="" data-industry="industry1">Select Industry</option>
<option value="" data-industry="industry2">Select Industry 2</option>
</select>;
}
onIndustryChangeOption(event, index, value) {
const {target} = event;
const option = target.options[target.selectedIndex];
if (option) {
console.log(option.getAttribute('data-industry'));
//this.props.setRootState({selectedIndustry: event.target.value});
}
}
}
ReactDOM.render(
<Example />,
document.getElementById("root")
);
<div id="root"></div>
<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>
That said, with the given example, it's not clear why you wouldn't use value instead. :-)
Simply pass callback reference and capture event, use value attribute
<select onChange={this.onIndustryChangeOption} value={this.props.selectedIndustry}>
<option value="industry1">Industry 1</option>
<option value="industry2" >Industry 2</option>
</select>
onIndustryChangeOption(event) {
this.props.setRootState({selectedIndustry: event.target.value});
}
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>