Добавить новую переменную в состояние, которая отслеживает, являются ли обязательные поля действительными. Используйте эту переменную для отключения / включения кнопки отправки.
state = {
...
isValidForm: false
}
validateNumber = value => {
const regex = /^[0-9]\d*$/;
return regex.test(value);
};
validateEmail = email => {
/* eslint-disable-next-line */
const regexp = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return regexp.test(email);
};
handleChange = e => {
const { name, value } = e.target;
const { user } = this.state;
this.setState(
{
user: {
...user,
[name]: value
}
},
() => {
// update the value here
this.setState({
isValidForm:
this.validateEmail(this.state.user.email1) &&
this.validateEmail(this.state.user.email2) &&
this.validateNumber(this.state.user.age) &&
this.validateNumber(this.state.user.phone)
});
}
);
};
Затем отключите / включите кнопку отправки на основе введенных значений.
<button disabled={!this.state.isValidForm} type="submit">
Submit
</button>
Чтобы отобразить ошибки во время ввода текста, добавьте переменная в состоянии, в которой хранятся прикосновенные входы, вход onFocus добавляет сфокусированное имя входа в массив.
state = {
...
isTouched: []
}
<div>
<label htmlFor="email2">Email 2</label>
<input
type="email"
id="email2"
name="email2"
onFocus={() => this.isTouched("email2")}
value={user.email2}
onChange={this.handleChange}
/>
{submitted && !user.email2 && (
<div style={{ color: "red" }}>Email 2 is required</div>
)}
{!this.validateEmail(this.state.user.email2) &&
this.state.isTouched.includes("email2") && (
<div style={{ color: "red" }}>Email is invalid</div>
)}
</div>
.App {
font-family: sans-serif;
text-align: center;
}
div {
margin: 0 0 10px 0;
clear: both;
overflow: hidden;
}
div label {
float: left;
width: 100px;
text-align: left;
}
div input,
div select {
float: left;
width: 200px;
padding: 5px;
clear: both;
}
div div {
text-align: left;
}
button {
float: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
state = {
user: {
name: "",
email1: "",
email2: "",
age: "",
city: "",
phone: ""
},
invalidNumber: false,
invalidEmail: false,
submitted: false,
isValidForm: false,
isTouched: []
};
validateNumber = value => {
const regex = /^[0-9]\d*$/;
return regex.test(value);
};
validateEmail = email => {
/* eslint-disable-next-line */
const regexp = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return regexp.test(email);
};
handleChange = e => {
const { name, value } = e.target;
const { user } = this.state;
this.setState(
{
user: {
...user,
[name]: value
}
},
() => {
this.setState({
isValidForm:
this.validateEmail(this.state.user.email1) &&
this.validateEmail(this.state.user.email2) &&
this.validateNumber(this.state.user.age) &&
this.validateNumber(this.state.user.phone)
});
}
);
};
handleSubmit = e => {
e.preventDefault();
const { name, age, email1, email2, city, phone } = this.state.user;
this.setState({
submitted: true
});
if (
name !== "" &&
age !== "" &&
email1 !== "" &&
email2 !== "" &&
city !== "" &&
phone !== ""
) {
console.log("User created : ", this.state.user);
} else {
console.log("Error creating user");
}
};
isTouched = inputName => {
const inputs = [...this.state.isTouched];
if (!inputs.includes(inputName)) {
inputs.push(inputName);
this.setState({
isTouched: inputs
});
}
};
render() {
const { submitted, invalidEmail, user } = this.state;
return (
<div className="App">
<form onSubmit={this.handleSubmit}>
<div>
<label htmlFor="name">Name</label>
<input
type="text"
id="name"
onFocus={() => this.isTouched("name")}
name="name"
value={user.name}
onChange={this.handleChange}
/>
{!user.name && this.state.isTouched.includes("name") && (
<div style={{ color: "red" }}>Name is required</div>
)}
</div>
<div>
<label htmlFor="age">Age</label>
<input
type="text"
id="age"
name="age"
onFocus={() => this.isTouched("age")}
value={user.age}
onChange={this.handleChange}
/>
{submitted && !user.age && (
<div style={{ color: "red" }}>Age is required</div>
)}
{!this.validateNumber(user.age) &&
this.state.isTouched.includes("age") && (
<div style={{ color: "red" }}>Age must be numeric</div>
)}
</div>
<div>
<label htmlFor="email1">Email 1</label>
<input
type="email"
id="email1"
name="email1"
onFocus={() => this.isTouched("email1")}
value={user.email1}
onChange={this.handleChange}
/>
{submitted && !user.email1 && (
<div style={{ color: "red" }}>Email 1 is required</div>
)}
{!this.validateEmail(this.state.user.email1) &&
this.state.isTouched.includes("email1") && (
<div style={{ color: "red" }}>Email is invalid</div>
)}
</div>
<div>
<label htmlFor="email2">Email 2</label>
<input
type="email"
id="email2"
name="email2"
onFocus={() => this.isTouched("email2")}
value={user.email2}
onChange={this.handleChange}
/>
{submitted && !user.email2 && (
<div style={{ color: "red" }}>Email 2 is required</div>
)}
{!this.validateEmail(this.state.user.email2) &&
this.state.isTouched.includes("email2") && (
<div style={{ color: "red" }}>Email is invalid</div>
)}
</div>
<div>
<label htmlFor="phone">Phone</label>
<input
type="text"
id="phone"
name="phone"
value={user.phone}
onFocus={() => this.isTouched("phone")}
onChange={this.handleChange}
/>
{submitted && !user.phone && (
<div style={{ color: "red" }}>Phone is required</div>
)}
{!this.validateNumber(user.phone) &&
this.state.isTouched.includes("phone") && (
<div style={{ color: "red" }}>Phone must be numeric</div>
)}
</div>
<div>
<label htmlFor="city">City</label>
<select
id="city"
name="city"
value={user.city}
onChange={this.handleChange}
>
<option value="" disabled>
Select
</option>
<option value="Delhi">Delhi</option>
<option value="Mumbai">Mumbai</option>
<option value="Pune">Pune</option>
</select>
{submitted && !user.city && (
<div style={{ color: "red" }}>City is required</div>
)}
</div>
<button disabled={!this.state.isValidForm} type="submit">
Submit
</button>
</form>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
</script>