React antd form disable submit button

How could I disable form submit button using antd

Form validations work, but I need to visually disable form submit button when validation fails

React antd form disable submit button

This is a stackblitz url
https://stackblitz.com/edit/react-ts-z5d6tr?file=Hello.tsx

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I found some elegant way to perform this

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

Method 2

I’m going to paste here my solution in case anyone finds it useful.
Note; this solution uses the hook Form.useForm() and the callback onFieldsChange.

The validation is not included in this excerpt. But the idea is that when the form changes (any field) it will set the submit button (in this case inside the Modal) to disabled/enabled.

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

Method 3

I found a nice solution here that doesn’t involve any additional state. If you wrap your submit button in a Form.Item like this, it should disable it until all required fields are completed. The rest of the form would remain the same.

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

Method 4

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;

Method 5

I did some edits here : https://stackblitz.com/edit/react-ts-spuhdd?file=Hello.tsx

Sum up of what I’ve done :

  1. I created hooks username, password and disabled
  2. Everytime the user changes username and password, if these fields are empty, disabled is set as false.
  3. If the onFinishFailed is executed, this disabled is set to true.
  4. When the disabled is at true, the button becomes disabled. If disabled property becomes false, the button becomes clickable again.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x