React <select>'s <option> is not working at onClick - javascript

I need a function at every here is it.
i want to access option value.
const region = ['Africa','America','Asia','Europe','Oceania'];
<div className="options">
<select>
<option>Select a Region</option>
{region.map((nameOfRegion) => {
return <option onClick={() => requestRegion(nameOfRegion)}>
{nameOfRegion}
</option>
})}
</select>
this function is not logging options
const requestRegion = (region) => {
console.log(region)
}

Use onChange event on the <select>:
const requestRegion = (event) => {
console.log(event.target.value);
};
return (
<div className="options">
<select onChange={requestRegion}>
<option>Select a Region</option>
{
region.map((nameOfRegion) => (<option>{nameOfRegion}</option>))
}
</select>
</div>

Because neither the onSelect() nor onClick() events are supported by the option tag. So you can use onChange in select tag in this case:
const onChange =(e) => {
console.log(e.target.value);
}
<select name="select" onChange = {onChange}>
<option>Select a Region</option>
{region.map((nameOfRegion, i) => {
return (
<option key={i}>
{nameOfRegion}
</option>
);
})}
</select>
Note: you need add key in child tag when using map

You should use an onChange handler on the select element, and get the value from the change event:
const Demo = ({ regions }) => {
const requestRegion = e => {
console.log(e.target.value)
}
return (
<select onChange={requestRegion}>
<option>Select a Region</option>
{regions.map(region => (
<option key={region}>{region}</option>
))}
</select>
)
}
const regions = ['Africa','America','Asia','Europe','Oceania']
ReactDOM.render(
<Demo regions={regions} />,
root
)
<script crossorigin src="https://unpkg.com/react#17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#17/umd/react-dom.development.js"></script>
<div id="root"></div>

Related

How do I add onClick() on a Select Dropdown via React

I'm trying to apply reactI18next on a project, normally you to toggle the language change you would create a button that would call the "changelanguage" function like this:
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
}
<button onClick={() => changeLanguage('en')}>en</button>
However, I was wondering if it's possible to make something similar but In a dropdown fashion.
Is there a way to trigger an onClick via select or other means?
Thanks and I hope to hear you guys soon!
Yes this is possible, you can add onChange event handler on Select tag such as
import { useState } from "react";
export default function App() {
const [lang , setLang] = useState('en')
function changeLanguage(event){
// i18n.changeLanguage(event.target.value)
setLang(event.target.value)
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<p>{lang}</p>
<select value={lang} onChange={changeLanguage}>
<option value="en">English</option>
<option value="fr">French</option>
</select>
</div>
);
}
you can test on working sandbox here
You can just use the onChange prop on the <select> element.
import { useState } from "react";
const languages = {
en: "English",
ta: "Tagalog",
es: "Español"
};
export default function App() {
const [selectedValue, setSelectedValue] = useState("en");
function onChange(e) {
il18n.changeLanguage(e.target.value); // Use your library here
setSelectedValue(e.target.value);
}
return (
<div className="App">
<label for="lang">Choose a language: </label>
<select name="lang" id="lang" onChange={onChange}>
{Object.keys(languages).map((languageKey) => (
<option key={languageKey} value={languageKey}>
{languages[languageKey]}
</option>
))}
</select>
<br />
<br />
<p>Currently selected:</p>
<p>Key: {selectedValue}</p>
<p>Value: {languages[selectedValue]}</p>
</div>
);
}
Please try this one
const [value, setValue] = React.useState('');
const changeLanguage = (event) => {
i18n.changeLanguage(event.target.value);
}
<select value={value} onChange={changeLanguage}>
<option value="en">English</option>
</select>

How can I do to show three params when I click on the select using react.js?

