[英]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. 我已经实现了
onChange
和onBlur
方法。 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.