I'm trying to get the value of an option inside my select in React.js but somehow e.value is always undefined.
This is the code:
<Col md={4} className="col-padding-left">
<Input onChange={this.filterProducts} type="select" name="select" id="exampleSelect">
<option name='default'>Default</option>
<option name='price' value='desc'>Price (High-Low)</option>
<option name='price' value='asc'>Price (Low-High)</option>
<option name='addedAt' value='desc'>Added At (First-Last)</option>
<option name='addedAt' value='asc' >Added At (Last-First)</option>
<option name='name' value='desc'>Name (A-Z)</option>
<option name='name' value='asc'>Name (Z-A)</option>
</Input>
</Col>
With the following function filterProducts:
filterProducts(e){
console.log(e.value);
}
Try this
<Col md={4} className="col-padding-left">
<Input onChange={this.filterProducts.bind(this)} type="select" name="select" id="exampleSelect">
<option name='default'>Default</option>
<option name='price' value='desc'>Price (High-Low)</option>
<option name='price' value='asc'>Price (Low-High)</option>
<option name='addedAt' value='desc'>Added At (First-Last)</option>
<option name='addedAt' value='asc' >Added At (Last-First)</option>
<option name='name' value='desc'>Name (A-Z)</option>
<option name='name' value='asc'>Name (Z-A)</option>
</Input>
</Col>
filterProducts = (e) => {
console.log(e.target.value);
}
You need to use e.target.value
See this question: OnChange event using React JS for drop down
First, check if you have e. If so, try e.target.value.
The event object doesn't hold a value property.
In order to access the value attribute of element you need to use event.target.value when target is the element that triggered this event.
Running example:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
items: ['john', 'jane', 'greg']
};
}
onSelect = e => {
console.log(e.target.value);
}
render() {
const{items} = this.state;
return (
<div>
<select onChange={this.onSelect}>
{
items.map(item => {
return (<option value={item}>{item}</option>)
})
}
</select>
</div>
);
}
}
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>
According to your request, it's my solution:
<Col md={4} className="col-padding-left">
<Input onChange={this.filterProducts} type="select" name="select" id="exampleSelect">
<option name='default'>Default</option>
<option name='price' value='desc'>Price (High-Low)</option>
<option name='price' value='asc'>Price (Low-High)</option>
<option name='addedAt' value='desc'>Added At (First-Last)</option>
<option name='addedAt' value='asc' >Added At (Last-First)</option>
<option name='name' value='desc'>Name (A-Z)</option>
<option name='name' value='asc'>Name (Z-A)</option>
</Input>
</Col>
The function for could be:
filterProducts(e){
// e.target.id identified the unique element in DOM
// in example when 'exampleSelect' make a change (onChange) event
if(e.target.id === 'exampleSelect'){
console.log("Value for exampleSelect: " + e.target.value);
}
// if you have another html input select add here another 'if'
// with a diferent id. ex.
if(e.target.id === 'fruitSelect'){
console.log("Value for fruit: " + e.target.value);
}
...
}
¡Ey!, don't forget to bind the function, in the React constructor:
this.filterProducts = this.filterProducts.bind(this);
Related
I'm trying to get the value of a dropdown menu that looks like this:
<ul className="tabs" data-component={true}>
<li>
<section className="sort-list" data-component={true}>
<select value={0} className="sort" data-element={true}>
<option key="0" value="0">Any Topic</option>
<option key="1" value="1">Art</option>
<option key="2" value="2">Auto</option>
//...and so on
I've seen similar questions, but trying to alert(sort).value won't work (along with some other variants) so I think I need to string together my selectors?
I can use either the value or the text, as the goal is to keep the filter applied even when a user goes back to the previous page.
How do I get the key, value, or text of the options?
You need to add onchage event to your select.
change = (event) => {
this.setState({
topic: event.target.value
})
}
<select onChange={this.change} value={0} className="sort" data-element={true}
<option key="0" value="0">Any Topic</option>
<option key="1" value="1">Art</option>
<option key="2" value="3">Auto</option>
</select>
DEMO
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
constructor() {
super();
this.state = {
topic: ''
};
}
change = (event) => {
this.setState({
topic: event.target.value
})
}
render() {
return (
<div>
<p>
Selected topic: {this.state.topic}
</p>
<select onChange={this.change} className="sort" data-element={true}>
<option key="0" value="0">Any Topic</option>
<option key="1" value="1">Art</option>
<option key="2" value="2">Auto</option>
</select>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
</script>
The Reactjs way would be to have a select box component which has an onChange handler. Something like this:
class MySelect extends React.Component {
onChange = (val) => {
// save the val somewhere..
this.setState({currentVal: val})
}
render() {
return <select onChange={this.onChange}> { getOptions() } </select>
}
}
Add onChange property to element.
Here is a simple code snippet for a working example.
import React, { useState } from 'react';
import { oneOfType, string, number } from 'prop-types';
function MyDropdown({ selected: preSelected }) {
const [selected, setSelected] = useState(preSelected);
const onChange = evt => {
setSelected(evt.target.value);
}
return (
<div>
<select onChange={onChange} value={selected}>
<option value={1}>Opption 1</option>
<option value={2}>Opption 2</option>
<option value={3}>Opption 3</option>
</select>
{selected && <div>Selcted: {selected}</div>}
</div>
)
}
MyDropdown.propTypes = {
selected: oneOfType([string, number])
};
MyDropdown.defaultProps =
selected: 1
};
You can also check it live on CodeSandbox: https://codesandbox.io/s/react-codesandbox-2voc6
I want to retrieve the value from my selection so I can make post requests. I have no problem getting from text input, but for some reason I can't get it from the drop down menu select. I end up getting a
"TypeError: Cannot read property 'value' of undefined"
Here is the code I am using.
import React from "react";
import { Form, Input, Button, Select } from "antd";
const { Option } = Select;
class ItemForm extends React.Component {
handleFormSubmit = event => {
event.preventDefault();
const name = event.target.elements.name.value;
const description = event.target.elements.description.value;
const category = event.target.elements.category.value;
console.log(name, description, this.refs.category.value);
};
render() {
return (
<div>
<Form onSubmit={this.handleFormSubmit}>
<Form.Item label="Form Layout" />
<Form.Item label="Product Name">
<Input name="name" placeholder="Ex: Organic Apple..." />
</Form.Item>
<Form.Item label="Description">
<Input name="description" placeholder="Ex: Juicy organic apples!" />
</Form.Item>
<Form.Item label="Category">
<Select name="category" placeholder="Please select a category">
<Option value="Fruit">Fruit</Option>
<Option value="Vegetable">Vegetable</Option>
<Option value="Poultry">Poultry</Option>
</Select>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
</div>
);
}
}
export default ItemForm;
Use onChange which is fired when the value of the select changes. antd select documentation
<Form.Item label="Category">
<Select
onChange={(value) => {
alert(value)
}}
name="category"
placeholder="Please select a category">
<Option value="Fruit">Fruit</Option>
<Option value="Vegetable">Vegetable</Option>
<Option value="Poultry">Poultry</Option>
</Select>
</Form.Item>
working example
Something similar to the classic javascript approach, you intended to use, could be use getFieldValue.
But coupling to coherent createRef , Form and Form.Item as below.
When getting values, remember to reference the Form.Item name and not the Input one ;-)
I have created a sandbox demo hoping other people will enjoy or contribute.
import React from "react";
import { Form, Input, Button, Select } from "antd";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css"; //export default ItemForm;
const { Option } = Select;
class ItemForm extends React.Component {
formRef = React.createRef();
handleFormSubmit = event => {
event.preventDefault();
console.log("All field values", this.formRef.current.getFieldsValue());
const name = this.formRef.current.getFieldValue("productName"); //OLD event.target.elements.name.value;
const description = this.formRef.current.getFieldValue("description"); //OLD event.target.elements.description.value;
const category = this.formRef.current.getFieldValue("category"); //OLD event.target.elements.category.value;
console.log(name, description, category);
alert(`${name}, ${description}, ${category}`);
};
render() {
return (
<div>
<Form ref={this.formRef} onSubmit={this.handleFormSubmit}>
<Form.Item label="Form Layout (Form.Item-createRef-getFieldValue Example)" />
<Form.Item label="Product Name" name="productName">
<Input name="name" placeholder="Ex: Organic Apple..." />
</Form.Item>
<Form.Item label="Description" name="description">
<Input name="description" placeholder="Ex: Juicy organic apples!" />
</Form.Item>
<Form.Item label="Category" name="category">
<Select name="category" placeholder="Please select a category">
<Option value="Fruit">Fruit</Option>
<Option value="Vegetable">Vegetable</Option>
<Option value="Poultry">Poultry</Option>
</Select>
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
onClick={this.handleFormSubmit}
>
Submit
</Button>
</Form.Item>
</Form>
</div>
);
}
}
ReactDOM.render(<ItemForm />, document.getElementById("container"));
Managed it by using onChange as shown below this.
state = {
status: ""
};
<Form.Item label="Status">
<Select
name="status"
onChange={value => {
this.setState({ status: value });
}}
placeholder="Please choose the status"
>
<Option value="new">New</Option>
<Option value="open">Open</Option>
<Option value="rejected">Rejected</Option>
<Option value="deferred">Deferred</Option>
<Option value="reopened">Reopened</Option>
</Select>
</Form.Item>
unlike what you would expect, in Ant Design Select you can't get the value by calling:
onChange={(e)=>console.log(e.target.value)}
no. instead you get the value directly by just accessing the event itself, like this:
onChange={(e)=>console.log(e)}
You can fix this as follows. (Works fine for Antd)
<Select
onChange={(text, index) => {
console.log(index.children);
}}
>
A better and cleaner way to avoid this issue is to define all the form values and labels in an array and pass it into the . Declare or use an onChange event and store the value of the event in your state.
I have a problem with select in JavaScript. I'd like to change option of select. The option is changing, but text is default. Why is that? What can I change in my code? I need timeout, because script is loading slowly.
setTimeout(() => {
if(this.props.Locale === "en-EN") {
let country = document.getElementById("Country");
country.getElementsByTagName("option")[10].selected = "selected";
}
}, 3000);
You can control the selected option using the value property of the select component. You can bind it to an item in state and then set that to whatever you need. I've given an example below, which isn't particularly great code, but gives a demonstration of how this might work:
class App extends React.Component {
state = {
selectedOption: 2,
}
updateSelectedOption(newValue) {
this.setState({
selectedOption: newValue
});
}
render() {
return (
<div>
<select
onChange={({ target }) => { this.updateSelectedOption(target.value) }}
value={this.state.selectedOption}
>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<button onClick={() => this.updateSelectedOption(1)}>1</button>
<button onClick={() => this.updateSelectedOption(5)}>5</button>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
<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>
<div id="app"></div>
In the following code block, I want to perform sorting and filtering according to the panels I have defined on top. User can select sorting criteria and order to sort the data. User can select the criteria and related values to get the filtered results. Note: first I want to pull dynamic drop down according to the selected criteria while filtering.
class StudentRow extends React.Component {
render() {
const student = this.props.student;
return (
<tr>
<td>{student.ID}</td>
<td>{student.Name}</td>
<td>{student.Age}</td>
<td>{student.Major}</td>
<td>{student.College}</td>
</tr>
);
}
}
class DropDown extends React.Component {
constructor(props) {
super(props);
this.state = {criteria: 'id', order: 'ascending'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
handleSubmit(event) {
alert('Your cretiria is: ' + this.state.criteria + ' Order is: ' + this.state.order);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Cretiria to sort:
<select value={this.state.criteria} name="criteria" onChange={this.handleChange}>
<option value="id">ID </option>
<option value="name">Name </option>
<option value="age">Age </option>
<option value="major">Major </option>
<option value="college">College</option>
</select>
</label>
<label>
Order of sorting:
<select value={this.state.order} name="order" onChange={this.handleChange}>
<option value="ascending">Ascending</option>
<option value="descending">Descending</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
class Filter extends React.Component {
constructor(props) {
super(props);
this.state = {criteria: 'id', value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
handleSubmit(event) {
alert('Your cretiria is: ' + this.state.criteria + ' Value is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Cretiria to filter:
<select value={this.state.criteria} name="criteria" onChange={this.handleChange}>
<option value="id">ID </option>
<option value="name">Name </option>
<option value="age">Age </option>
<option value="major">Major </option>
<option value="college">College</option>
</select>
</label>
<label>
Value to filer:
<select value={this.state.value} name="value" onChange={this.handleChange}>
// Need dynamic values here
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
const filtereData = data.filter(item => item.value === valuetofilter);
<label>
Value to filer:
<select value={this.state.value} name="value" onChange={this.handleChange}>
{filteredData.map(item => <option value={item.value}> {item.value} </option>}
</select>
</label>
replace item.value with the value from the data you want to use to compare. Then valuetofilter is the value from the state that the user queried. If it matches a new option element will be returned into the select.
I have a form in which I am using html select element.
<select className="form-control" id="ntype" required >
<option value = "">None</option>
<option value = "1">1</option>
<option value = "2">2</option>
<option value = "3">3</option>
</select>
I know with html input type element we can attach ref like below code
ref = {(input) => { this.nHeading = input; }}
and
<input
type = "text"
className = "form-control"
id = "tInput"
placeholder = "Sample input"
ref = {(input) => { this.sInput = input; }}
required
/>
How can I attach ref to <Select> element and get selected option value from the attached ref when form is submitted?
Do I need to attach ref to each options or select element itself?
You can store the value in a state on change and later use that i.e make it a controlled component
class App extends React.Component {
constructor() {
super();
this.state = {selectValue: ''}
}
callThis = (e) => {
this.setState({selectValue: e.target.value}, ()=> {console.log(this.state.selectValue)});
}
render() {
return (
<select onChange={this.callThis}className="form-control" id="ntype" required >
<option value = "">None</option>
<option value = "1">1</option>
<option value = "2">2</option>
<option value = "3">3</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>
Or you can use refs to get the value like this
class App extends React.Component {
constructor() {
super();
this.state = {selectValue: ''}
}
callThis = (e) => {
console.log(this.selectVal.value)
}
render() {
return (
<div><select ref={(input) => this.selectVal = input} className="form-control" id="ntype" required >
<option value = "">None</option>
<option value = "1">1</option>
<option value = "2">2</option>
<option value = "3">3</option>
</select>
<input type="button" value="click" onClick={this.callThis}/></div>
)
}
}
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>
I would give each element a value and onChange handler for the select element like this
<select className="form-control"onChange={this.onChange.bind(this)}>
<option value="">None</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
And define an onChange handler that sets the state of the selection
onChange(e){
this.setState({value: e.target.value}, function(){
// do other stuff
});
}
If you are using React functional components, you can do the following.
import { useState, useRef } from 'react';
...
const selectRef = useRef(null)
<select className="form-control" id="ntype" required ref={selectRef}>
<option value = "">None</option>
<option value = "1">1</option>
<option value = "2">2</option>
<option value = "3">3</option>
</select>
then you can access the value in your submit logic by,
selectRef.current.value
You can just use an onChange function to set the value of the Ref. E.g.:
<select className="form-control" id="ntype" required onChange={e => {yourRef.current = e.target.value}} >
<option value = "">None</option>
<option value = "1">1</option>
<option value = "2">2</option>
<option value = "3">3</option>
</select>