繁体   English   中英

如何禁用提交按钮,直到表单在 javascript 中填写并有效?

[英]How to disable submit button until form is filled and valid in javascript?

我创建了一个Contact Us表单并且提交按钮被禁用。 提交按钮仅在所有字段都已填写且条目有效时才启用。

目前,我的问题是在我输入所有具有有效条目的字段后,该按钮仍未显示。 但是,在使用有效输入输入所有字段并单击nameemail输入框并在末尾键入一个字符后, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM