简体   繁体   English

在变更模糊时进行表单验证,并提交表单和字段

[英]form validation on change blur and submit of form and fields

 // App.js import React, { Component } from 'react'; import './App.css'; import fields from './fields' import CustomInputType from './custominputtype' class App extends Component { state = { formData: {}, fieldErrorStatus: {}, submitErrorStatus: false } handleChange = (e) => { // adding the new on change value to the corresponding field name const { name, value } = e.target; const tempObj = { ...this.state.formData }; tempObj[name] = value; this.setState({ formData: tempObj }); // adding the error status for the corresponding field name let tempErrorStatus = { ...this.state.fieldErrorStatus } tempErrorStatus[name] = false; this.setState({ fieldErrorStatus: tempErrorStatus }) }; handleSubmit = (e) => { let formValues = this.state.formData; if (Object.keys(formValues).length === 0) { this.setState({ submitErrorStatus: true }) } else { let tempErrorStatus = {}; this.setState({ submitErrorStatus: false }); Object.keys(formValues).forEach(key => { if (formValues[key]) { tempErrorStatus[key] = false; } }) this.setState(prevState => { return { fieldErrorStatus: { ...prevState.fieldErrorStatus, tempErrorStatus } } }) } e.preventDefault(); } render() { return ( <div className="form"> <form onSubmit={this.handleSubmit} onChange={(e) => this.handleChange(e)} > <div className="inputs-collection"> { fields[0].attributes.map((field, i) => { return ( <CustomInputType attributes={field} key={i} value={this.state.formData[i]} obj={this.state.formData} errorStatus={this.state.fieldErrorStatus} displayError={this.state.submitErrorStatus} /> ) }) } </div> <div className="button-container"> <button className="submit-button" type="submit">Submit Details</button> </div> </form> </div> ) } } export default App; // CustomInputType import React , {Component} from 'react' class CustomInputType extends Component { render(){ const { attributes: { id, name, dataType, } = {}, displayError, obj, errorStatus } = this.props; return ( <div className="input-container"> <label htmlFor={id}> {name} </label> <input type={dataType} name={name || ''} value={obj[name]} id={id} /> { displayError || Boolean(errorStatus[name]) ? <span>{`Error on ${name}`}</span> : null } </div> ) } } export default CustomInputType // fields let fields = [ { "id": "1", "name": "Form 1", "type": "Dynamic Form", "attributes": [ { "name": "First Name", "dataType": "String", "id": 101, }, { "name": "Surname", "dataType": "String", "id": 102, }, { "name": "Phone Number", "dataType": "Number", "id": 103, }, { "name": "Roll Number", "dataType": "Number", "id": 104, } ] } ]; export default fields; 

i have a parent component , where i am reading a json file locally and rendering the fields, basically i have a child component which is a custom input type component. 我有一个父组件,我在本地读取一个json文件并渲染字段,基本上我有一个子组件,它是一个自定义输入类型的组件。

in my child component there is an prop called error it is a boolean value. 在我的子组件中,有一个名为error的属性,它是一个布尔值。 So if it is true it will show a red box around the field. 因此,如果为真,它将在字段周围显示一个红色框。 The cases i need to show the red box are onChange , onBlur and submit. 我需要显示红色框的情况是onChange,onBlur和Submit。 for sumbit i am using submitErrorStatus variable in state, and for handleChange and onBlur using fieldErrorStatus. 对于sumbit,我正在使用状态中的submitErrorStatus变量,对于handleChange和onBlur使用fieldErrorStatus。 So when the user directly submit without any fields entering redbox should come, once he types each field or blur the redbox should go. 因此,当用户直接提交而没有任何字段输入redbox时,一旦他键入每个字段或模糊了redbox,就应该消失。

i have done the below but some where it is confusing. 我已经做了以下工作,但是有些令人困惑。

Parent Component 父组件

