【问题标题】:How to disable submit button until form is filled and valid in javascript?如何禁用提交按钮,直到表单在javascript中填写并有效?
【发布时间】:2020-09-23 21:36:17
【问题描述】:

我创建了一个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

【问题讨论】:

  • 这不是你的错误,但我注意到你的 checkValidation 函数的定义类似于 checkValidation = e =&gt; {…},采用 e 参数。这个e 参数永远不会传递给它或使用,所以你应该写checkValidation = () =&gt; {…}checkValidation() {…}

标签: javascript reactjs


【解决方案1】:

我猜这是因为只有在离开输入时才会触发更改事件。尝试在渲染方法中将onChange 替换为onInput

【讨论】:

  • 在纯 JavaScript 中你是对的,但在 React 中,onChange 实际上与onInput 的工作方式相同——它侦听input 事件。所以onChange 不是问题。
  • 抱歉,我不知道,谢谢指出
【解决方案2】:

this.setState(…) 是异步的,所以在changeHandler 函数中this.checkValidation() 在状态更新后执行。这就是为什么它只有在表单有效后添加一个字符时才有效。

【讨论】:

  • 我该如何解决它,这样用户就不必执行该额外步骤并显示提交按钮?
  • 您可以在this.setState(…) 第二个参数函数中添加this.checkValidation()(在checkValidation 声明中有console.log)。或者,可能更好,因为documentation 建议使用componentDidUpdate()
  • 谢谢,我使用 componentDidUpdate 并且它可以工作。我还需要对 if 语句进行一些更新以使其正常工作。我在这里发布了我的解决方案。如果您找到更简单的方法,请告诉我。
【解决方案3】:

这里有人建议我使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 2012-12-05
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    • 2023-04-01
    相关资源
    最近更新 更多