React- onSubmit Function on forms is not working - reactjs

I'm not sure what i'm doing wrong here. I'm trying to console log when i click on a button on a form element using onSubmit function.
export class Search extends Component {
state = {
text: ''
};
onFormSubmit = e => {
console.log('Working');
e.preventDefault();
};
onChange = e => this.setState({ [e.target.name]: e.target.value });
render() {
return (
<div>
<form onSubmit={this.onFormSubmit} className='form' />
<input
type='text'
onChange={this.onChange}
value={this.state.text}
name='text'
placeholder='Search Users...'
/>
<input
type='submit'
value='Search'
className='btn btn-dark btn-block'
/>
</div>
);
}
}

You are not wrapping your button in form but closing the form itself,
<form onSubmit={this.onFormSubmit} className='form' />
You need to wrap input and button in form like,
<form onSubmit={this.onFormSubmit} className='form'>
<input
type='text'
onChange={this.onChange}
value={this.state.text}
name='text'
placeholder='Search Users...'
/>
<input
type='submit'
value='Search'
className='btn btn-dark btn-block'
/>
</form> //form closing tag

Related

The react app is returning/printing data for one text input but not for other. I have used the exact same blocks of code but nothing seems to work

import React from 'react'
export default class Login extends React.Component {
handleSubmit=(e)=>
{
e.preventDefault();
console.log('you clikked submit')
}
state={
fName:'',
lName:'',
gender:'',
}
These are the functions i am talking about
i am using setState to set the values input from the textfield.
fnameChange = (e) =>{
this.setState({fName:e.target.value})
}
lnameChange = (e) =>{
this.setState({lName:e.target.value})
}
render() {
return (
<div>
<h1>Login</h1>
<form
onSubmit={this.handleSubmit}
className='add-form' autoComplete="off">
<div className='form-control' >
These are the input fields from where i am calling the functions.
both are coded in exact same way.
I am using tags for printing the data to webpage.
I also tried console logging => onChange, the lastName textfield.
But some how onChange set for lastName textfield is getting fired when i enter value in firstName textfield.
<div>
<label >First Name</label>
<input type='text' name='firstName' onChange={this.fnameChange.bind(this)} required maxLength={10}/>
<h1>{this.state.fName}</h1>
</div>
<div>
<label >Last Name</label>
<input type='text' name='lastName' onChanege={this.lnameChange.bind(this)} required maxLength={10}/>
<h1>{this.state.lName}</h1>
</div>
<div>
<label >Email</label>
<input type='text' name='email' required />
<h1>{this.state.fName}</h1>
</div>
</div>
<div className='form-control form-control-check'>
<p><label>Male</label>
<input type='radio' name='gender' value='male' required/></p>
<p><label>Female</label>
<input type='radio' name='gender' value='female'/></p>
<p><label>Other</label>
<input type='radio' name='gender' value='other'/></p>
</div>
<div className='form-control'>
<input type='submit' value='Login'
className='btn btn-block'
/>
</div>
</form>
</div>
)
}
}
<input type='text' name='lastName' onChanege={this.lnameChange.bind(this)} required maxLength={10}/>
onChanege should be onChange
Multiple problems.
You are resetting your state on each onChange.
You had to consider the previous values and override the state like,
fnameChange = (e) => {
this.setState({...this.state, fName: e.target.value });
};
lnameChange = (e) => {
this.setState({...this.state, lName: e.target.value });
};
You don't need to bind as you are using arrow functions.
You can use the value of state to make your inputs a controlled component.
Example: https://stackblitz.com/edit/react-ts-dufrzd?file=Hello.tsx

form setstate on submit, not on onchange

I have a view showing name and email. I click edit, and an overlay shows up. I want to have the state updated on save changes, not on change, as to avoid having this.state.name and this.state.newName...
Not sure how to handle this...
This is the view - not editable
<div>
<span>{name}</span>
<span>{email}</span>
</div>
This is the form - editable
<form>
<div>
<span>
<input
type="text"
name="name"
title="Please fill out this field"
required
onBlur={event => { handleChange(event) }}
onChange={event => { handleChange(event) }}
/>
</span>
</div>
<div>
<span>
<input
type="text"
name="email"
title="Please fill out this field"
required
onBlur={event => { handleChange(event) }}
onChange={event => { handleChange(event) }}
/>
</span>
</div>
</form>

How Can I Get Form/Submit To Work with ReactStrap in a React functional component?

