Two dropdowns in a React Form - reactjs

I want to get the users input of a form with two drop-downs, and store it inside a global variable using react. I looked at reacts docs on how to create forms, and manipulate their code a little bit to have two drop-downs, but can't get it to save the variable as a global variable and print that global variable onto the screen. Unfortunately, there was an error when I clicked the second submit button (The first button did nothing). Here was the error: TypeError: this is undefined handleSubmit src/App.js:55 52 | } 53 | handleSubmit(event) { 54 | event.preventDefault(); > 55 | two = this.state.value | ^ 56 | } 57 | 58 | render() { – . Here was my code inside App.js:
import React from "react";
import "./App.css";
var one = "";
var two = "";
class FlavorFormOne extends React.Component {
constructor(props) {
super(props);
this.state = { value: "coconut" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
one = this.state.value
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
class FlavorFormTwo extends React.Component {
constructor(props) {
super(props);
this.state = { value: "GrabeFruit" };
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
two = this.state.value
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="submit"/>
</form>
</div>
);
}
}
function App() {
return (
<>
<FlavorFormOne />
<FlavorFormTwo />
{one}
{two}
</>
);
}
export default App;

you didn't pass the event
try onSubmit={(e)=>this.handleSubmit(e)}
also onChange={(e)=>this.handleChange(e)}

There were a couple things that needed to be fixed in your code. The first was this.handleSubmit = this.handleSubmit.bind(this); needed to be added in FlavorFormTwo's constructor, as I mentioned in the comments. The second was your handling of global variables. React won't re-render a component when a global variable changes, but it will re-render when the state is changed with setState. This is the reason why react state doesn't update when using this.state =. Instead, I added onSubmit as a prop to both, and inside both handleSubmit functions I added this.props.onSubmit(this.state.value). I changed the App component to a class, and added functions for handleOneSubmit and handleTwoSubmit that set the state of app. Try it online: https://codesandbox.io/s/vibrant-smoke-tsgri?file=/src/App.js
import React from "react";
import "./App.css";
class FlavorFormOne extends React.Component {
constructor(props) {
super(props);
this.state = { value: "coconut" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
this.props.onSubmit(this.state.value);
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
class FlavorFormTwo extends React.Component {
constructor(props) {
super(props);
this.state = { value: "GrabeFruit" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
this.props.onSubmit(this.state.value);
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="submit" />
</form>
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = { one: "", two: "" };
this.handleOneSubmit = this.handleOneSubmit.bind(this);
this.handleTwoSubmit = this.handleTwoSubmit.bind(this);
}
handleOneSubmit(value) {
this.setState({ one: value });
}
handleTwoSubmit(value) {
this.setState({ two: value });
}
render() {
return (
<>
<FlavorFormOne onSubmit={this.handleOneSubmit} />
<FlavorFormTwo onSubmit={this.handleTwoSubmit} />
{this.state.one}
{this.state.two}
</>
);
}
}
export default App;

Related

How i can navigate in an another page with a react.component

I'm a beginner with react and I want use it for sand a form and change the page. This is my code:
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {type: true, number: true};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.type === 'type' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
async handleSubmit(event) {
event.preventDefault();
try{
await axios.post("http://localhost:5000/number",{
type: this.state.type,
number: this.state.number
});
}catch(error){
console.log(error)
}
}
render() {
return (
<div className="tabSearch">
<form onSubmit={this.handleSubmit}>
<select className="input" value={this.state.value} name="type" onChange={this.handleChange}>
<option className="first_select" value="">0</option>.
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select className="input" value={this.state.value} name="number" onChange={this.handleChange}>
<option className="first_select" value="">number</option>.
<option value="1">1</option>
<option value="2">2</option>
<option value="0">0</option>
</select>
<input className="button" type="submit" value="Submit" />
</form>
</div>
);
}
}
export default Home;
I tried to use "Navigate" but it gives me some problems because I use a react.component, so I wanted to know how to solve this problem pls T.T
You can use react router.
Official docs: https://reactrouter.com/en/main

TypeError: Cannot read property 'value' of undefined React, Ant select

I cannot get React Ant Form Select value as it is undefined. I have tried updating state and anything but nothing solves this issue. Error is located under handleChange method. Maybe i am handling wrong Ant design form.
What could be issue here?
My form code:
import React from "react";
import { Form, Input, Button, Select } from "antd";
import axios from "axios";
const FormItem = Form.Item;
const { Option } = Select;
class CustomForm extends React.Component {
constructor(props) {
super(props)
this.state = {sport: ''};
this.handleChange = this.handleChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleFormSubmit = (event, requestType, trainingID) => {
const sport = event.targets.elements.sport.value;
...
}
render() {
return (
<div>
<Select name="sport" value={this.state.sport} style={{ width: 120 }} onChange={this.handleChange}>
<Option value="jooks" >Jooks</Option>
<Option value="jõud" >Jõud</Option>
<Option value="crossfit" >Crossfit</Option>
<Option value="kardio" >Kardio</Option>
</Select>
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit" shape="round" >
{this.props.btnText}
</Button>
</FormItem>
</Form>
</div>
);
}
}
The onChange event for the antd select component does not provide an event object, it provides the actual value that has been selected.
Instead, change your handleChange method to
handleChange(name, value) {
this.setState({
[name]: value
});
}
and then change your select onChange function to
onChange={value => this.handleChange("sport", value)}
So it would like like this
<Select
name="sport"
value={this.state.sport}
style={{ width: 120 }}
onChange={value => this.handleChange("sport", value)}
>
<Option value="jooks">Jooks</Option>
<Option value="jõud">Jõud</Option>
<Option value="crossfit">Crossfit</Option>
<Option value="kardio">Kardio</Option>
</Select>
The easiest way to actually debug this situation would be to console log the event value passed in from the onChange event. This would have shown that it is in fact the value that was selected, and not an event object.
EDIT:
Im not sure if it was by accident, but <Form> and <FormItem> tags were missing. I have added the full class below
import React from "react";
import { Form, Input, Button, Select } from "antd";
import axios from "axios";
const FormItem = Form.Item;
const { Option } = Select;
export default class CustomForm extends React.Component {
constructor(props) {
super(props);
this.state = { sport: "" };
this.handleChange = this.handleChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleChange(name, value) {
this.setState({
[name]: value
});
}
handleFormSubmit = value => {
console.log(this.state);
};
render() {
return (
<div>
<Form onFinish={this.handleFormSubmit}>
<FormItem>
<Select
name="sport"
value={this.state.sport}
style={{ width: 120 }}
onChange={value => this.handleChange("sport", value)}
>
<Option value="jooks">Jooks</Option>
<Option value="jõud">Jõud</Option>
<Option value="crossfit">Crossfit</Option>
<Option value="kardio">Kardio</Option>
</Select>
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit" shape="round">
{this.props.btnText}
</Button>
</FormItem>
</Form>
</div>
);
}
}

Passing submitted form data to another component

I have the following code, it basically accepts some basic input and when submit button is clicked user is notified with an alert, state is constantly being updated via onChange event. What i wonder is can i somehow pass the retrieved data to another component inside the event handler for submit button (which i have called handleFormSubmit)? I have recently seen react has something called 'context' ...maybe that would be best here? Advice please? :)
class Form extends Component {
constructor(props) {
super(props)
this.state = {
username: '',
comments: '',
topic: 'react'
}
this.handleUsernameChange = this.handleUsernameChange.bind(this);
this.handleCommentsChange = this.handleCommentsChange.bind(this);
this.handleTopicChange = this.handleTopicChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleUsernameChange(event){
this.setState({
username: event.target.value
},
() =>{
console.log(this.state.username)
})
}
handleCommentsChange(event){
this.setState({
comments: event.target.value
},
() =>{
console.log(this.state.comments)
})
}
handleTopicChange(event){
this.setState({
topic: event.target.value
},
() =>{
console.log(this.state.topic)
})
}
handleFormSubmit(event){
event.preventDefault();
alert(`${this.state.username} ${this.state.comments} ${this.state.topic}`);
}
render() {
return (
<form onSubmit={this.handleFormSubmit}>
<div>
<label>Username</label>
<input type='text' value={this.state.username} onChange={this.handleUsernameChange}/>
</div>
<div>
<textarea value={this.state.comments} onChange={this.handleCommentsChange}></textarea>
</div>
<div>
<select value={this.state.topic} onChange={this.handleTopicChange}>
<option value="react">React</option>
<option value="angular">Angular</option>
<option value="vue">Vue</option>
</select>
</div>
<button>Submit</button>
</form>
)
}
}
Hi all i made some changes and got something working, added extra state attribute called dataSubmitted set it to false then only after i submit the data is child (which i called AcceptFormData) allowed to render and i pass the state attributes as props. I do not know if this is a good approach or not but it works and no console errors.
class Form extends Component {
constructor(props) {
super(props)
this.state = {
username: '',
comments: '',
topic: 'react',
dataSubmitted: false
}
this.handleUsernameChange = this.handleUsernameChange.bind(this);
this.handleCommentsChange = this.handleCommentsChange.bind(this);
this.handleTopicChange = this.handleTopicChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleUsernameChange(event){
this.setState({
username: event.target.value
},
() =>{
console.log(this.state.username)
})
}
handleCommentsChange(event){
this.setState({
comments: event.target.value
},
() =>{
console.log(this.state.comments)
})
}
handleTopicChange(event){
this.setState({
topic: event.target.value
},
() =>{
console.log(this.state.topic)
})
}
handleFormSubmit(event){
event.preventDefault();
this.setState({
dataSubmitted: true
})
}
render() {
if(this.state.dataSubmitted === false){
return (
<form onSubmit={this.handleFormSubmit}>
<div>
<label>Username</label>
<input type='text' value={this.state.username} onChange={this.handleUsernameChange}/>
</div>
<div>
<textarea value={this.state.comments} onChange={this.handleCommentsChange}></textarea>
</div>
<div>
<select value={this.state.topic} onChange={this.handleTopicChange}>
<option value="react">React</option>
<option value="angular">Angular</option>
<option value="vue">Vue</option>
</select>
</div>
<button>Submit</button>
</form>
)
}else{
return (
<AcceptFormData username={this.state.username} comments={this.state.comments} topic={this.state.topic}/>
)
}
}
}
export default Form

How to get values from select react js

class button extends Component {
constructor(props) {
super(props);
this.state = {
role: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ [event.target.id]: event.target.value });
}
handleSubmit(event) {
console.log(this.state.role);
event.preventDefault();
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
<select value={this.state.role} onChange={this.handleChange}>
<option value="A" >A</option>
<option value="B" >B</option>
</select>
</label>
<input type="submit" value="a" />
</form>
</div>
);
}
}
If I were to go to the scroll bar and click either A or B it should console log A or B but it gives empty. Why? At the moment I can't scroll the bar either. I tried using name, id as this.state.role those didn't work either
You are using the event.target.id in your handleChange method, but your select has no id property (btw, property "name" will be better suited than "id" for this). Also, you should define an initial role value (as your select is set to A, by default);
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
role: 'A'
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({
[event.target.id]: event.target.value
});
}
handleSubmit(event) {
console.log(this.state.role);
event.preventDefault();
}
render() {
return (<div>
<form onSubmit={this.handleSubmit}>
<label>
<select id="role" value={this.state.role} onChange={this.handleChange}>
<option value="A">A</option>
<option value="B">B</option>
</select>
</label>
<input type="submit" value="a"/>
</form>
</div>);
}
}
ReactDOM.render(< Button / >, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="root"></div>
Try code below
class button extends Component {
constructor(props) {
super(props);
this.state = {
role: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
handleSubmit(event) {
console.log(this.state.role);
event.preventDefault();
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
<select name="role" value={this.state.role} onChange={this.handleChange}>
<option value="A" >A</option>
<option value="B" >B</option>
</select>
</label>
<input type="submit" value="a" />
</form>
</div>
);
}
}
Also, check the documentation on controlled components and how to handle forms in react https://reactjs.org/docs/forms.html
If i understood you correctly this is the solution to your problem:
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
role: 'A'
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
console.log('####onChange Value: ', event.target.value)
this.setState({ role: event.target.value });
}
handleSubmit(event) {
console.log('submited value: ',this.state.role);
event.preventDefault();
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
<select value={this.state.role} onChange={this.handleChange}>
<option value="A" >A</option>
<option value="B" >B</option>
</select>
</label>
<input type="submit" value={this.state.role} />
</form>
</div>
);
}
}

Prooblem on select in react

I want to create a select component of Blood group option. I write code and it does render on dom but it is not showing up in the browser.
This is FindDonor Component
import React, { Component } from "react";
class FindDonor extends Component {
state = {
value: "Find Donor By Blood Group"
};
handleChange = e => {
this.setState({ value: e.target.value });
};
render() {
return (
<div className="findDonor">
<h1>Hello</h1>
<div className="input-field">
<select value={this.state.value} onChange={this.handleChange}>
<option value="a+">A+</option>
<option value="o+">O+</option>
<option value="b+">B+</option>
<option value="ab+">AB+</option>
<option value="a-">A-</option>
<option value="o-">O-</option>
<option value="b-">B-</option>
<option value="ab-">AB-</option>
</select>
</div>
</div>
);
}
}
export default FindDonor;
<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>
Home Component code
Home.js
App Component code
App.js
You are probably missing a this.handleChange = this.handleChange.bind(this); in your constructor.
Check this example from the React docs (https://reactjs.org/docs/forms.html#the-select-tag):
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
I think you need to pass event on your onChange onChange={(e) => {this.handleChange(e)}. Also, in case of arrow functions, there is no need to bind functions.
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
}
handleChange = (event) => {
this.setState({value: event.target.value});
}
handleSubmit = (event) => {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={(e) => {this.handleChange(e)}}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}

Resources