React JS Form button calling - reactjs

I am try trying to submit the form once the button is clicked, but the function is not triggering in React.
The only enquiry is on the submit button onclick=submitform.
So I can get the value and update it to the json arry
import React, { Component } from "react";
class Createcomponent extends Component {
constructor() {
super()
this.state={
firstname:"",
lastname:"",
phonenumber:""
}
this.ontextchange=this.ontextchange.bind(this)
this.submitform=this.submitform.bind(this)
}
componentDidMount() {
console.log("Component Mounted");
}
ontextchange(event) {
if(event.target.id==='fname') {
this.setState({firstname: event.target.value})
}
}
submitform() {
alert("trigger");
//console.log(this.state)
}
render(){
return (
<div>
<label for="fname">First name:</label>
<input type="text" id="fname" onChange={this.ontextchange} value={this.state.firstname} name="fname"/><br/>
<label for="lname">Last name:</label>
<input type="text" id="lname" onChange={this.ontextchange} value={this.state.lastname} name="lname"/><br/>
<label for="lname">PhoneNumber:</label>
<input type="text" id="phone" onChange={this.ontextchange} value={this.state.phonenumber} name="lname"/><br/>
<input type="submit" value="Submit"/>
<button onClick={this.submitform}>Submit</button>
</div>
);
}
}
export default Createcomponent

You have two "Submit" buttons. Clicking the right "Submit" button triggers the alert correctly using your code as it is.
The left "Submit" button, which is setup as a form submit by setting type = submit, doesn't do anything because there actually is no <form> in use. Setting up a form as I've added it to your code below, the left "Submit" button works too. I've also created this CodeSandbox for demonstration.
import React, { Component } from "react";
class Createcomponent extends Component {
constructor() {
super();
this.state = {
firstname: "",
lastname: "",
phonenumber: ""
};
this.ontextchange = this.ontextchange.bind(this);
this.submitform = this.submitFormButton.bind(this);
}
componentDidMount() {
console.log("Component Mounted");
}
ontextchange(event) {
if (event.target.id === "fname") {
this.setState({ firstname: event.target.value });
}
}
submitFormButton() {
alert("trigger");
//console.log(this.state)
}
submitFormOnSubmit(e) {
e.preventDefault();
alert("trigger");
}
render() {
return (
<form onSubmit={this.submitFormOnSubmit}>
<label for="fname">First name:</label>
<input
type="text"
id="fname"
onChange={this.ontextchange}
value={this.state.firstname}
name="fname"
/>
<br />
<label for="lname">Last name:</label>
<input
type="text"
id="lname"
onChange={this.ontextchange}
value={this.state.lastname}
name="lname"
/>
<br />
<label for="lname">PhoneNumber:</label>
<input
type="text"
id="phone"
onChange={this.ontextchange}
value={this.state.phonenumber}
name="lname"
/>
<br />
<input type="submit" value="Submit" />
<button onClick={this.submitFormButton}>Submit</button>
</form>
);
}
}
export default Createcomponent;

Make sure to use htmlFor instead of for in React on your label element.

Related

How to display an unordered list into a JSX <ul> element in a React Form using class component

