antd 组件form验证的奇葩问题
问题?
当把Input组件设置为disabled的时候,验证提醒还会出现,经过查找api都无法完美解决,或者解决后会出现这样或那样的奇葩问题
解决
- 伪造一个模样一样的组件,但要将rules属性删掉。
- 给伪装组件加一个自定义的key
实例
import React from "react";
import ReactDOM from "react-dom";
import moment from "moment";
import { DatePicker, version } from "antd";
import "antd/dist/antd.css";
import {
Form,
Input,
Tooltip,
Icon,
Cascader,
Select,
Row,
Col,
Checkbox,
Button,
AutoComplete
} from "antd";
const FormItem = Form.Item;
const Option = Select.Option;
const AutoCompleteOption = AutoComplete.Option;
const residences = [
{
value: "zhejiang",
label: "Zhejiang",
children: [
{
value: "hangzhou",
label: "Hangzhou",
children: [
{
value: "xihu",
label: "West Lake"
}
]
}
]
},
{
value: "jiangsu",
label: "Jiangsu",
children: [
{
value: "nanjing",
label: "Nanjing",
children: [
{
value: "zhonghuamen",
label: "Zhong Hua Men"
}
]
}
]
}
];
class RegistrationForm extends React.Component {
state = {
confirmDirty: false,
isDisabled: true,
autoCompleteResult: []
};
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log("Received values of form: ", values);
}
});
};
handleClickBtn = () => {
this.props.form.resetFields(['email'])
this.setState({
isDisabled: !this.state.isDisabled
});
};
handleConfirmBlur = e => {
const value = e.target.value;
this.setState({ confirmDirty: this.state.confirmDirty || !!value });
};
compareToFirstPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && value !== form.getFieldValue("password")) {
callback("Two passwords that you enter is inconsistent!");
} else {
callback();
}
};
validateToNextPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && this.state.confirmDirty) {
form.validateFields(["confirm"], { force: true });
}
callback();
};
handleWebsiteChange = value => {
let autoCompleteResult;
if (!value) {
autoCompleteResult = [];
} else {
autoCompleteResult = [".com", ".org", ".net"].map(
domain => `${value}${domain}`
);
}
this.setState({ autoCompleteResult });
};
render() {
const { getFieldDecorator } = this.props.form;
const { autoCompleteResult } = this.state;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 }
}
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0
},
sm: {
span: 16,
offset: 8
}
}
};
const prefixSelector = getFieldDecorator("prefix", {
initialValue: "86"
})(
<Select style={{ width: 70 }}>
<Option value="86">+86</Option>
<Option value="87">+87</Option>
</Select>
);
const websiteOptions = autoCompleteResult.map(website => (
<AutoCompleteOption key={website}>{website}</AutoCompleteOption>
));
return (
<Form onSubmit={this.handleSubmit}>
<FormItem {...formItemLayout} label="E-mail" disabled>
<Button onClick={this.handleClickBtn}>点击123</Button>
</FormItem>
{this.state.isDisabled ? (
<FormItem {...formItemLayout} label="E-mail" key="self">
<Input disabled />
</FormItem>
) : (
<FormItem {...formItemLayout} label="E-mail">
{getFieldDecorator("email", {
disabled: true,
rules: [
{
type: "email",
message: "The input is not valid E-mail!",
disabled: true
},
{
required: true,
message: "Please input your E-mail!"
}
]
})(<Input />)}
</FormItem>
)}
<FormItem {...formItemLayout} label="Password">
{getFieldDecorator("password", {
rules: [
{
required: true,
message: "Please input your password!"
},
{
validator: this.validateToNextPassword
}
]
})(<Input type="password" />)}
</FormItem>
<FormItem {...formItemLayout} label="Confirm Password">
{getFieldDecorator("confirm", {
rules: [
{
required: true,
message: "Please confirm your password!"
},
{
validator: this.compareToFirstPassword
}
]
})(<Input type="password" onBlur={this.handleConfirmBlur} />)}
</FormItem>
<FormItem
{...formItemLayout}
label={
<span>
Nickname
<Tooltip title="What do you want others to call you?">
<Icon type="question-circle-o" />
</Tooltip>
</span>
}
>
{getFieldDecorator("nickname", {
rules: [
{
required: true,
message: "Please input your nickname!",
whitespace: true
}
]
})(<Input />)}
</FormItem>
<FormItem {...tailFormItemLayout}>
{getFieldDecorator("agreement", {
valuePropName: "checked"
})(
<Checkbox>
I have read the <a href="">agreement</a>
</Checkbox>
)}
</FormItem>
<FormItem {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">
Register
</Button>
</FormItem>
</Form>
);
}
}
const WrappedRegistrationForm = Form.create()(RegistrationForm);
ReactDOM.render(
<div style={{ margin: 24 }}>
<p style={{ marginBottom: 24 }}>
Current antd version: {version} <br />
You can change antd version on the left panel (Dependencies section).
</p>
<WrappedRegistrationForm />
</div>,
document.getElementById("root")
);
复制代码
关键代码
{this.state.isDisabled ? (
<FormItem {...formItemLayout} label="E-mail" key="self">
<Input disabled />
</FormItem>
) : (
<FormItem {...formItemLayout} label="E-mail">
{getFieldDecorator("email", {
disabled: true,
rules: [
{
type: "email",
message: "The input is not valid E-mail!",
disabled: true
},
{
required: true,
message: "Please input your E-mail!"
}
]
})(<Input />)}
</FormItem>
)}
复制代码