I have a select such as :
<Select id='1' list={[...this.state.dictionnary]}/>
where this.state.dictionnary is like this :
state = {
dictionnary: [
{value: "a", name: "ab"},
]}
And the component select is like this :
class Select extends Component {
handleChange()
{
// I would like to show 1, a and ab
// 1 is the id of the select
// a and ab are value and name of
};
render() {
return (
<select onChange={this.handleChange} className="custom-select">{this.props.list.map(option => (
<option key={option.value} value={option.value}>{option.name}</option>))}
</select>
)
}
}
export default Select;
I would like to show some informations using the handleChange() function like the id, name and value.
Could you help me please ?
Thank you very much
You should change the option so the value has the entire object to get it later in the handleChange. Also, to access the same this with the props in the handleChange method you need to use an arrow function:
<select onChange={(e) => this.handleChange} className="custom-select">
{this.props.list.map((option) => (
<option key={option.value} value={option}>
{option.name}
</option>
))}
</select>
By default, the onChange handler gets the event param so you can get the target and the props:
handleChange(event) {
const { value, name } = event.target.value;
console.log(this.props.id, value, name);
}
Adding to #Alavaro answer, you need to split after getting the value to remote ,
handleChange = e => {
const [value, name] = e.target.value.split(',')
console.log({ id: this.props.id, value, name})
}
render() {
return (
<select onChange={this.handleChange} className="custom-select">
{this.props.list.map((option, index) => (
<option key={option.value} value={[option.value, option.name]} >
{ option.name }
</option>
))}
</select>
);
}
}

Update a select's options based on another dropdown, using React