I'd like to write an unordered list compiled from a form's input values into a <ul> when I click on the Submit button. It's a controlled form in a class based component. Unfortunately I haven't found out how I can achieve it without hooks.
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
message: "",
demo: "",
};
this.changeHandler = this.changeHandler.bind(this);
this.submitFormHandler = this.submitFormHandler.bind(this);
}
changeHandler = (e) => {
this.setState = {
name: e.target.value,
email: e.target.value,
message: e.target.value,
demo: `
<li>${this.state.name}</li>
<li>${this.state.email}</li>
<li>${this.state.message}</li> `
};
this.setState(this.setState)
};
submitFormHandler = (e) => {
e.preventDefault();
// I guess the solution will be here somehow
};
render() {
return (
<form onSubmit={this.submitFormHandler} >
<label htmlFor="name">Name:</label> <br/>
<input id="name" type="text" value={this.state.name} onChange={this.changeHandler} />
<br/>
<label htmlFor="mail">E-mail:</label> <br/>
<input id="mail" type="email" value={this.state.email} onChange={this.changeHandler} />
<br/>
<label htmlFor="msg">Message:</label> <br/>
<textarea id="msg" type="email" value={this.state.message} onChange={this.changeHandler} />
<h4>Values of the inputs:</h4>
<ul id="demo">
{this.state.demo} {/* the list would be here! */}
</ul>
<button type="submit">Submit</button>
</form>
); }
};
To show something when it is submitted I would make a isSubmitted flag. Also you controlled inputs were not working. When inputs ids are corresponding with names in state we can easier handle them in onChange handler function. Also when it is submitted we can prevent user from updating data in changeHandler with early return. So I fixed it in code below:
// import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: '',
isSubmitted: false,
};
this.changeHandler = this.changeHandler.bind(this);
this.submitFormHandler = this.submitFormHandler.bind(this);
}
changeHandler = ({ target }) => {
if (this.state.isSubmitted) return;
this.setState({ [target.id]: target.value });
};
submitFormHandler = (e) => {
e.preventDefault();
this.setState({ isSubmitted: true });
};
render() {
return (
<div>
<form onSubmit={this.submitFormHandler}>
<label htmlFor="name">Name:</label> <br />
<input
id="name"
type="text"
value={this.state.name}
onChange={this.changeHandler}
/>
<br />
<label htmlFor="email">E-mail:</label> <br />
<input
id="email"
type="email"
value={this.state.email}
onChange={this.changeHandler}
/>
<br />
<label htmlFor="message">Message:</label> <br />
<textarea
id="message"
type="email"
value={this.state.message}
onChange={this.changeHandler}
/>
<br />
<button type="submit">Submit</button>
</form>
{this.state.isSubmitted && (
<React.Fragment>
<h4>Values of the inputs:</h4>
<ul>
<li>{this.state.name}</li>
<li>{this.state.email}</li>
<li>{this.state.message}</li>
</ul>
</React.Fragment>
)}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Semantic UI React (SUIR) Form with only a Form.Dropdown won't submit on Enter

I am trying to build a form with a dropdown and a submit button with SUIR. The form is submitted when I click the button but not when I press Enter.
<Form onSubmit={this.onSubmit}>
<Button type='submit'>
Submit
</Button>
<Form.Dropdown
fluid
selection
options={options}
onChange={onChange}
value={value}
/>
</Form>
What is the best way to get both to work ?
You can add an event Listener "keydown":
If your are developing Function component with hooks api you can do something like:
import { Button, Checkbox, Form } from "semantic-ui-react";
import { useEffect } from "react";
const MyForm = () => {
useEffect(() => {
const handleKeyDown = (event) => {
if (event.keyCode === 13) {
//13 is the Enter key code
onSubmit();
}
};
document.addEventListener("keydown", handleKeyDown);
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, []);
function onSubmit() {
console.log("submit function");
}
return (
<Form onSubmit={onSubmit}>
<Form.Field>
<label>First Name</label>
<input placeholder="First Name" />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder="Last Name" />
</Form.Field>
<Form.Field>
<Checkbox label="I agree to the Terms and Conditions" />
</Form.Field>
<Button type="submit">Submit</Button>
</Form>
);
};
export default MyForm;
Or if you are using class component :
import "./styles.css";
import "semantic-ui-css/semantic.min.css";
import { Button, Checkbox, Form } from "semantic-ui-react";
import React from "react";
export default class FormClass extends React.Component {
onSubmit() {
console.log("submit class");
}
handleKeyDown = (event) => {
if (event.keyCode === 13) {
//13 is the Enter key code
this.onSubmit();
}
};
componentDidMount() {
document.addEventListener("keydown", this.handleKeyDown);
}
componentWillUnmount() {
document.removeEventListener("keydown", this.handleKeyDown);
}
render() {
return (
<Form onSubmit={this.onSubmit}>
<Form.Field>
<label>First Name</label>
<input placeholder="First Name" />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder="Last Name" />
</Form.Field>
<Form.Field>
<Checkbox label="I agree to the Terms and Conditions" />
</Form.Field>
<Button type="submit">Submit</Button>
</Form>
);
}
}
An other solution is to use the onKeyPressprops this solution add another feature that to be execute on key the component need to be focus (the two other solution add an eventListner on all the document):
for example in a Class component (works too in a function component):
export default class FormClassKeyPress extends React.Component {
onSubmit() {
console.log("submit class on key press");
}
handleKeyDown = (event) => {
if (event.keyCode === 13) {
//13 is the Enter key code
this.onSubmit();
}
};
render() {
return (
<Form onSubmit={this.onSubmit} onKeyPress={this.handleKeyDown}>
<Form.Field>
<label>First Name</label>
<input placeholder="First Name" />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder="Last Name" />
</Form.Field>
<Form.Field>
<Checkbox label="I agree to the Terms and Conditions" />
</Form.Field>
<Button type="submit">Submit</Button>
</Form>
);
}
}
here you can see a codeSandbox example of both component type and onKeyPress

React: rendering multiple user inputs

I have a form containing several inputs and I am handling multiple user inputs but I want to display all the inputs when the submit button is clicked.
What do I need to add/change in my code to display the inputs when they are submitted?
class Planning extends React.Component {
constructor() {
super()
this.state = {
title: '',
goal: '',
tech: '',
features: '',
details: ''
}
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(`Plan: ` )
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div>
<label class="label-title">
Project Title:</label>
<input name="title" id="title" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-goal">
Motivational Goal: </label>
<input name="goal" id="goal" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-tech">
Technologies/tools:</label>
<input name="tech" id="tech" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-features">
Features:</label>
<input name="features" id="features" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-details">
Other details: </label>
<input name="details" id="details" type="text" onChange={this.handleChange}/>
</div>
<input class="submit" type="submit" value="Submit" />
</form>
)
}
}
The values are stored in the state so you could
handleSubmit(event) {
event.preventDefault();
alert(`Plan:\n${JSON.stringify(this.state,null,2)}`);
}
or the more explicit approach
handleSubmit(event) {
const {
title,
goal,
tech,
features,
details
} = this.state;
event.preventDefault();
alert(`Plan:
Title: ${title}
Goal: ${goal}
Tech: ${tech}
Features: ${features}
Details: ${details}
`);
}

React onSubmit placement

I have looked at multiple sources for using onSubmit functions in React and they always place onSubmit triggers as a Form attribute, like this
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { register } from "../../../actions/auth/auth.action";
import { Container } from "react-bootstrap";
import {
Button,
Form,
Label,
Input,
} from "reactstrap";
class Register extends Component {
state = {
fname: "",
lname: "",
email: "",
password: ""
};
static propTypes = {
register: PropTypes.func.isRequired
};
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
handleSubmit = e => {
e.preventDefault();
const { fname, lname, email, password } = this.state;
const newUser = {
name: {
first: fname,
last: lname
},
email: {
address: email
},
password
};
// Attempt to register user
this.props.register(newUser);
};
render() {
return(
<Form onSubmit={this.handleSubmit}>
<Label for="fname">First Name</Label>
<Input
type="text"
name="fname"
id="fname"
placeholder="Enter first name"
className="mb-3"
onChange={this.handleChange}
/>
<Label for="lname">Last Name</Label>
<Input
type="text"
name="lname"
id="lname"
placeholder="Enter last name"
className="mb-3"
onChange={this.handleChange}
/>
<Label for="email">Email</Label>
<Input
type="email"
name="email"
id="email"
placeholder="Enter email"
className="mb-3"
onChange={this.handleChange}
/>
<Label for="password">Password</Label>
<Input
type="password"
name="password"
id="password"
placeholder="Enter password"
className= "mb-3"
onChange={this.handleChange}
/>
<Button color="primary" style={{ marginTop: "2rem" }} block>
Register
</Button>
</Form>
);
};
};
const mapStateToProps = state => ({
error: state.error
});
export default connect(
mapStateToProps,
{ register }
)
(Register);
However, when I try this there is no way to call the function. (Ie. how does the button "know" when to call the onSubmit function when the call is a Form attrbute) I even tried added a type="submit" attribute to the button but that doesn't work either.
Just declare type="submit" in your button <button type="submit">send stuff</button> The type attribute is what onSubmit form is waiting for :) and remove e.preventDefault from your handleSubmit method and try again
The function will be called when submit event occurred.
Below code shows actions that trigger submit event.
class FormComponent extends React.Component {
handleSubmit = e => {
e.preventDefault();
console.log('submitted');
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="submit" /><br />
<button>Button with no attribute</button><br />
<button type="submit">submit typed Button</button><br />
<button type="button">button typed Button (no submit)</button><br />
<input type="text" value="Press enter to submit" />
</form>
);
}
}
ReactDOM.render(
<FormComponent />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

ReactJS Uncaught ReferenceError: onSubmit is not defined

Please help me to understand where I am doing what mistake? I created CustomerForm React Component, which having few form fields. These form fields will add records and in another component will show records into table format.
Every thing is working fine for CustomerForm React Component, but if I am adding onSubmit function than form fields are not loading and I am getting console error as:-
Uncaught ReferenceError: onSubmit is not defined
at new CustomerForm (index.js:32590)
<button type="submit" className="btn btn-primary" onClick={ e => this.onSubmit(e)} > Submit </button>
Also please suggest any better way to write ReactJS code using Props & State...
// Let's import react for creating component
import React from "react";
// Create CustomerForm component
class CustomerForm extends React.Component{
// create constructor function for CustomerForm component
constructor(props){
// call super, so constructor function can connect with CustomerForm component
super(props);
// Use state add object with their property and value
this.state = {
firstName : "",
lastName : "",
phoneNo : "",
issue : "",
}
// Create changeData function
// changeData = e => {
// this.setState({
// [e.target.name] : e.target.value
// });
// };
onSubmit = e => {
e.preventDefault();
console.log(this.state);
}
} // close constructor function
render(){
return(
<form>
<div className="form-group">
<label htmlFor="fname">First name</label>
<input
type="text"
className="form-control"
id="fname"
placeholder="First name"
value={this.state.firstName}
onChange={e => this.setState({ firstName: e.target.value })}
/>
{/* call setState for change firstName value
question - I created changeData function which target name attribute and change value for form fields, but it's not working
onChange={e => this.changeData(e)}
*/}
</div>
<div className="form-group">
<label htmlFor="lname">Last name</label>
<input
type="text"
className="form-control"
id="lname"
placeholder="Last name"
value={this.state.lastName}
onChange={e => this.setState({ lastName: e.target.value })}
/>
{/* call setState for change lastName value */}
</div>
<div className="form-group">
<label htmlFor="phone">Phone no.</label>
<input
type="text"
className="form-control"
id="phone"
placeholder="Phone no."
value={this.state.phoneNo}
onChange={e => this.setState({phoneNo: e.target.value})}
/>
{/* call setState for change phoneNo value */}
</div>
<div className="form-group">
<label htmlFor="issue">Issue</label>
<textarea
className="form-control"
id="issue"
rows="3"
value={this.state.issue}
onChange={e => this.setState({issue: e.target.value})}
>
{/* call setState for change issue value */}
</textarea>
</div>
<button
type="submit"
className="btn btn-primary"
onClick={ e => this.onSubmit(e)}
>
Submit
</button>
</form>
);
}
}
export default CustomerForm;
You're declaring a variable named onSubmit on the constructor and trying to access it with this.onSubmit, like a property.
You can do this in your constructor:
this.onSubmit = e => {
e.preventDefault();
console.log(this.state);
}
The suggestion
A better way to accomplish this is extracting your onSubmit method to a class method, with makes your code more readable and more consistent. Would be something like this:
// Let's import react for creating component
import React from "react";
// Create CustomerForm component
class CustomerForm extends React.Component{
// create constructor function for CustomerForm component
constructor(props){
// call super, so constructor function can connect with CustomerForm component
super(props);
// Use state add object with their property and value
this.state = {
firstName : "",
lastName : "",
phoneNo : "",
issue : "",
}
}
/////////
/// Your submit handler is now a method in the CustomerForm class,
/// so you can access with the keyword "this"
onSubmit(e) {
e.preventDefault();
console.log(this.state);
}
render(){
return(
<form onSubmit={e => this.onSubmit(e)}>
{/* Note that I've changed your handler to form,
is usually better than put on a button, since you're using a form already */}
<div className="form-group">
<label htmlFor="fname">First name</label>
<input
type="text"
className="form-control"
id="fname"
placeholder="First name"
value={this.state.firstName}
onChange={e => this.setState({ firstName: e.target.value })}
/>
{/* call setState for change firstName value
question - I created changeData function which target name attribute and change value for form fields, but it's not working
onChange={e => this.changeData(e)}
*/}
</div>
<div className="form-group">
<label htmlFor="lname">Last name</label>
<input
type="text"
className="form-control"
id="lname"
placeholder="Last name"
value={this.state.lastName}
onChange={e => this.setState({ lastName: e.target.value })}
/>
{/* call setState for change lastName value */}
</div>
<div className="form-group">
<label htmlFor="phone">Phone no.</label>
<input
type="text"
className="form-control"
id="phone"
placeholder="Phone no."
value={this.state.phoneNo}
onChange={e => this.setState({phoneNo: e.target.value})}
/>
{/* call setState for change phoneNo value */}
</div>
<div className="form-group">
<label htmlFor="issue">Issue</label>
<textarea
className="form-control"
id="issue"
rows="3"
value={this.state.issue}
onChange={e => this.setState({issue: e.target.value})}
>
{/* call setState for change issue value */}
</textarea>
</div>
<button
type="submit"
className="btn btn-primary"
>
Submit
</button>
</form>
);
}
}
export default CustomerForm;
Controlled Components
Just one more thing I think it may be helpful to you (I've noted your comment about changeData) so if you not resolve the way to do controlled inputs, this minimalist example may help you, with a onChangeHandler I usually use:
import React from 'react';
export default class MyControlledComponent extends React.Component {
constructor(props){
super(props);
// Initiating the first value for our controlled component
this.state = {
name: ""
}
}
submitHandler(e) {
e.preventDefault();
console.log('Hi, ' + this.state.name + '!');
}
onChangeHandler(e) {
const { name, value } = e.target
/*
Here we using the name property of your input to
increase reuse of this function
*/
this.setState({
[name]: value
});
}
render(){
return (
<div className="my-app">
<form onSubmit={e => this.submitHandler(e)}>
<input type="text"
name="name"
value={this.state.name}
onChange={e => this.onChangeHandler(e)} />
<button>Send!</button>
</form>
</div>
)
}
}
Hope it helps!
Your onSubmit function is not bind either bind it in constructor or use fat arrow properly like
{(return)=>{functionname()}}

Resources