OnChange event using React JS for drop down - javascript

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>

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>

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

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>

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>
);
}
}

Geting key value of the dropdown list in reactjs

I'm trying to get the 'key' value of my dynamic dropdown list as follows:
searchSubmit(e){
const s = e.target.value;
alert(s);
}
my dropdown list is as follows:
<select
className="textboxstyle"
onChange={this.searchSubmit}
>
<option key='-1'>Select Brand</option>
<option key='0'>ALL</option>
{optionItems}
</select>
And my dynamic drop-down is populated as follows,
let brands = this.state.brands;
let optionItems = brands.map((brand) =>
<option key={brand.id}>{brand.name}</option>
);
But when I select option, alert display the name of the selected value, not the key. How to get the 'key' value?
Thanks
The key prop is used by React to differentiate between all the elements in an array. If you want value to be the id of the brand, you can use it as value as well as key.
Example
class App extends React.Component {
state = {
brands: [{ id: 1, name: "Foo" }, { id: 2, name: "Bar" }]
};
searchSubmit = e => {
const { value } = e.target;
alert(value);
};
render() {
const { brands } = this.state;
return (
<select onChange={this.searchSubmit}>
<option value="-1">Select Brand</option>
<option value="0">ALL</option>
{brands.map(brand => (
<option value={brand.id} key={brand.id}>
{brand.name}
</option>
))}
</select>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>

React: How to listen to child component events

I have a component, let's say it contains a form. The form has child components which are essentially UI widgets for outputting text inputs and select menus.
The select menu components are a bit fancy and do some state maintaining using the onChange event.
My question is; how do I hook into the onChange event for a select menu from the parent (form) component? I can't pass onChange through props as I already have onChange specified inside the select component and I don't want to override it.
Example:
var Form = React.createClass({
handleSelectChange: function(){
// Do something when <Select /> changes
},
render: function () {
var selectMenuOptions = [
{label: 'Choose...', value: ''},
{label: 'First option', value: 'one'},
{label: 'Second option', value: 'two'}
];
return (
<form>
<Select name="selectMenu" id="selectMenu" options={selectMenuOptions} />
</form>
);
}
});
var Select = React.createClass({
getDefaultProps: function() {
return {
options: [],
className: "select"
};
},
getInitialState: function () {
return {
buttonText: 'Loading...',
defaultValue: null
};
},
handleChange: function (e) {
// Update buttonText state
},
render: function () {
return (
<div className={this.props.className}>
<div className="select__button">{this.state.buttonText}</div>
<select className="select__selector"
ref="select"
onChange={this.handleChange}>
{this.props.options.map(function(option, i){
return (<Option option={option} key={i} />);
})}
</select>
</div>
);
}
});
Using <Select onChange={...} /> won't override the <select onChange={...} /> inside Select's render method. The <Select/> component and the <select/> component it renders have completely different sets of props.
The simplest way to do what you want, I think, is to have your Select's handleChange method call this.props.onChange. You can just pass it the same e argument handleChange receives:
var Form = React.createClass({
handleSelectChange: function(){
// Do something when <Select /> changes
},
render: function () {
// ...
return (
<form>
<Select name="selectMenu"
id="selectMenu"
options={selectMenuOptions}
onChange={this.handleSelectChange} />
</form>
);
}
});
var Select = React.createClass({
// ...
handleChange: function (e) {
if (this.props.onChange) {
this.props.onChange(e);
}
// Update buttonText state
},
render: function () {
return (
<div className={this.props.className}>
<div className="select__button">{this.state.buttonText}</div>
<select className="select__selector"
ref="select"
onChange={this.handleChange}>
{this.props.options.map(function(option, i){
return (<Option option={option} key={i} />);
})}
</select>
</div>
);
}
});

Categories

Resources