I like how Reactstrap handles Modal so I want to keep using it, but I can't figure out how to get the data out of a form and capture it in state.
const handleSubmit = (evt) => {
evt.preventDefault();
alert(`Submitting Name ${name}`);
};
With Reactstrap
<Form onSubmit={handleSubmit}>
<FormGroup>
<Label for="firstname">First Name</Label>{' '}
<Input name="speakername"></Input>
</FormGroup>
</Form>
When I use standard form and input elements, I'm able to capture what I need in handleSubmit, but I can't figure out how to do the same thing with the Form and Input tags of Reactstrap
Regular form and input elements
<form onSubmit={handleSubmit}>
<label>
First Name:
<input
type="text"
value={name}
onChange={e => setName(e.target.value)}
/>
</label>
<input type="submit" value="Submit" />
</form>
I was having exactly the same problem. Seemed to have fixed it as follows...
(I believe all you're missing are the value & onChange props for the Input component, and possibly the useState hooks for setName()... )
--- Set state ---
const currentDate = findDate();
function findDate() {
let d = new Date(),
month = "" + (d.getMonth() + 1),
day = "" + d.getDate(),
year = d.getFullYear();
if (month.length < 2) month = "0" + month;
if (day.length < 2) day = "0" + day;
return [year, month, day].join("-");
}
console.log(typeof currentDate);
const UpdateCount = () => {
const [date, setDate] = useState(currentDate);
const [hactCount, setHactCount] = useState("");
--- Handle Submit function ---
const handleSubmit = (e) => {
e.preventDefault();
alert(`${hactCount} hacts on ${date}`);
};
--- Return from functional component ---
return (
<div>
<Card>
<CardTitle className="border-bottom p-3 mb-0">
<i className="mdi mdi-priority-low mr-2"></i>Update your Hact Count
</CardTitle>
<CardBody>
<CardSubtitle className="py-2">
Insert your day's count and we'll do the magic
</CardSubtitle>
<Form onSubmit={handleSubmit}>
<FormGroup>
Date:
<Input
className="mt-2 mb-4"
type="date"
value={date}
onChange={(e) => {
setDate(e.target.value);
console.log(typeof e.target.value);
}}
/>
Count:
<Input
className="my-2 mb-4"
type="number"
placeholder="0"
value={hactCount}
onChange={(e) => {
setHactCount(e.target.value);
console.log(e.target.value);
}}
/>
<br />
<InputGroup className="text-center">
<Button className="text-center" color="primary" type="submit">
Update
</Button>
</InputGroup>
</FormGroup>
</Form>
</CardBody>
</Card>
</div>
);
Add a Button component with type=submit to your reactstrap form the same way you had an <input> with type=submit so that React know's to fire the onSubmit handler when the Button is clicked.
import { Form, FormGroup, Input, Label, Button } from "reactstrap";
<Form onSubmit={handleSubmit}>
<FormGroup>
<Label for="firstname">First Name</Label>{' '}
<Input name="speakername"></Input>
</FormGroup>
<Button type="submit">Submit</Button>
</Form>
you should be able using innerRef
onFormSubmit = (e) => {
e.preventDefault()
console.log(this.emailInputValue)
}
<Form onSubmit={this.onFormSubmit}>
<FormGroup>
<Label >Email:</Label>
<Input innerRef={(node) => this.emailInputValue = node} type="email" name="email" " placeholder="Email" />
<Button type="submit" color="primary" >Submit</Button>
</Form>
You can get the value by referring to the name key and ID of the input.
Exmaple
onFormSubmit = (e) => {
e.preventDefault()
console.log(e.target.company.value)
console.log(e.target.name.value)
}
<Modal isOpen={isModalVisible} toggle={handleModal}>
<ModalHeader toggle={handleModal}>add modal</ModalHeader>
<ModalBody>
<Form onSubmit={onFinish}>
<FormGroup>
<Label for="company">company</Label>
<Input type={"text"} name={"company"} id={"company"} placeholder={"company"} />
</FormGroup>
<FormGroup>
<Label for="name">name</Label>
<Input type={"text"} name={"name"} id={"name"} placeholder={"name"} />
</FormGroup>
<Button type="submit" color={"primary"}>
save
</Button>
</Form>
</ModalBody>
</Modal>

onsubmit gets triggered on every form field change

I am trying to implement simple form which triggers API call on form submit in React.
It blows my mind as when trying the below code:
import React, { Component } from 'react';
import axios from 'axios';
var panelStyle = {
'max-width': '80%',
margin: '0 auto'
}
class DBInject extends Component {
constructor() {
super();
this.formHandler = this.formHandler.bind(this);
this.state = {
formFields: {Id: '',
Name: '',
Payment: "01-10-2019",
Type: '',
Value: 110,
Cycle:'',
Frequency:''
}
}
}
render() {
return(
<div>
<div class="panel panel-primary" style={panelStyle}>
<div class="panel panel-heading">React Forum - Register</div>
<div class="panel panel-body">
<form onsubmit={this.formHandler(this.state.formFields)}>
<strong>Id:</strong> <br /> <input type="text" name="Id" placeholder="123" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Id} /> <br />
<strong>Name:</strong> <br /> <input type="text" name="Name" placeholder="me#example.com" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Name}/> <br />
<strong>Cycle:</strong> <br /> <input type="text" name="Cycle" placeholder="me#example.com" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Cycle} /> <br />
<strong>Frequency:</strong> <br /> <input type="text" name="Frequency" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Frequency}/> <br />
<strong>Type:</strong> <br /> <input type="text" name="Type" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Type} /> <br />
<strong>Payment:</strong> <br /> <input type="date" name="Payment" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Payment}/> <br />
<strong>Value:</strong> <br /> <input type="number" name="Value" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Value}/> <br /><br />
<button class="btn btn-primary">Send to database</button>
</form>
</div>
</div>
</div>
);
}
inputChangeHandler(e) {
console.log(e);
let formFields = {...this.state.formFields};
formFields[e.target.name] = e.target.value;
this.setState({
formFields
});
};
formHandler(formFields) {
console.log(formFields);
alert('This button does nothing.');
axios.post('http://127.0.0.1:1880/api','', {headers:formFields})
.then(function(response){
console.log(response);
//Perform action based on response
})
.catch(function(error){
console.log(error);
//Perform action based on error
});
}
}
export default DBInject
formHandler gets called every time InputchangeHandler gets called - which is not my intention.
Is there any other simpler way to do it in React?
Every time you call setState the component re-renders. Your form element is calling the function every time it re-renders. You need to make the following changes:
#Update onsubmit
<form onsubmit={this.formHandler.bind(this)}>
#Reference the formFields directly from the component's state
formHandler() {
const { formFields } = this.state;
You can read more on React forms here:
https://reactjs.org/docs/forms.html
Make sure to reference state from inside the handler function rather than passing it in - as this will make your function re-render every state update.
Form element:
//make sure the "S" in submit is capitalized
<form onSubmit={this.formHandler}>
...Your Form Contents
</form>
Handler function:
formHandler(e) {
e.preventDefault() // stop propagation at the start
// reference state from here with this.state like so:
const { formFields } = this.state;
...Your handler code
}

React TypeScript onSubmit e.preventDefault() not working

I'm building a simple user search app using React and TypeScript. I have a basic form with an input text box to search users and an input button that submits the search. But the e.preventDefault() method in my onSubmit method doesn't seem to be working. When I submit, the whole app refreshes. Actually, it may be that onSubmit isn't even being called at all.
private handleSubmit = (e: React.FormEvent<HTMLInputElement>) => {
e.preventDefault();
this.props.searchUsers(this.state.text);
this.setState({text: ''});
}
private handleChange = (e: React.FormEvent<HTMLInputElement>) => {
this.setState({text: e.currentTarget.value});
}
public render() {
return (
<div>
<form className="form">
<input
type="text"
name="text"
value={this.state.text}
placeholder="Search Users..."
onChange={this.handleChange}
/>
<input
type="submit"
value="search"
className="btn btn-dark btn-block"
onSubmit={this.handleSubmit}
/>
</form>
</div>
);
}
Any suggestions? Thanks!
You are adding onSubmitin the wrong place.
You should add in the form not in the button.
public render() {
return (
<div> // \/ added here
<form className="form" onSubmit={this.handleSubmit}>
<input
type="text"
name="text"
value={this.state.text}
placeholder="Search Users..."
onChange={this.handleChange}
/>
<input // removed from the button
type="submit"
value="search"
className="btn btn-dark btn-block"
/>
</form>
</div>
);
}
If you look at the example on the docs you will see that they add it in the form.
*Remember that to trigger the form's onSubmit, your input/button needs to have type="submit"
You can simply do this :-
private handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
this.props.searchUsers(this.state.text);
this.setState({text: ''});
}
private handleChange = (e: React.FormEvent<HTMLInputElement>) => {
this.setState({text: e.currentTarget.value});
}
public render() {
return (
<div>
<form className="form" onSubmit={(e) =>this.handleSubmit(e)}>
<input
type="text"
name="text"
value={this.state.text}
placeholder="Search Users..."
onChange={this.handleChange}
/>
<input
type="submit"
value="search"
className="btn btn-dark btn-block"
/>
</form>
</div>
);
}
Also in addition to moving the event from onClick to onSubmit, to get the event from the form, type React.FormEvent works.
private handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
this.props.searchUsers(this.state.text);
this.setState({text: ''});
}```
Instead of e:React.FormEvent<HTMLInputElement>
I fixed the similar issue by removing e.preventDefault from handleSubmit function and adding **onClick={e => {e.preventDefault(); this.handleSubmit()}}** on button.
and you have to put onSubmit on Form.
private handleSubmit = (e: React.FormEvent<HTMLInputElement>) => {
this.props.searchUsers(this.state.text);
this.setState({text: ''});
}
public render() {
return (
<div>
<form onSubmit={this.handleSubmit} className="form">
<input
type="text"
name="text"
value={this.state.text}
placeholder="Search Users..."
onChange={this.handleChange}
/>
<input
type="submit"
value="search"
className="btn btn-dark btn-block"
onClick={e => {e.preventDefault(); this.handleSubmit()}}
/>
</form>
</div>
);
}
This is tested and should work.

Resources