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

时间:2019-01-22 08:03:37

标签: javascript reactjs

<div class="image-box" style="background-image:url(https://cdn.pixabay.com/photo/2018/06/30/09/31/background-image-3507320__340.jpg);"></div>
<div class="image-box" style="background-image:url(https://cdn.pixabay.com/photo/2018/06/30/09/31/background-image-3507320__340.jpg);"></div>
<div class="image-box" style="background-image:url(https://cdn.pixabay.com/photo/2018/06/30/09/31/background-image-3507320__340.jpg);"></div>
<div class="image-box" style="background-image:url(https://cdn.pixabay.com/photo/2018/06/30/09/31/background-image-3507320__340.jpg);"></div>
<div class="image-box" style="background-image:url(https://cdn.pixabay.com/photo/2018/06/30/09/31/background-image-3507320__340.jpg);"></div>
<div class="image-box" style="background-image:url(https://cdn.pixabay.com/photo/2018/06/30/09/31/background-image-3507320__340.jpg);"></div>

我有一个父组件,我在本地读取一个json文件并渲染字段,基本上我有一个子组件,它是一个自定义输入类型的组件。

在我的子组件中有一个称为error的属性,它是一个布尔值。因此,如果为真,它将在字段周围显示一个红色框。我需要显示红色框的情况是onChange,onBlur和Submit。 对于sumbit,我正在使用状态中的submitErrorStatus变量,对于handleChange和onBlur使用fieldErrorStatus。因此,当用户直接提交而没有任何字段输入redbox时,一旦他键入每个字段或模糊了redbox,就应该消失。

我做了以下事情,但有些地方令人困惑。

父组件

// 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;

子组件

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> 

}

1 个答案:

答案 0 :(得分:0)

因此,我为您提供了一些基本组件,您可以将其用作参考。我已经实现了onChangeonBlur方法。我还给出了一条易于访问的错误消息,但是我没有创建onSubmit函数,因为您只需要在比较空输入时映射数组即可。

这是我的代码:

容器:

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);
  }
}

输入:

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'}}
    />
  }
}

我希望它能帮助=)