如何使用按钮道具动态禁用antd modal的按钮
How to dynamically disable the button of antd modal using button props
我有一个 antd Modal,我正在尝试验证一个字段并为其提供验证。我如何 enable/disable 基于验证的确定按钮。如果验证成功,则应启用按钮,否则禁用。
<Form>
<Modal
title={modalHeader}
okText="ADD FIELD"
cancelText="CANCEL"
visible={visible}
onCancel={onCancelHandler}
onOk={() => onAddFieldHandler(fieldName)}
width={600}
okButtonProps={{disabled:true}}
>
<p>Please provide name</p>
<Form.Item
name="fieldName"
rules={[{ required: true, message: 'Please enter name' }]}
>
<FieldNameInput
placeholder="Field name..."
value={fieldName}
onChange={(event) => setFieldName(event.target.value)}
/>
</Form.Item>
</Modal>
</Form>
您可以使用来自 Antd Forms API togehter with geFieldsError
and the okButtonProps
from Antd Modal API 的 onFieldsChange
。
const [form] = Form.useForm();
const [buttonDisabled, setButtonDisabled] = useState(true);
return (
<Modal
...
okButtonProps={{ disabled: buttonDisabled }}
>
<Form
form={form}
...
onFieldsChange={() =>
setButtonDisabled(
form.getFieldsError().some((field) => field.errors.length > 0)
)
}
>
这是一个有效的 Stackblitz。
在 Modal 中包含表单,更新模式按钮状态的方法就是 运行 form instance's validateFields
,但有两点需要考虑:
此函数是一个 Promise,因此状态必须在 await
之后更新验证结果。
我在使用 onFieldsChange
时遇到了一些循环问题(也许验证会触发某种字段更新)。相反,onValuesChange
对我来说已经足够好了。
运行 setTimeout
回调的验证似乎是强制性的。在没有 setTimeout
returns 的情况下执行此操作会出现验证错误,即使所有字段都因 outOfDate: true
而有效。这似乎是因为 Antd Form 更新生命周期的工作方式,等到这个过程结束(我们可以用 setTimeout
轻松实现)解决这个问题。
验证成功 returns 表单值对象,验证失败 returns 包含错误列表的 errorInfo
对象,outOfDate
状态和当前表单值.你可以使用后者中的错误列表来获取Antd返回的验证消息,以显示更具描述性和具体的反馈。
最后,我的方法有这样的结构:
const MyModal = ({onFinish, ...otherProps}) => {
const [canSubmit, setCanSubmit] = useState(false);
const [form] = Form.useForm();
return (
<Modal
{...otherProps}
okButtonProps={{
disabled: !canSubmit
}}
>
<MyFormComponent
form={form}
onFinish={onFinish}
onValuesChange={() => {
setTimeout(() => {
form
.validateFields()
.then(() => {
/*
values:
{
username: 'username',
password: 'password',
}
*/
setCanSubmit(true);
})
.catch((err) => {
/*
errorInfo:
{
values: {
username: 'username',
password: 'password',
},
errorFields: [
{ name: ['password'], errors: ['Please input your Password!'] },
],
outOfDate: false,
}
*/
setCanSubmit(false);
});
});
}}
/>
</Modal>
);
};
在我的例子中,我有 Form inside modal 并且有 onFieldChange 道具,当你可以传递函数来执行一些操作时,由于 from 的变化,你可以这样:
const SomeModal = ({ visible }) => {
const [form] = Form.useForm();
const [buttonDisabled, setButtonDisabled] = useState(true);
const handleOk = () => form.submit();
const handleAfterClose = () => {
setButtonDisabled(true);
form.resetFields();
}
const handleCancel = () => ...some action to hide modal;
const handleFormFinish = (values) => {
... some logic here
}
return (
<Modal
title={"Some title..."}
visible={visibile}
onOk={handleOk}
onCancel={handleCancel}
afterClose={handleAfterClose}
okButtonProps={{ disabled: buttonDisabled }}
>
<Form
form={form}
layout="vertical"
name="acceptform"
onFinish={handleFormFinish}
initialValues={{
...initial values here
}}
onFieldsChange={() => {
const actualFieldValues = form.getFieldsValue();
const anyError = form.getFieldsError().some((field) => field.errors.length > 0);
.. some logic if error etc..
if (anyError) {
setButtonDisabled(true);
}
else {
setButtonDisabled(false);
}
}}
>
当然还需要在字段上设置一些验证器
<Form.Item
label={"someLabel"}
id="field"
name="field"
hasFeedback
rules={[
{
type: "string",
validator: async (rule, value) => inputFieldValidate(value, "custom message")
},
]}
>
和验证器看起来很像:
const inputFieldValidate = async (value, message) => {
if (someCondition)) {
return Promise.reject(message);
}
return Promise.resolve();
};
这里有一些很高兴知道验证器是异步的,并且让它在没有任何警告的情况下工作只是处理承诺
我有一个 antd Modal,我正在尝试验证一个字段并为其提供验证。我如何 enable/disable 基于验证的确定按钮。如果验证成功,则应启用按钮,否则禁用。
<Form>
<Modal
title={modalHeader}
okText="ADD FIELD"
cancelText="CANCEL"
visible={visible}
onCancel={onCancelHandler}
onOk={() => onAddFieldHandler(fieldName)}
width={600}
okButtonProps={{disabled:true}}
>
<p>Please provide name</p>
<Form.Item
name="fieldName"
rules={[{ required: true, message: 'Please enter name' }]}
>
<FieldNameInput
placeholder="Field name..."
value={fieldName}
onChange={(event) => setFieldName(event.target.value)}
/>
</Form.Item>
</Modal>
</Form>
您可以使用来自 Antd Forms API togehter with geFieldsError
and the okButtonProps
from Antd Modal API 的 onFieldsChange
。
const [form] = Form.useForm();
const [buttonDisabled, setButtonDisabled] = useState(true);
return (
<Modal
...
okButtonProps={{ disabled: buttonDisabled }}
>
<Form
form={form}
...
onFieldsChange={() =>
setButtonDisabled(
form.getFieldsError().some((field) => field.errors.length > 0)
)
}
>
这是一个有效的 Stackblitz。
在 Modal 中包含表单,更新模式按钮状态的方法就是 运行 form instance's validateFields
,但有两点需要考虑:
此函数是一个 Promise,因此状态必须在
await
之后更新验证结果。我在使用
onFieldsChange
时遇到了一些循环问题(也许验证会触发某种字段更新)。相反,onValuesChange
对我来说已经足够好了。运行
setTimeout
回调的验证似乎是强制性的。在没有setTimeout
returns 的情况下执行此操作会出现验证错误,即使所有字段都因outOfDate: true
而有效。这似乎是因为 Antd Form 更新生命周期的工作方式,等到这个过程结束(我们可以用setTimeout
轻松实现)解决这个问题。
验证成功 returns 表单值对象,验证失败 returns 包含错误列表的 errorInfo
对象,outOfDate
状态和当前表单值.你可以使用后者中的错误列表来获取Antd返回的验证消息,以显示更具描述性和具体的反馈。
最后,我的方法有这样的结构:
const MyModal = ({onFinish, ...otherProps}) => {
const [canSubmit, setCanSubmit] = useState(false);
const [form] = Form.useForm();
return (
<Modal
{...otherProps}
okButtonProps={{
disabled: !canSubmit
}}
>
<MyFormComponent
form={form}
onFinish={onFinish}
onValuesChange={() => {
setTimeout(() => {
form
.validateFields()
.then(() => {
/*
values:
{
username: 'username',
password: 'password',
}
*/
setCanSubmit(true);
})
.catch((err) => {
/*
errorInfo:
{
values: {
username: 'username',
password: 'password',
},
errorFields: [
{ name: ['password'], errors: ['Please input your Password!'] },
],
outOfDate: false,
}
*/
setCanSubmit(false);
});
});
}}
/>
</Modal>
);
};
在我的例子中,我有 Form inside modal 并且有 onFieldChange 道具,当你可以传递函数来执行一些操作时,由于 from 的变化,你可以这样:
const SomeModal = ({ visible }) => {
const [form] = Form.useForm();
const [buttonDisabled, setButtonDisabled] = useState(true);
const handleOk = () => form.submit();
const handleAfterClose = () => {
setButtonDisabled(true);
form.resetFields();
}
const handleCancel = () => ...some action to hide modal;
const handleFormFinish = (values) => {
... some logic here
}
return (
<Modal
title={"Some title..."}
visible={visibile}
onOk={handleOk}
onCancel={handleCancel}
afterClose={handleAfterClose}
okButtonProps={{ disabled: buttonDisabled }}
>
<Form
form={form}
layout="vertical"
name="acceptform"
onFinish={handleFormFinish}
initialValues={{
...initial values here
}}
onFieldsChange={() => {
const actualFieldValues = form.getFieldsValue();
const anyError = form.getFieldsError().some((field) => field.errors.length > 0);
.. some logic if error etc..
if (anyError) {
setButtonDisabled(true);
}
else {
setButtonDisabled(false);
}
}}
>
当然还需要在字段上设置一些验证器
<Form.Item
label={"someLabel"}
id="field"
name="field"
hasFeedback
rules={[
{
type: "string",
validator: async (rule, value) => inputFieldValidate(value, "custom message")
},
]}
>
和验证器看起来很像:
const inputFieldValidate = async (value, message) => {
if (someCondition)) {
return Promise.reject(message);
}
return Promise.resolve();
};
这里有一些很高兴知道验证器是异步的,并且让它在没有任何警告的情况下工作只是处理承诺