Handling events of forms - reactjs

I am new to React and I am trying to make a form I wrote this simple form
class Profile extends React.Component {
constructor(props) {
super(props);
this.state = {name: '', age:''};
this.handleNameChange = this.handleNameChange.bind(this);
this.handleAgeChange = this.handleAgeChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleNameChange(event) {
this.setState({name: event.target.name});
}
handleAgeChange(event) {
this.setState({age: event.target.age});
}
handleSubmit(event) {
alert('Name was submitted: ' + this.state.value);
alert('Age was submitted: '+ this.state.age);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.name} onChange={this.handleNameChange} />
</label>
<label>
Age:
<input type="text" value={this.state.age} onChange={this.handleAgeChange}/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
export default Profile;
When I try it I can't write anything in the Name and the alert always shows me 'Name was submitted: undefined' 'Age was submitted: undefined'

You have a few typos in your code. For each of your handleChange functions, you should have event.target.value for the state value being set instead of the names of the fields.
Also in your alert function for the name, the value should be this.state.name instead of this.state.value.
Here is a complete working version:
class Profile extends React.Component {
constructor(props) {
super(props);
this.state = { name: "", age: "" };
this.handleNameChange = this.handleNameChange.bind(this);
this.handleAgeChange = this.handleAgeChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleNameChange(event) {
this.setState({ name: event.target.value });
}
handleAgeChange(event) {
this.setState({ age: event.target.value });
}
handleSubmit(event) {
alert("Name was submitted: " + this.state.name);
alert("Age was submitted: " + this.state.age);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
type="text"
value={this.state.name}
onChange={this.handleNameChange}
/>
</label>
<label>
Age:
<input
type="text"
value={this.state.age}
onChange={this.handleAgeChange}
/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<Profile / > ,
document.body
);
<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>

Related

this.state not populating fields in editProfile.component

Newbie here. Basic question I know. I have made a 'newProfile' component using pretty much the same mechanics as this and it's working! Now I need an editProfile component that updates the Profile form with props from the database using params.id. The URL shows the .id piece is working when I click 'edit' on a profile in a profileList component that is also working. This code is not getting errors, but it is not showing state for each of the fields.
What am I missing?
`
export default class EditProfile extends Component {
constructor(props) {
super(props);
this.onChangeUsername = this.onChangeUsername.bind(this);
this.onChangeFirst = this.onChangeFirst.bind(this);
this.onChangeLast = this.onChangeLast.bind(this);
this.onChangeEmail = this.onChangeEmail.bind(this);
this.onChangePassword = this.onChangePassword.bind(this);
this.onChangeDob = this.onChangeDob.bind(this);
this.onChangeLocation = this.onChangeLocation.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
username: '',
first: '',
last: '',
email: '',
password:'',
dob:'',
location:'',
}
}
componentDidMount() {
axios.get('http://localhost:5000/profiles/'+this.props.match.params.id)
.then(response => {
this.setState({
username: response.data.username,
first: response.data.first,
last: response.data.last,
email: response.data.email,
password: response.data.password,
dob: response.data.dob,
location: response.data.location
})
})
.catch(function (error) {
console.log(error);
})
}
componentDidMount() {
axios.get('http://localhost:5000/users/')
.then(response => {
if (response.data.length > 0) {
this.setState({
users: response.data.map(user => user.username),
})
}
})
.catch((error) => {
console.log(error);
})
}
onChangeProfilePic(e) {
this.setState({
profilePic: e.target.value
});
}
onChangeUsername(e) {
this.setState({
username: e.target.value
});
}
onChangeFirst(e) {
this.setState({
first: e.target.value
});
}
onChangeLast(e) {
this.setState({
last: e.target.value
});
}
onChangeEmail(e) {
this.setState({
email: e.target.value
});
}
onChangePassword(e) {
this.setState({
password: e.target.value
});
}
onChangeDob(e) {
this.setState({
dob: e.target.value
});
} onChangeLocation(e) {
this.setState({
location: e.target.value
});
}
onSubmit(e) {
e.preventDefault();
const profile = {
username: this.state.username,
first: this.state.first,
last: this.state.last,
email: this.state.email,
password: this.state.password,
dob: this.state.dob,
location: this.state.location,
}
console.log(profile);
axios.post('http://localhost:5000/profiles/update'+this.props.match.params.id, profile)
.then(res => console.log(res.data));
window.location = '/';
}
render() {
return (
<div>
<h3>Edit Profile
</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Username:
</label>
<input
type="text"
className="form-control"
value={this.state.username}
onChange={this.onChangeUsername}
/>
</div>
<div className="form-group">
<label>First Name:
</label>
<input
type="text"
className="form-control"
value={this.state.first}
onChange={this.onChangeFirst}
/>
</div>
<div className="form-group">
<label>Last Name:
</label>
<input
type="text"
className="form-control"
value={this.state.last}
onChange={this.onChangeLast}
/>
</div>
<div className="form-group">
<label>Email:
</label>
<input
type="text"
className="form-control"
value={this.state.email}
onChange={this.onChangeEmail}
/>
</div>
<div className="form-group">
<label>Password:
</label>
<input
type="text"
className="form-control"
value={this.state.password}
onChange={this.onChangePassword}
/>
</div>
<div className="form-group">
<input type="submit" value="Save" className="btn btn-primary" />
</div>
</form>
</div>
)}
}
`
Here is the error I'm getting in the console.
react-dom.development.js:86 Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
at input
at div
at form
at div
at CreateProfile (http://localhost:3000/static/js/bundle.js:194:5)
at RenderedRoute (http://localhost:3000/static/js/bundle.js:44214:5)
at Routes (http://localhost:3000/static/js/bundle.js:44678:5)
at div
at Router (http://localhost:3000/static/js/bundle.js:44609:15)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:42779:5)
at App

Extra undefined value in this.state

i am trying to post a form in reactjs, and i suspect it doesnt write to DB because i get strange undefined in my state, which looks like:
form looks like this
but in console i get:
this
my code on front is :
constructor(props) {
super(props);
this.state = { name: '', gender: '', email: '' };
}
handleChange= (event) => {
this.setState({
[event.target.name]: event.target.value,
[event.target.gender]: event.target.value,
[event.target.email]: event.target.value,
// [event.target.phone]: event.target.value,
});
}
handleSubmit = (event) => {
console.log(JSON.stringify(this.state));
alert('A form was submitted: ' + this.state);
fetch('http://localhost:3000/api/game/contacts', {
method: 'POST',
body: JSON.stringify(this.state)
}).then(function(response) {
return response.json();
});
event.preventDefault();
}
render() {
const { user } = this.props.auth;
console.log(this.state);
return(
<div>
<form onSubmit={this.handleSubmit}>
<label>
Name:</label>
<input type="text" value={this.state.value} name="name" onChange={this.handleChange} />
<label>
Gender:</label>
<input type="text" value={this.state.value} name="gender" onChange={this.handleChange} />
<label>
Email:</label>
<input type="text" value={this.state.value} name="email" onChange={this.handleChange} />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
Dashboard.propTypes = {
auth: PropTypes.object.isRequired
};
const mapStateToProps = ( state ) => ({
auth: state.auth
});
export default connect( mapStateToProps )( Dashboard );
must be super simple, but i googled for 2 hours, and could not see issue. Thanks for you time

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>
);
}
}

how do i add a validation message in my react component

I have this app that adds products and updates it.As it is, the product form can be submitted without a name, and it creates a new product with a blank line in the name column.how do i Add a validation message so that it requires a 'name' field before submitting the results, and shows a message if you try to submit the form without a name value.
import React from 'react';
const RESET_VALUES = {id: '', category: '', price: '', stocked: false, name: ''};
class ProductForm extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSave = this.handleSave.bind(this);
this.state = {
product: Object.assign({}, RESET_VALUES),
errors: {}
};
}
handleChange(e) {
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState((prevState) => {
prevState.product[name] = value;
return { product: prevState.product };
});
}
handleSave(e) {
this.props.onSave(this.state.product);
this.setState({
product: Object.assign({}, RESET_VALUES),
errors: {}
});
e.preventDefault();
}
render() {
return (
<form>
<h3>Enter a new product</h3>
<p>
<label>
Name
<br />
<input type="text" name="name" onChange={this.handleChange} value={this.state.product.name}/>
</label>
</p>
<p>
<label>
Category
<br />
<input type="text" name="category" onChange={this.handleChange} value={this.state.product.category} />
</label>
</p>
<p>
<label>
Price
<br />
<input type="text" name="price" onChange={this.handleChange} value={this.state.product.price} />
</label>
</p>
<p>
<label>
<input type="checkbox" name="stocked" onChange={this.handleChange} checked={this.state.product.stocked}/>
In stock?
</label>
</p>
<input type="submit" value="Save" onClick={this.handleSave}/>
</form>
);
}
}
export default ProductForm;
<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>
Set errors to null by default.
this.state = {
product: Object.assign({}, RESET_VALUES),
errors: null
};
Update your handleSave to something like this:
handleSave(e) {
e.preventDefault();
if (this.state.product.name.trim() === '') {
this.setState({errors: {name: 'Please fill name'}});
return;
}
this.props.onSave(this.state.product);
this.setState({
product: Object.assign({}, RESET_VALUES),
errors: null
});
}
And then in Form render method under Input field show error.
<label>
Name
<br />
<input type="text" name="name" onChange={this.handleChange} value={this.state.product.name}/>
{this.state.errors && <p>{this.state.errors.name}</p>}
</label>
Working example https://codesandbox.io/s/cocky-ride-2p8ym

Adding onBlur Functionality in Forms in Reactjs

I have a simple form build in react js. It has a text area with a submit button. Now I want to add an OnBlur functionality in this form. I tried this in the render method:
render() {
return (
<form onSubmit={this.handleSubmit}> onBlur={this.onBlur}
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
But this is not working. The original code( from FaceBook Tutorials) is as follows: Please note that I know that I need to bind the onBlur() through these lines: this.onBlur = this.onBlur.bind(this);. So that is not an area of Concern.
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>
);
}
}

Resources