state = { 
      formData : {},
      fieldErrorStatus : {},
      submitErrorStatus : false
    }

 handleChange = (e) => {
        // adding the new on change value to the corresponding field name
        const { name, value} = e.target;
        const tempObj = {...this.state.formData};
        tempObj[name] = value;
        this.setState({ formData:tempObj });

        // adding the error status for the corresponding field name
        let tempErrorStatus = {...this.state.fieldErrorStatus}
        tempErrorStatus[name] = false;
        this.setState({fieldErrorStatus:tempErrorStatus})

    };


handleSubmit = (e) => {

        let formValues = this.state.formData;

        if(Object.keys(formValues).length === 0){
            this.setState({submitErrorStatus: true})
        }
        else{
            let tempErrorStatus = {};

            this.setState({submitErrorStatus: false});
            Object.keys(formValues).forEach(key => {
                if(formValues[key]){
                    tempErrorStatus[key] = false;
                }
            })
            this.setState(prevState => {
                return {
                    fieldErrorStatus: {...prevState.fieldErrorStatus, tempErrorStatus}
                }
            })
        }

        e.preventDefault();
    }

    render(){
      <div className = "form">
                        <form 
                            onSubmit = {this.handleSubmit} 
                            onChange = {(e) => this.handleChange(e)}
                            >
                            <div className = "inputs-collection">
                            {
                                fields.map((field, i) => {
                                    return (
                                        <InputTypes 
                                            attributes = {field} 
                                            key = {i}                                 
                                            value = {this.state.formData[i]}
                                            obj = {this.state.formData}
                                            errorStatus = {this.state.fieldErrorStatus}
                                            displayError = {this.state.submitErrorStatus}
                                        />
                                    )                                                            
                                })
                            }
                            </div>
                            <div className = "button-container">
                                <button  className = "submit-button" type = "submit">Submit Details</button>
                            </div>
                        </form> 
                    </div> 

}

Child Component 子组件

render(){
   const {
            attributes : {
                id,
                name,
                dataType,
                rules,            
            } = {}, 
            displayError,
            obj,
            errorStatus
        } = this.props;

 return(
 <div className="input-container">

                <Input 
                    type = {dataType} 
                    id = {id.toString()}
                    name = {name || ''}
                    value = {obj[name]}
                    error={displayError || errorStatus[name] ? false : true} />



            </div>
)
}

So I made you some basic components which you can use as a reference. 因此,我为您提供了一些基本组件,您可以将其用作参考。 I've implemented the onChange and onBlur method. 我已经实现了onChangeonBlur方法。 I also made an easily accessible error message but I didn't create the onSubmit functions as you just have to map the array while comparing for empty inputs. 我还做出了一条易于访问的错误消息,但是我没有创建onSubmit函数,因为您只需要在比较空输入时映射数组即可。

Here is my code: 这是我的代码:

Container: 容器:

 import React, { Component } from 'react'; import Field from './Field'; export default class Container extends Component { state = { // Create fields fields: [ { key: "0", errorMessage: 'Error message for field: 0', isValid: true }, { key: "1", errorMessage: 'Error message for field: 1', isValid: true }, { key: "2", errorMessage: 'Error message for field: 2', isValid: true }, { key: "3", errorMessage: 'Error message for field: 3', isValid: true }, { key: "4", errorMessage: 'Error message for field: 4', isValid: true } ] } render() { return this.state.fields.map((field, i) => { return <Field key={field.key} isValid={field.isValid} onChange={this.onInputChange} index={i} /> }); } onInputChange = (index, event) => { let newState = this.state; if(event.target.value === '') { // Set field invalid newState.fields[index].isValid = false; // In this case log but you could do other stuff with the message console.log(this.state.fields[index].errorMessage); } else { // Set field valid newState.fields[index].isValid = true; } this.setState(newState); } } 

Input: 输入:

 import React, { Component } from 'react'; export default class Field extends Component { render() { // Get props const {isValid, onChange, index} = this.props; return <input type="text" // Check the input onInput={event => onChange(index, event)} onBlur={event => onChange(index, event)} // If invalid make the background red style={{backgroundColor: isValid ? 'white' : 'red'}} /> } } 

I hope it helps =) 希望对您有帮助=)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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