[英]How to disable submit button until form is filled and valid in javascript?
我创建了一个Contact Us
表单并且提交按钮被禁用。 提交按钮仅在所有字段都已填写且条目有效时才启用。
目前,我的问题是在我输入所有具有有效条目的字段后,该按钮仍未显示。 但是,在使用有效输入输入所有字段并单击name
或email
输入框并在末尾键入一个字符后, submit
按钮将变为活动状态。 我认为我的checkValidation
函数存在一些异步问题,我不知道如何修复它。
import React, { Component } from 'react'
import axios from 'axios'
import '../css/ContactUs.css';
class ContactUs extends Component {
constructor(props) {
super(props)
this.state = {
name: '',
email: '',
birthDate: '',
emailConsent: false,
disableSubmitButton: true
}
}
changeHandler = e => {
const nameSelect = e.target.name
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
this.setState({
[nameSelect]: value
})
this.checkValidation()
}
checkValidation = e => {
const { name, email, birthDate, emailConsent, disableSubmitButton } = this.state
const validCharacters = /^[a-zA-Z ]+$/
const validEmail = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const today = new Date();
const birthdate = new Date(birthDate);
if (
!(name.length === 0) &&
name.match(validCharacters) &&
!(email.length === 0) &&
validEmail.test(email) &&
emailConsent === true &&
birthdate < today
) {
this.setState({
disableSubmitButton: false
}, () => console.log('passed'))}
}
clearHandler = e => {
this.setState({
name: '',
email: '',
birthDate: '',
emailConsent: false
})
console.log('clicked clear')
}
handleSubmit = e => {
const { name, email, birthDate, emailConsent } = this.state
e.preventDefault()
console.log(this.state);
axios.post('https://my-json-server.typicode.com/xxxxx/users', {name : name, email: email, birthDate: birthDate, emailConsent: emailConsent })
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
render() {
const { name, email, birthDate, emailConsent, disableSubmitButton } = this.state
return (
<div className="container">
<h1>Contact Us</h1>
<form onSubmit={this.handleSubmit}>
<label>
Name
<input
className="text"
name="name"
type="text"
value={name}
onChange={this.changeHandler}
/>
</label>
<label>
Email
<input
className="text"
name="email"
type="email"
value={email}
onChange={this.changeHandler}
/>
</label>
<label>
Birth Date
<input
className="text"
name="birthDate"
type="date"
value={birthDate}
onChange={this.changeHandler}
/>
</label>
<label className="checkbox">
<input
name="emailConsent"
type="checkbox"
checked={emailConsent}
onChange={this.changeHandler}
/>
I agree to be contact via email.
</label>
<div className="float-right">
<button className="clear" type="button" onClick={this.clearHandler}>Clear</button>
<input disabled={disableSubmitButton} className={disableSubmitButton ? 'submit-inactive' : 'submit'} type="submit" value="Submit"></input>
</div>
</form>
</div>
)
}
}
export default ContactUs
我猜这是因为只有在离开输入时才会触发更改事件。 尝试在渲染方法onInput
onChange
替换为onInput
。
this.setState(…)
是异步的,因此在changeHandler
函数中this.checkValidation()
在状态更新后执行。 这就是为什么它仅在您在表单有效后添加一个字符时才有效。
这里有人建议我使用componentDidUpdate
并且它有效。 如果你知道另一种方法,请告诉我。 谢谢!
import React, { Component } from 'react'
import axios from 'axios'
import '../css/ContactUs.css';
class ContactUs extends Component {
constructor(props) {
super(props)
this.state = {
name: '',
email: '',
birthDate: '',
emailConsent: false,
disableSubmitButton: true
}
}
changeHandler = e => {
const nameSelect = e.target.name
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
this.setState({
[nameSelect]: value
})
}
clearHandler = e => {
this.setState({
name: '',
email: '',
birthDate: '',
emailConsent: false
})
// console.log('clicked clear')
}
handleSubmit = e => {
const { name, email, birthDate, emailConsent } = this.state
e.preventDefault()
// console.log(this.state);
axios.post('https://my-json-server.typicode.com/xxxxx/users', JSON.stringify({name : name, email: email, birthDate: birthDate, emailConsent: emailConsent }))
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
alert('Submitted')
}
// componentDidUpdate will check all field inputs are complete and valid. If so, it toggles the state of disableSubmitButton and the submit button becomes available and vice versa
componentDidUpdate() {
const { name, email, birthDate, emailConsent, disableSubmitButton } = this.state
const validCharacters = /^[a-zA-Z ]+$/
const validEmail = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const today = new Date();
const birthdate = new Date(birthDate);
if (
disableSubmitButton === true &&
!(name.length === 0) &&
name.match(validCharacters) &&
!(email.length === 0) &&
validEmail.test(email) &&
emailConsent === true &&
birthdate < today &&
isNaN(birthdate) === false
) {
this.setState({
disableSubmitButton: false
})} else if (
disableSubmitButton === false &&
((name.length === 0) ||
!(name.match(validCharacters)) ||
(email.length === 0) ||
!(validEmail.test(email)) ||
emailConsent !== true ||
birthdate >= today ||
isNaN(birthdate) === true)
) {
this.setState({
disableSubmitButton: true
})}
}
render() {
const { name, email, birthDate, emailConsent, disableSubmitButton } = this.state
return (
<div className="container">
<h1>Contact Us</h1>
<form onSubmit={this.handleSubmit}>
<label>
Name
<input
className="text"
name="name"
type="text"
value={name}
onChange={this.changeHandler}
/>
</label>
<label>
Email
<input
className="text"
name="email"
type="email"
value={email}
onChange={this.changeHandler}
/>
</label>
<label>
Birth Date
<input
className="text"
name="birthDate"
type="date"
value={birthDate}
onChange={this.changeHandler}
/>
</label>
<label className="checkbox">
<input
name="emailConsent"
type="checkbox"
checked={emailConsent}
onChange={this.changeHandler}
/>
I agree to be contact via email.
</label>
<div className="float-right">
<button className="clear" type="button" onClick={this.clearHandler}>Clear</button>
<input disabled={disableSubmitButton} className={disableSubmitButton ? 'submit-inactive' : 'submit'} type="submit" value="Submit"></input>
</div>
</form>
</div>
)
}
}
export default ContactUs
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.