I am trying to catch 2 input field's value but none of the input fields is working.
when I comment second Input field than the first one works properly.
state = { zipcode: null, city: "" };
onFormSubmit = event => {
event.preventDefault();
//Callback
this.props.onEnter(this.state.zipcode);
};
handleChange = event => {
this.setState({ [event.target.name]: event.target.value });
};
render() {
return (
<div>
<form onSubmit={this.onFormSubmit}>
<input
type="number"
className={`form-control`}
placeholder="Enter ZIP code"
name="zipcode"
onChange={this.handleChange} />
<input
type="text"
className={`form-control`}
placeholder="Enter Zip-code"
name="city"
onChange={this.handleChange}/>
</form>
</div>
);
}
}
When I hit enter after entering a query in the first input field I get no output and no error.
I tried below code and it worked just fine. Maybe there is something wrong with your callback function. Because on form submission you are getting the correct values.
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = {
zipcode: null,
city: ""
}
}
onFormSubmit = event => {
event.preventDefault();
//Callback
console.log(this.state);
};
handleChange = event => {
this.setState({ [event.target.name]: event.target.value });
}
render() {
return (
<div>
<form onSubmit={this.onFormSubmit}>
<input
type="number"
className={`form-control`}
placeholder="Enter ZIP code"
name="zipcode"
onChange={this.handleChange} />
<input
type="text"
className={`form-control`}
placeholder="Enter Zip-code"
name="city"
onChange={this.handleChange}/>
<input type="submit" value="submit" />
</form>
</div>
);
}
}
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
Here is the jsfiddle link with your code. Check in the inspect element after clicking on the submit button.
It works.
https://jsfiddle.net/t4o0xawr/1/
Related
i want to validate my form by checking if all the fields are filled. I am quite new to react. Any suggestions? I have got the states ready, but i am pretty much stuck. Thank you in advance for your replies. I appreciate it
my code:
const [fields, setFields] = useState({
name: '',
email: '',
subject: '',
msg: '',
});
const handleSubmit = (event) => {
emailjs.sendForm().then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
alert('form submitted');
event.target.reset();
event.preventDefault();
};
<form onSubmit={handleSubmit}>
<div className={styles.firstInputs}>
<div>
<label>name</label>
<br />
<input
type='text'
refs='name'
name='name'
placeholder='your name'
></input>
</div>
<div>
<label>email</label>
<br />
<input type='email' name='email' placeholder='email'></input>
</div>
</div>
<label>subject</label>
<br />
<input
type='text'
name='subject'
placeholder='subject'
className={styles.subject}
></input>{' '}
<br />
<label>message</label> <br />
<textarea placeholder='your message' name='message'></textarea>
<br />
<button type='submit' className={styles.sendForm}>
SUBMIT
</button>
</form>;
You are not using your state correctly there.
Set the values of the fields to what is in the state, then change the state when the fields change.
Don't forget you can just add the required attribute to your HTML element to make sure it gets some kind of value.
Then you just validate the state before submission.
Don't just fall back on packages all the time as people suggest here. As you say, you are new to React so, learn to set things up manually (which is basically less work for small forms). Once you understand that, then consider if having another dependency is really saving you time.
See sample code below in action here: https://codesandbox.io/s/form-validation-pbbf1
import { useState } from "react";
import "./styles.css";
const defaultFields = { name: "", email: "", subject: "", message: "" };
export default function App() {
const [fields, setFields] = useState(defaultFields);
const handleSubmit = (event) => {
// Stop form from resetting
event.preventDefault();
// Check fields
if (fields.name.length < 2) {
return alert("Name should be greater than 1 character.");
}
// etc...
// Send off data
/*
emailjs.sendForm().then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
*/
// I would probably put these two
// lines inside the then block above.
setFields(defaultFields);
alert("form submitted");
};
const handleFieldChange = (e) => {
const { name, value } = e.target;
setFields((previousFields) => ({ ...previousFields, [name]: value }));
};
return (
<form onSubmit={handleSubmit}>
{/* NAME */}
<div>
<label>name</label>
<br />
<input
type="text"
name="name"
placeholder="your name"
value={fields.name}
required
onChange={handleFieldChange}
></input>
</div>
{/* EMAIL */}
<div>
<label>email</label>
<br />
<input
type="email"
name="email"
placeholder="email"
value={fields.email}
required
onChange={handleFieldChange}
></input>
</div>
{/* SUBJECT */}
<div>
<label>subject</label>
<br />
<input
type="text"
name="subject"
placeholder="subject"
value={fields.subject}
required
onChange={handleFieldChange}
></input>{" "}
<br />
</div>
{/* MESSAGE */}
<div>
<label>message</label> <br />
<textarea
placeholder="your message"
name="message"
value={fields.message}
required
onChange={handleFieldChange}
></textarea>
</div>
<button type="submit">SUBMIT</button>
</form>
);
}
New to react so I apologize if the solution obvious. Working on a registration form that should create a new account on submit using ajax. I know that I'm supposed to use onChange to gather the information is submitted. After seeing a number of examples I am still unable to get my code to work.
I know that the ajax call for POST works because I put in information myself on vscode to test if on submit it will create which it did. I am having issues with the transition from onChange to my submit form. Hope that was clear. Thank you
I've tried creating a onChange function for my registration template. I am unable to get the results that I've been hoping for
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
payload: {
firstName: "",
lastName: "",
email: "",
password: "",
passwordConfirm: ""
}
};
}
handleChange = event => {
let name = event.target.name;
let value = event.target.value;
this.setState({
[name]: value,
[name]: value,
[name]: value,
[name]: value,
[name]: value
});
};
onClickHandler = evt => {
evt.preventDefault();
let payload = this.state;
console.log(payload);
debugger;
registerService
.register(payload)
.then(this.onActionSuccess)
.catch(this.onActionError);
};
onActionSuccess = response => {
console.log(response);
};
onActionError = errResponse => {
console.log(errResponse);
};
<!-- -->
render() {
return (
<main role="main">
<div className="container">
<h1 id="title" align="center">
Register User
</h1>
</div>
<div className="container">
<div className="col-sm-4 col-sm offset-4">
<form className="form">
<div className="form-group">
<label htmlFor="this.state.firstName">First Name</label>
<input
placeholder="First Name"
type="text"
id="this.state.firstName"
className="form-control"
name="firstName"
value={this.state.firstName}
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<label htmlFor="this.state.lastName">Last Name</label>
<input
placeholder="last Name"
type="text"
id="this.state. lastName"
className="form-control"
value={this.state.lastName}
onChange={this.handleChange}
/>
<div className="form-group">
<label htmlFor="register-email">Email</label>
<input
placeholder="Enter Email"
type="text"
className="form-control"
id="register-email"
value={this.state.email}
onChange={this.handleChange}
/>
</div>
</div>
<div className="form-group">
<label htmlFor="register-password">Password</label>
<input
placeholder="Password"
type="password"
id="register-password"
`enter code here`className="form-control"
value={this.state.password}
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<label htmlFor="register-passwordConfirm">
Confirm Password
</label>
<input
placeholder="Confirm Password"
type="password"
id="register-passwordConfirm"
className="form-control"
value={this.state.passwordConfirm}
onChange={this.handleChange}
/>
</div>
<button onClick={this.onClickHandler} className="btn btn-
primary">
Submit Form
</button>
I am expecting to create a new profile when clicking submit via POST ajax call
Your handleChange function should be
handleChange = event => {
let { name, value } = event.target;
this.setState({
[name]: value,
});
};
You always call your handleChange once at a time. Every time you change something on the input, the function gets different name and different value, which is suffice to add/update the your state.
And I noticed that you also have payload object in state. Modify the state like
this.state = {
firstname: '',
....
}
If you really want to use like
this.state = {
payload: {
firstName: '',
....
}
};
Your onChange function should look like,
handleChange = event => {
let { name, value } = event.target;
this.setState({
payload: {
...this.state.payload, // don't forget to copy all the other values
[name]: value,
}
});
};
The constructor and function:
constructor(props) {
super(props);
this.state = {
tagline: 'We rank what people are talking about.',
year: new Date().getFullYear()
};
this.onFormSubmit = this.onFormSubmit.bind(this);
}
onFormSubmit(e) {
console.log('onFormSubmit', e)
console.log('this.state', this.state);
};
The form (classNames removed for clarity):
<form onSubmit={ this.onFormSubmit }>
<div className="fl w100">
<div>
<input type="text" id="email" value={ this.state.email }/>
<label htmlFor="email">Email</label>
</div>
</div>
<div className="fl w100">
<div>
<input type="password" id="password" value={ this.state.password }/>
<label htmlFor="password">Password</label>
</div>
</div>
<button type="submit">
Login
</button>
</form>
This is what logs out, note no email or password information:
Full Login component code
import React from 'react';
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
tagline: 'We rank what people are talking about.',
year: new Date().getFullYear()
};
this.onFormSubmit = this.onFormSubmit.bind(this);
}
onFormSubmit(e) {
console.log('onFormSubmit', e)
console.log('this.state', this.state);
};
render() {
return (<div className="app">
<div className="welcome">
<header>
<div className="wikitags-logo">
<img src="imgs/wikitags-logo.png"/>
</div>
<h2>Admin Portal</h2>
<p>{ this.state.tagline }</p>
</header>
<section className="login-form">
<form onSubmit={ this.onFormSubmit }>
<div className="fl w100">
<div className="mdl-textfield mdl-js-textfield">
<input className="mdl-textfield__input" type="text" id="email" value={ this.state.email }/>
<label className="mdl-textfield__label" htmlFor="email">Email</label>
</div>
</div>
<div className="fl w100">
<div className="mdl-textfield mdl-js-textfield">
<input className="mdl-textfield__input" type="password" id="password" value={ this.state.password }/>
<label className="mdl-textfield__label" htmlFor="password">Password</label>
</div>
</div>
<button type="submit" className="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
Login
</button>
</form>
</section>
<footer>
© { this.state.year } WikiTags
</footer>
</div>
</div>);
}
}
export default Login;
Suggestions:
1. You are using value property with input fields but you didn't defined the onChange method so your input fields will be read-only because state value will not get updated.
2. You need to define a onChange event will all the input fields or make them uncontrolled element by removing the value property.
3. In case of uncontrolled element define the ref to each field and to access the value use this.ref_name.value.
By Defining the onChange event:
Define the name property to each input element (name should be same as state variable name it will help to update the state and we can handle all the change in single onChange function) like this:
<input type="text" name='value' value={this.state.value} onChange={(e) => this.handleChange(e)} />
handleChange(e){
this.setState({[e.target.name]: e.target.value})
}
By Uncotrolled element:
<input type="text" ref={el => this.el = el} />
Now inside onSubmit function use this.el.value to access he values of this input field.
Check this answer for reference: https://stackoverflow.com/a/43695213/5185595
You are not getting email or password information because you're passing in the state console.log('this.state', this.state); and you haven't set a state for the email and password.
Now, you got two options:
Set the state and get the form info from there
Pass the input value to a function that handles the info
For option 1, you'll need to set a state for your email and password (although setting a state for a password is not recommended) and an onChange event handler on the input(s).
Set up your onChange event handlers.
<form onSubmit={ this.onFormSubmit }>
<input type="text" id="email" onChange={this.handleEmailChange} value={ this.state.email } />
<input type="password" id="password" onChange={this.handlePasswordChange} value={ this.state.password } />
<button type="submit">
Login
</button>
</form>
And the functions to set the email and password states.
handleEmailChange(event) {
this.setState({ email: event.target.value });
}
handlePasswordChange(event) {
this.setState({ password: event.target.value });
}
And don't forget to initialize the state for your email and password in the constructor and bind the functions.
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
}
And you're done! Then on the onFormSubmit function just access the email and password values from the state this.state.email and this.state.password and do whatever you like.
Now for option 2, you can just pass in the event.target.value of the inputs, those are the values for the email and the password, and pass those values to a form event handler onSubmit function, from there you can do whatever you want (set the state or update the email and password, change them, whatever).
<form onSubmit={ this.onFormSubmit }>
<input type="text" id="email" name="theEmail" />
<input type="password" id="password" name="thePassword" />
<button type="submit">
Login
</button>
</form>
And the onFormSubmit function.
onFormSubmit(event) {
const email = event.target.theEmail.value;
const password = event.target.thePassword.value;
// do stuff
console.log('Email:', email);
console.log('Password:', password);
};
The easier and recommended way to accomplish what you're trying to do is the option 2.
Remember, the less state your app handles the better.
So how I would approach this is to store the values in your state using what is called a controlled component. Making a controlled component is very simple, this is a basic implementation:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
The key here is the handleChange function, and the onChange attribute. Every time the input field changes, the handleChange function is going to be called and the state will be updated.
You can find more info form the documentation here: https://facebook.github.io/react/docs/forms.html
I have two fields in the form, but i am not able to post the data to the server. I know how to submit single filed but how do i submit multiple field in the form.
below is the code of 2 fields
class Createstudent extends React.Component {
constructor(props) {
super(props);
this.state = {name: '',
age:''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({name: event.target.value});
this.setState({age:event.target.value});
}
handleSubmit(event) {
alert(this.state.name);
axios.post('/create',{values:this.state.name,ages:this.state.age})
.then(function(response){
console.log(response);
})
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.name} onChange={this.handleChange} />
</label>
<label>
Age:
<input type="text" value={this.state.age} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Reason is you are updating both the fields with the same value, on change of any one, update the specific field, it will work, try this:
handleChange(event) {
if(event.target.name == 'name')
this.setState({name: event.target.value});
else
this.setState({age: event.target.value});
}
or
handleChange(event) {
this.setState({[event.target.name]: event.target.value});
}
Add name attr to input field to identify them uniquely, Use this render method:
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" name='name' value={this.state.name} onChange={this.handleChange} />
</label>
<label>
Age:
<input type="text" name='age' value={this.state.age} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
Check the jsfiddle: https://jsfiddle.net/dp0an79f/
I have changed the code like this.And its working.
import React from 'react';
import axios from 'axios';
class Createstudent extends React.Component {
constructor(props) {
super(props);
this.state = {name: '',
age:''
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
alert(this.state.name);
axios.post('/create',{values:this.state.name,ages:this.state.age})
.then(function(response){
console.log(response);
})
}
componentDidMount(){
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.name} onChange={e => this.setState({ name: e.target.value })} />
</label>
<label>
Age:
<input type="text" value={this.state.age} onChange={e => this.setState({ age: e.target.value })} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
I have the below input fields of which I need to get the entered inputs and pass it to the onClick event of the button shown below.
<input type="text" style={textFieldStyle} name="topicBox" placeholder="Enter topic here..."/>
<input type="text" style = {textFieldStyle} name="payloadBox" placeholder="Enter payload here..."/>
<button value="Send" style={ buttonStyle } onClick={this.publish.bind(this,<value of input field 1>,<value of input field2>)}>Publish</button><span/>
I have a method called publish which takes two string arguments. In place of those strings, I need to pass the values entered in the input fields. How can I achieve this without storing the values in states? I do not want to store the input field values in state variables. Any help would be much appreciated.
How can I achieve this without storing the values in states?
I think in this case better use states
class App extends React.Component {
constructor() {
super();
this.state = {
topicBox: null,
payloadBox: null
};
this.publish = this.publish.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange({ target }) {
this.setState({
[target.name]: target.value
});
}
publish() {
console.log( this.state.topicBox, this.state.payloadBox );
}
render() {
return <div>
<input
type="text"
name="topicBox"
placeholder="Enter topic here..."
value={ this.state.topicBox }
onChange={ this.handleChange }
/>
<input
type="text"
name="payloadBox"
placeholder="Enter payload here..."
value={ this.state.payloadBox }
onChange={ this.handleChange }
/>
<button value="Send" onClick={ this.publish }>Publish</button>
</div>
}
}
ReactDOM.render(<App />, document.getElementById('container'));
<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="container"></div>
You can add ref for each text field, and read the value from it like:
class App extends React.Component {
constructor() {
super();
this.publish = this.publish.bind(this);
}
publish(topicBox, payloadBox) {
alert(this.refs.topic.value);
alert(this.refs.payload.value);
}
render() {
return <div>
<input
ref="topic"
type="text"
name="topicBox"
placeholder="Enter topic here..."/>
<input
ref="payload"
type="text"
name="payloadBox"
placeholder="Enter payload here..."/>
<button
value="Send"
onClick={this.publish}>
Publish
</button>
</div>
}
}
ReactDOM.render(<App />, document.getElementById('container'));
Working fiddle https://jsfiddle.net/hjx3ug8a/15/
Thanks for Alexander T for his addition!