reactjs React和表格禁用提交按钮

v64noz0r  于 2023-02-18  发布在  React
关注(0)|答案(7)|浏览(186)

我如何禁用表单提交按钮使用antd
表单验证工作,但我需要可视化禁用表单提交按钮时,验证失败

这是一个堆栈 lightning 战url https://stackblitz.com/edit/react-ts-z5d6tr?file=Hello.tsx

js81xvg6

js81xvg61#

我找到了一种优雅的方式来表演

<Form.Item shouldUpdate className="submit">
  {() => (
    <Button
      type="primary"
      htmlType="submit"
      disabled={
        !form.isFieldsTouched(true) ||
        form.getFieldsError().filter(({ errors }) => errors.length)
          .length > 0
      }
    >
      Log in
    </Button>
  )}
</Form.Item>
gwbalxhn

gwbalxhn2#

我将把我的解决方案粘贴在这里,以防有人觉得有用。该解决方案使用挂钩X1 M0 N1 X和回调X1 M1 N1 X。
验证并没有包含在这个摘录中,但是当表单改变(任何字段)时,它会将提交按钮(在这个例子中是在Modal中)设置为禁用/启用。

const LoginForm = () => {
  const [form] = useForm();
  const [disabledSave, setDisabledSave] = useState(true);
  
  const handleFormChange = () => {
    const hasErrors = form.getFieldsError().some(({ errors }) => errors.length);
    setDisabledSave(hasErrors);
  }
  
  return (
    <Modal okButtonProps={{ disabled: disabledSave }} onOk={form.submit}>
      <Form onFieldsChange={handleFormChange} form={form}>
        <Item name="username" label="username">
          <Input />
        </Item>
        <Item name="password" label="password">
          <Input />
        </Item>
      </Form>
    </Modal>
  )
};
lsmepo6l

lsmepo6l3#

我发现了一个很好的解决方案,它不涉及任何额外的状态。如果你把提交按钮 Package 成这样的Form.Item,它应该禁用它,直到所有必填字段都完成。表单的其余部分将保持不变。

<Form.Item
 noStyle
 shouldUpdate
>
  {({ getFieldsValue }) => {
    const { username, password } = getFieldsValue();
    const formIsComplete = !!username && !!password;
    return (
      <Button
         type="primary"
         htmlType="submit"
         disabled={!formIsComplete}
       >
         Log In
       </Button>
    );
  }}
</Form.Item>
gcmastyq

gcmastyq4#

import { UnlockOutlined, UserOutlined } from "@ant-design/icons";
import { Button, Card, Form, Input, Layout, Space } from "antd";
import { ValidateErrorEntity } from "rc-field-form/es/interface";
import React, { useState } from "react";
import "antd/dist/antd.css";

interface LoginForm {
  username: string;
  password: string;
}

const Hello = () => {
  // Create State
  const [error, setError] = useState(false);

  const onFinish = (values: LoginForm) => {
  };

  

  const onFinishFailed = (errorInfo: ValidateErrorEntity) => {
    setError(errorInfo); // set the state if error
  };

  // When the user starts type set state to false
  const handleChange = e => e.target.value && setError(false);

  return (
    <Layout className="login">
      <Card className="card">
        <Form
          onFinish={onFinish}
          onFinishFailed={onFinishFailed}
          size="large"
          layout="vertical"
        >
          <Space direction="vertical" size="middle">
            <Form.Item
              name="username"
              rules={[
                { required: true, message: "Please input your username!" }
              ]}
            >
              {/*Listening to change event*/ }
              <Input onChange={handleChange} prefix={<UserOutlined />} placeholder="Username" />
            </Form.Item>

            <Form.Item
              name="password"
              rules={[
                { required: true, message: "Please input your password!" }
              ]}
            >
              {/*Listening to change event*/ }
              <Input.Password
                onChange={handleChange}
                prefix={<UnlockOutlined />}
                placeholder="Password"
              />
            </Form.Item>

            <Form.Item className="submit">
              {/*Disable button only if error is true*/ }
              <Button disabled={error && true} type="primary" htmlType="submit">
                Login
              </Button>
            </Form.Item>
          </Space>
        </Form>
      </Card>
    </Layout>
  );
};

export default Hello;
7kqas0il

7kqas0il5#

这个解决方案对我很有效!

const [formError, setFormError] = useState(false);
...
...
const onValuesChange = async (values: any) => {
  try {
    await form.validateFields();
    setFormError(false);
  } catch (err) {
    setFormError(true);
  }
}
...
...
<Form form={form} onValuesChange={onValuesChange} />
...
...
<Form.Item label="First Name" name='firstName' required={true} rules={[{ required: true, min: 3, max: 50,
  message: 'First name is required, min 3 and max 50 characters!' }]}>
  <Input />
</Form.Item>
...
...
<Button disabled={formError}>Save</Button>
</Form>
bogh5gae

bogh5gae6#

我有一个很好的解决方案,没有任何额外的重新呈现(重新评估)成本!!我用Form.Item控制按钮组件,因为它将值属性传递给按钮,并且当按钮属性更改时,React会重新评估它,所以如果我们在按钮内部使用此值属性来禁用和启用,问题将得到解决!!例如:

<Form
    name="form"
    form={form}
    initialValues={{
      button: 1,
    }}
    onFieldsChange={() => {
      // button field value = true if there isn't an error
      form.setFieldValue(
        "button",
       //Attention: put all fields except the button field
        !form.isFieldsTouched(["input"], true) ||
          form.getFieldsError().filter(({ errors }) => {
            return errors.length;
          }).length > 0
      );
    }}
  >
    <Form.Item
      name="input"
      rules={[
        {
          required: true,
        },
      ]}
    >
      <Input />
    </Form.Item>
    <Form.Item name="button">
      <CustomButton>login</CustomButton>
    </Form.Item>
  </Form>
function CustomButton({children, ...rest}) {
  return (
    <Button
      {...rest}
      disabled={rest.value}
    >
    {children}
   </Button>
  );
dddzy1tm

dddzy1tm7#

我在这里做了一些编辑:https://stackblitz.com/edit/react-ts-spuhdd?file=Hello.tsx
总结一下我所做的:
1.我创建了钩子用户名,密码和禁用
1.每次用户更改用户名和密码时,如果这些字段为空,则disabled设置为false。
1.如果执行onFinishFailed,则此disabled设置为true。
1.当disabled为true时,按钮变为禁用状态。如果disabled属性变为false,按钮再次变为可单击状态。

相关问题