I've got 2 selects in my form. Options for the 2nd select are generated based on 1st select. Everything works fine except that every time I choose an option for the 2nd select and then change the 1st one, I should get the default option for the 2nd, but it's not resetting.
Code below
const [animalClass, setAnimalClass] = useState();
const [animalType, setAnimalType] = useState();
const [isLoadingClasses, setLoadingClasses] = useState(true);
const [isLoadingTypes, setLoadingTypes] = useState(true);
const [availableAnimalClasses, setAvailableAnimalClasses] = useState();
const [availableAnimalTypes, setAvailableAnimalTypes] = useState();
useEffect(() => {
setLoadingClasses(true);
const availableOptions = async () => {
const availableClasses = await Axios.get();
console.log(availableClasses.data);
if (availableClasses.data.length > 0) {
setAvailableAnimalClasses(availableClasses.data.map(animal => ({name: animal.name})));
setLoadingClasses(false);
}
};
availableOptions();
}, []);
useEffect(() => {
setLoadingTypes(true);
setAnimalType("DEFAULT");
const availableOptions = async () => {
const availableTypes = await Axios.get();
console.log(availableTypes.data);
if(availableTypes.data.length > 0) {
setAvailableAnimalTypes(availableTypes.data.map(animal => ({name: animal.name})));
setLoadingTypes(false);
}
};
availableOptions();
}, [animalClass]);
return (
<div className="page">
<h2>New Auction</h2>
<form className="form" onSubmit={onSubmit}>
<label>
Animal Class
<select defaultValue={'DEFAULT'} onChange={(e) => setAnimalClass(e.target.value)} >
<option value="DEFAULT" disabled>Choose animal class</option>
{isLoadingClasses ? <option value="Loading" disabled>Loading.....</option> : availableAnimalClasses.map((option) => (
<option value={option.name}>{upperCase(option.name)}</option>
))}
</select>
</label>
<label>Animal Type
<select defaultValue={'DEFAULT'} onChange={(e) => setAnimalType(e.target.value)} >
<option value="DEFAULT" disabled>Choose animal type</option>
{isLoadingTypes? <option value="Loading" disabled>Loading.....</option> : availableAnimalTypes.map((option) => (
<option value={option.name}>{upperCase(option.name)}</option>
))}
</select>
Since you are using state to store your form field values, you could set your defaults when you create the hooks:
const [animalClass, setAnimalClass] = useState('DEFAULT');
const [animalType, setAnimalType] = useState('DEFAULT');
and then use value instead of defaultValue in your JSX:
<select value={animalClass} onChange={(e) => setAnimalClass(e.target.value)} >
...
<select value={animalType} onChange={(e) => setAnimalType(e.target.value)} >
These values should reset your select elements when the state changes.
You should call setAnimalType to reset it back to the default when selecting the animal class. Change:
<select defaultValue={'DEFAULT'} onChange={(e) => setAnimalClass(e.target.value)}>...</select>
...to:
<label>
Animal Class
<select
defaultValue={'DEFAULT'}
value={animalClass}
onChange={(e) => {
setAnimalClass(e.target.value);
setAnimalType('DEFAULT');
}}
>
...
</select>
</label>
<label>
Animal Type
<select
defaultValue={'DEFAULT'}
value={animalType}
onChange={(e) => setAnimalType(e.target.value)}
>
// ...
</select>
</label>
This is necessary because the onChange event will not be automatically fired for a select when the options change. In order for this to work, where state controls the state of your <select/>s, you'll also want to change the defaultValueprops tovalue` props.

How to handle multiple select dropdowns in a React application with a single function?

I have a forms with 3 select dropdowns that filter an array based on a selected value. Rather than having an onChange handler for each of these forms I was wondering if I could use a single function too handle all of them based on a parameter.
I tried passing a string into the function but it doesn't work since it is expecting an event to be passed as a parameter.
Here is the code for the react form:
const UserSearchBox = ({ handleChange, handleLocationChange, handleTeamChange, handleClientChange }) => {
return (
<form className="user-search">
<input className="user-input" placeholder="Search for Peeps" name="userSearch" onChange={handleChange} />
<div>
<select defaultValue="all" onChange={handleLocationChange}>
<option value="all">All</option>
<option value="boston">Boston</option>
<option value="chicago">Chicago</option>
<option value="tampa">Tampa</option>
</select>
<select defaultValue="all" onChange={handleTeamChange}>
<option value="all">All</option>
<option value="design">Design</option>
<option value="engineering">Engineering</option>
<option value="finance">Finance</option>
</select>
<select defaultValue="all" onChange={handleClientChange}>
<option value="all">All</option>
<option value="company">Company1</option>
<option value="company2">Company2</option>
<option value="company3">Company3</option>
</select>
</div>
</form>
)
}
And this is the code for the App:
const handleInputChange = (e) => {
e.preventDefault();
let searchTerm = e.target.value;
if(searchTerm){
let filteredUsers = users.filter((x) => x.name.toLowerCase().includes(searchTerm.toLowerCase()))
setUsers(filteredUsers)
} else{
setUsers(allUsers)
}
}
const handleLocationChange = (e) => {
e.preventDefault();
let searchTerm = e.target.value;
if(searchTerm !== "all"){
let filteredUsers = allUsers.filter((x) => x.location.toLowerCase().includes(searchTerm.toLowerCase()))
setUsers(filteredUsers)
} else{
setUsers(allUsers)
}
}
return (
<div className="container-fluid">
<Header name={loggedInUser.name} profile_photo={loggedInUser.profile_photo} />
<UserSearchBox handleLocationChange={handleLocationChange} handleChange={handleInputChange}/>
<Users users={users} />
</div>
)
You can pass additional parameters with the event by changing the onChange to this:
onChange={(e) => { handleLocationChange(e, param1, param2, param3...) }}
Or if you dont need the event you can skip it:
onChange{() => { handleLocationChange(param1, param2, param3...) }}
That way you still get your event inside, and then you add whatever other arguments you want.
Would that help you?
Another potential solution, however I believe #Darkbound had a more precise method.
Add data attributes to the options:
<select defaultValue="all" onChange={handleSelectChange}>
<option data-filter-type="location" value="all">All</option>
<option data-filter-type="location" value="boston">Boston</option>
<option data-filter-type="location" value="chicago">Chicago</option>
<option data-filter-type="location" value="tampa">Tampa</option>
</select>
Then use a switch statement:
if (searchTerm !== "all") {
switch (attr) {
case 'location':
setUsers(users.filter((x) => x.location.toLowerCase().includes(searchTerm.toLowerCase())));
break;
case 'team':
console.log('term: ', searchTerm);
setUsers(users.filter((x) => x.team.toLowerCase().includes(searchTerm.toLowerCase())));
break;
case 'client':
setUsers(users.filter((x) => x.client.toLowerCase().includes(searchTerm.toLowerCase())));
break;
default:
setUsers(allUsers)
}
} else {
setUsers(allUsers)
}

OnChange event using React JS for drop down

var MySelect = React.createClass({
change: function(){
return document.querySelector('#lang').value;
},
render: function(){
return(
<div>
<select id="lang">
<option value="select" onChange={this.change}>Select</option>
<option value="Java" onChange={this.change}>Java</option>
<option value="C++" onChange={this.change}>C++</option>
</select>
<p></p>
<p value={this.change}></p>
</div>
);
}
});
React.render(<MySelect />, document.body);
The onChange event does not work.
The change event is triggered on the <select> element, not the <option> element. However, that's not the only problem. The way you defined the change function won't cause a rerender of the component. It seems like you might not have fully grasped the concept of React yet, so maybe "Thinking in React" helps.
You have to store the selected value as state and update the state when the value changes. Updating the state will trigger a rerender of the component.
var MySelect = React.createClass({
getInitialState: function() {
return {
value: 'select'
}
},
change: function(event){
this.setState({value: event.target.value});
},
render: function(){
return(
<div>
<select id="lang" onChange={this.change} value={this.state.value}>
<option value="select">Select</option>
<option value="Java">Java</option>
<option value="C++">C++</option>
</select>
<p></p>
<p>{this.state.value}</p>
</div>
);
}
});
React.render(<MySelect />, document.body);
Also note that <p> elements don't have a value attribute. React/JSX simply replicates the well-known HTML syntax, it doesn't introduce custom attributes (with the exception of key and ref). If you want the selected value to be the content of the <p> element then simply put inside of it, like you would do with any static content.
Learn more about event handling, state and form controls:
http://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html
http://facebook.github.io/react/docs/forms.html
React Hooks (16.8+):
const Dropdown = ({
options
}) => {
const [selectedOption, setSelectedOption] = useState(options[0].value);
return (
<select
value={selectedOption}
onChange={e => setSelectedOption(e.target.value)}>
{options.map(o => (
<option key={o.value} value={o.value}>{o.label}</option>
))}
</select>
);
};
import React, { PureComponent, Fragment } from 'react';
import ReactDOM from 'react-dom';
class Select extends PureComponent {
state = {
options: [
{
name: 'Select…',
value: null,
},
{
name: 'A',
value: 'a',
},
{
name: 'B',
value: 'b',
},
{
name: 'C',
value: 'c',
},
],
value: '?',
};
handleChange = (event) => {
this.setState({ value: event.target.value });
};
render() {
const { options, value } = this.state;
return (
<Fragment>
<select onChange={this.handleChange} value={value}>
{options.map(item => (
<option key={item.value} value={item.value}>
{item.name}
</option>
))}
</select>
<h1>Favorite letter: {value}</h1>
</Fragment>
);
}
}
ReactDOM.render(<Select />, window.document.body);
handleChange(value, selectOptionSetter) => {
selectOptionSetter(value)
// handle other stuff like persisting to store etc
}
const Dropdown = (props) => {
const { options } = props;
const [selectedOption, setSelectedOption] = useState(options[0].value);
return (
<select
value={selectedOption}
onChange={e => handleChange(e.target.value, setSelectedOption)}>
{options.map(o => (
<option key={o.value} value={o.value}>{o.label}</option>
))}
</select>
);
};
If you are using select as inline to other component, then you can also use like given below.
<select onChange={(val) => this.handlePeriodChange(val.target.value)} className="btn btn-sm btn-outline-secondary dropdown-toggle">
<option value="TODAY">Today</option>
<option value="THIS_WEEK" >This Week</option>
<option value="THIS_MONTH">This Month</option>
<option value="THIS_YEAR">This Year</option>
<option selected value="LAST_AVAILABLE_DAY">Last Availabe NAV Day</option>
</select>
And on the component where select is used, define the function to handle onChange like below:
handlePeriodChange(selVal) {
this.props.handlePeriodChange(selVal);
}
I'll add this here, in case it helps someone because this was the solution that helped me.
This is to get the SELECTED INDEX. Not for the value.
(Worked for me because my options list was a list of numbers)
const [selectedOption, setSelectedOption] = useState(0)
<select onChange={event => setSelectedOption(event.target.options.selectedIndex)}>
Thank you Felix Kling, but his answer need a little change:
var MySelect = React.createClass({
getInitialState: function() {
return {
value: 'select'
}
},
change: function(event){
this.setState({value: event.target.value});
},
render: function(){
return(
<div>
<select id="lang" onChange={this.change.bind(this)} value={this.state.value}>
<option value="select">Select</option>
<option value="Java">Java</option>
<option value="C++">C++</option>
</select>
<p></p>
<p>{this.state.value}</p>
</div>
);
}
});
React.render(<MySelect />, document.body);
var MySelect = React.createClass({
getInitialState: function() {
var MySelect = React.createClass({
getInitialState: function() {
return {
value: 'select'
}
},
change: function(event){
event.persist(); //THE MAIN LINE THAT WILL SET THE VALUE
this.setState({value: event.target.value});
},
render: function(){
return(
<div>
<select id="lang" onChange={this.change.bind(this)} value={this.state.value}>
<option value="select">Select</option>
<option value="Java">Java</option>
<option value="C++">C++</option>
</select>
<p></p>
<p>{this.state.value}</p>
</div>
);
}
});
React.render(<MySelect />, document.body);
<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>

Categories

Resources