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.
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
I have an html select element that I am filling from a database (List of companies) Data
I am trying to capture the 2 values in the select
The field "company name (alias)" and The CompanyID field
I can't use an index in the map since this list is ordered in a specific way and the id(pk) needs to match the name field
But I can't capture the 2 data
Index
function ManejadorDeCambios(e) {
setformDato((estadoAnterior) => ({
...estadoAnterior,
[e.target.name]: {
pk: e.target.key,
titulo: e.target.value,
},
}));
}
<Console stateName={formDato} />
<label htmlFor="Compania">Compañia:</label>
<Select
name="Dato"
id="Dato"
on_change={ManejadorDeCambios}
db={datos}
/>
select Component
const Select = function ({ name, db, on_change }) {
return (
<>
{Array.isArray(db) ? (
<select name={name} onChange={on_change}>
<option key="0" value="-- Seleccionar --">
-- Seleccionar --
</option>
{db.map((x, index) => (
<option key={x.companiaID} value={x.alias}>
{x.alias}
</option>
))}
</select>
) : null}
</>
);
};
export default Select;
How can I capture the value of key?
One approach would be to change the arguments of ManejadorDeCambios
function ManejadorDeCambios(event, name) {
setformDato((estadoAnterior) => ({
...estadoAnterior,
[name]: {
pk: event.target.key,
titulo: event.target.value
},
}));
}
And change the onChange handler for select accordingly
<select name={name} onChange={(event) => on_change(event, name)}>
I'm trying to loop through the below data structure and set 'Select' fields options. This is where I have an issue. I'm trying to assign 'nameCombined' & 'codeCombined' to the value and text of the Select Form field.
DataStructure:
{
"Bucks":{
"countyCode":"42017",
"globalStateCode":"PA",
"stateCode":"PA",
"nameCombined":"42017 (PA)",
"codeCombined":"42017 PA Bucks"
},
"Montgomery":{
"countyCode":"42091",
"globalStateCode":"PA",
"stateCode":"PA",
"nameCombined":"42091 (PA)",
"codeCombined":"42091 PA Montgomery"
}
}
React JSX
Select Component
const {
name,
options,
actions: { handleFieldChange },
} = props;
<select id={name} onChange={(e) => handleValueChange(e)}>
{options.map((option, idx) => (
<option key={`${option.value}_${idx}`} value={option.value}>
{value === option.text}
</option>
))}
</select>;
// The component that consumes Select Component
// ============================================
<Select
inputData={{
name:name,
options:Object.entries(counties).map(([key, item]) => ({'value': item.nameCombined, 'text': item.codeCombined})), // <- this line needs attention
type:INPUT_TYPES.DROPDOWN,
}},
actions={{
handleFieldChange: handleDropdownChange
}}
/>
Try Object.keys instead of Object.entries.
Object.keys(counties).map(key => ({value: counties[key].nameCombined, item: counties[key].codeCombined}))
The conceptual limitation that you have in your assumption is that you need a proper array to iterate and Object.entries gives you [[key1, object1],...] while Object.keys gives you [key1, key2].
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 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>
});