How to store a value based on another attribute value - javascript

I need to display some attribute of an element in a select, and store the displayed attributes in a value and a different attribute of the same element in another value.
render() {
const refertiItems = this.state.referti.map((referti, i) => {
return (
<option key={referti.hash_referto}>
{referti.tipo_esame}-{referti.data_esame}
</option>
)
});
return(
<Label for="type" text="Descrizione Referto" />
<select
name="descrizioneReferto"
placeholder="Selezionare Referto"
onKeyPress={this.onEnter}
value={this.state.referti.descrizioneReferto}
onChange={this.handleInputChange}
>
<option default value="vuoto"></option>
{refertiItems}
</select>
So in this code i can store {referti.tipo_esame} and {referti.data_esame} in descrizioneReferto. I also need to store {referti.hash_referto} inside codiceReferto. Any advice?

You can access the key of the option element in the onChange function like this:
handleInputChange = (event, child) => {
this.setState({
descrizioneReferto: event.target.value,
codiceReferto: child.key
});
}
To use the material-ui select, change your code to:
<Select
value={this.state.referti.descrizioneReferto}
name="descrizioneReferto"
onKeyPress={this.onEnter}
placeholder="Selezionare Referto"
onChange={this.handleInputChange}>
<MenuItem value="vuoto"/>
{refertiItems}
</Select>
and
const refertiItems = this.state.referti.map((referti, i) => {
return <Menu key={referti.hash_referto}>
{referti.tipo_esame}-{referti.data_esame}
</option>
});

Related

Is there a way in React to change option in select by clicking on another select?

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

React adding custom props to vanilla html elements

const handleChange = (e) => {
console.log(e.target.id);
};
return (
<div>
<select onChange={(e) => handleChange(e)}>
<option value="1-10" id="foo">
1-10
</option>
How can I make the id prop in the <option> tag accessible by the code above? e.target.id returns nothing, but e.target.value returns the selected value. How can I create these custom attributes with when using vanilla html elements?
One of the easiest method to achieve this is as follows:
const handleChange = (e) => {
const index = e.target.selectedIndex;
const id = e.target.childNodes[index].id;
console.log(id); // logs 'foo' or 'bar' depending on selection
};
return (
<div>
<select onChange={(e) => handleChange(e)}>
<option value="1-10" id="foo">
1-10
</option>
<option value="11-20" id="bar">
11-20
</option>
</select>
</div>
);
e.target is the select, not the option. And since the select does not have an id, you are getting nothing. One way to achieve what you want is by doing so :
export default function App() {
const handleChange = (e) => {
const selectedOption = e.target.querySelector(`option[value='${e.target.value}']`);
console.log(selectedOption.id);
};
return (
<select onChange={(e) => handleChange(e)}>
<option value="1-10" id="foo">
1-10
</option>
<option value="1-11" id="bar">
1-11
</option>
</select>
);
}
Here's another way to do so
import React from 'react';
const handleChange = (e) => {
const index = e.target.selectedIndex;
const el = e.target.childNodes[index]
const option = el.getAttribute('id');
console.log(option)
};
export function App(props) {
return (
<div className='App'>
<select onChange={(e) => handleChange(e)}>
<option value="1-10" id="foo">
1-10
</option>
<option value="2-10" id="zoo">
2-10
</option>
</select>
</div>
);
}

Access key value

Inside my render I have a select, and for the options I use a .map, like this:
<select value={this.state.eixo} onChange={this.handleChange}>
<option value=""></option>
{this.state.eixos.map((item) => {
return <option key={item.id}>{item.descricao}</option>
})}
</select>
And I want the key from the option that I choose in my handleChange method, I tried something like this but it doesn't seem to be working:
handleChange = (event) => { this.setState({ key: event.target.value }) };
One way to do it is to Set the value of the option to a key:value pair,
<select value={this.state.eixo} onChange={this.handleChange}>
<option value=""></option>
{this.state.eixos.map(item => {
return (
<option key={item.id} value={`${ite.id}:${item.descricao}`}>
{item.descricao}
</option>
);
})}
</select>;
Then split the e.target.value to get the key : value pair and update the state using bracket notation :
handleChange = event => {
const [key, value] = event.target.value.split(":");
this.setState({ [key]: value });
};
If your values could contain : , choose another seperator.

DefaultValue and changing values in select dropdown

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.

change selected value dropdown reactjs

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>

Categories