Input filed is not clickable in react while using value attribute - reactjs

This is the very beginning of my react learning. I am facing some issue about input field. If I use value field in form then this input filed become unchangeable. Like I can't write anything on that filed. But while I remove value filed it work fine.
Here is my code
import React, { Component } from 'react';
export class Registration extends Component{
constructor(){
super();
this.state = {
name: '',
email: '',
password: '',
};
this.onChange = this.onChange.bind(this);
}
onChange(e){
this.setState = ({
name: e.target.value
});
}
render(){
return(
<div className="registration">
<form name="registration" id="registration" >
<div className="userName">
<label> Name : </label>
<input name="name" type="text" onChange={this.onChange} value={this.state.name}/>
<br/>
</div>
<label> Email : </label>
<input name="email" type="email" />
<br/>
<label> Password : </label>
<input name="password" type="password" />
<br/>
</form>
</div>
);
}
}
On the name input field I am using value attribute. This is making this issue.

The problem is that you accidentally wrote
this.setState = ({
name: e.target.value
});
Instead of
this.setState({
name: e.target.value
});
The = is incorrect, as you're trying to call a method and not declare a variable with a dictionary.

Your this.setState is set wrong.
class Registration extends React.Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: ""
};
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({
name: e.target.value
});
}
render() {
return (
<div className="registration">
<form name="registration" id="registration">
<div className="userName">
<label> Name : </label>
<input
name="name"
type="text"
onChange={e => this.onChange(e)}
value={this.state.name}
/>
<br />
</div>
<label> Email : </label>
<input name="email" type="email" />
<br />
<label> Password : </label>
<input name="password" type="password" />
<br />
</form>
</div>
);
}
}
ReactDOM.render(<Registration />, document.getElementById("app"));
<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="app" />

Related

how to set state from on change for multiple events react

in my react form I need to save each data item into the state.
I currently have on change methods for each of the inputs but its a lot of very similar code and looks messy. (But it does work...)
Here is the code
class EnterMortgage extends React.Component {
constructor(props) {
super(props);
this.state = {
repaymentType: '',
propVal: '',
bal: '',
fullTerm: '',
remainTerm: '',
intRate: '',
};
this.handleRepaymentChange = this.handleRepaymentChange.bind(this);
this.handlePropValChange = this.handlePropValChange.bind(this);
this.handleBalChange = this.handleBalChange.bind(this);
this.handleFullTermChange = this.handleFullTermChange.bind(this);
this.handleRemainTermChange = this.handleRemainTermChange.bind(this);
this.handleIntRateChange = this.handleIntRateChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleRepaymentChange(event) {
this.setState({ repaymentType: event.target.value });
}
handlePropValChange(event) {
this.setState({ propVal: event.target.value });
}
handleBalChange(event) {
this.setState({ bal: event.target.value });
}
handleFullTermChange(event) {
this.setState({ fullTerm: event.target.value });
}
handleRemainTermChange(event) {
this.setState({ remainTerm: event.target.value });=
}
handleIntRateChange(event) {
this.setState({ intRate: event.target.value });
}
handleSubmit(event) {
this.props.history.push('/EnterSavings', this.state);
}
// renders to display on page
render() {
return (
<div>
<div >
<p> Enter your mortgage details </p>
</div>
<div>
<form onSubmit={this.handleSubmit}>
<label>
Property Value {'\u00A3'}
<input type="Number" name="propVal" onChange={this.handlePropValChange} />
</label>
<label>
Current Balance
<input type="Number" name="bal" onChange={this.handleBalChange}/>
</label>
<label>
Full Mortgage Term (months)
<input type="Number" name="fullTerm" onChange={this.handleFullTermChange} />
</label>
<label>
Remaining Mortgage Term (months)
<input type="Number" name="remainTerm" onChange={this.handleRemainTermChange} />
</label>
<label>
InterestRate
<input type="Number" name="intRate" onChange={this.handleIntRateChange} />
</label>
<label>
Repayment Method
<select onChange={this.handleRepaymentChange}>
<option value="repayment">Repayment</option>
<option value="interest">Interest Only</option>
<option value="pap">Part and Part</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
</div>
</div>
);
}
}
export default EnterMortgage;
Is there a way to refactor this rather than having multiple functions? I have tried to combined into one method but I couldn't manage to get each item updated.

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>

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 JS input field not behaving as expected

I am creating a contact form using React JS and this is my code:
import React, { Component } from 'react';
export default class Create extends Component {
constructor(props) {
super(props);
this.onChangeFirstname = this.onChangeFirstname.bind(this);
this.onChangeLastname = this.onChangeLastname.bind(this);
this.onChangeMessage = this.onChangeMessage.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
person_firstname: '',
person_lastname: '',
message:''
}
}
onChangeFirstname(e) {
this.setState({
person_firstname: e.target.value
});
}
onChangeLastname(e) {
this.setState({
person_lastname: e.target.value
})
}
onChangeMessage(e) {
this.setState({
message: e.target.value
})
}
onSubmit(e) {
e.preventDefault();
console.log(`The values are ${this.state.person_firstname}, ${this.state.person_lastname}, and ${this.state.message}`)
this.setState({
person_firstname: '',
person_lastname: '',
message: ''
})
}
render() {
return (
<div style={{marginTop: 10}}>
<h3>Contact Form</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>First Name: </label>
<input type="text" className="form-control"
onChange={this.onChangeFirstName}/>
</div>
<div className="form-group">
<label>Last Name: </label>
<input type="text" className="form-control"
onChange={this.onChangeLastname}/>
</div>
<div className="form-group">
<label>Message: </label>
<textarea className="form-control"
onChange={this.onChangeMessage}>
</textarea>
</div>
<div className="form-group">
<input type="submit" value="Submit" className="btn btn-primary"/>
</div>
</form>
</div>
)
}
}
Everything seems fine, but the code gives a wrong result.
When I enter the following,
I get the following result
No matter what I enter in the first name field, it is ignored and I get a blank in the result.
I tried moving the Lastname input field above the Firstname input field and I still get the first input (Lastname) as blank in the console.
i refactor your code and everything looks fine ...
import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
export default class App extends Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
firstname: "",
lastname: "",
message: ""
};
}
handleChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
onSubmit(e) {
e.preventDefault();
console.log(this.state);
this.setState({
firstname: "",
lastname: "",
message: ""
});
}
render() {
return (
<div style={{ marginTop: 10 }}>
<h3>Contact Form</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>First Name: </label>
<input
type="text"
name="firstname"
className="form-control"
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<label>Last Name: </label>
<input
type="text"
name="lastname"
className="form-control"
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<label>Message: </label>
<textarea
name="message"
className="form-control"
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<input type="submit" value="Submit" className="btn btn-primary" />
</div>
</form>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
you have a typo, onChangeFirstname should have a capital N onChangeFirstName

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

Resources