Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable submit button on form #4374

Closed
Themandunord opened this issue Dec 27, 2016 · 20 comments
Closed

Disable submit button on form #4374

Themandunord opened this issue Dec 27, 2016 · 20 comments

Comments

@Themandunord
Copy link

Hi guys,

It is possible to disable the form button when all ForItem are not valided ?
Like react-validation does.

Thanks.

@afc163
Copy link
Member

afc163 commented Dec 28, 2016

It can be done by passing disabled to Button[htmlType="submit"] via React Context. @benjycui

@benjycui
Copy link
Contributor

So.. we need to find Button[htmlType="submit"] recursively? For the structure in Form it's unsure.

@benjycui
Copy link
Contributor

What we need is a handy API to determine whether all Form.Item are not valided

@afc163
Copy link
Member

afc163 commented Dec 28, 2016

Use context and add logic inside Button[htmlType="submit"].

@Themandunord
Copy link
Author

Hi guys,

So if I understand, you'll work on it ?

@afc163
Copy link
Member

afc163 commented Dec 28, 2016

We need a this.props.form.getFields() or this.props.form.getFieldsError().

@benjycui benjycui self-assigned this Jan 3, 2017
@benjycui
Copy link
Contributor

benjycui commented Jan 5, 2017

componentDidMount and then trigger validateFields, if any errors, disabled Button. Because, Form.Item will auto show errors if any, so we need to add a flag to know that whether a field is touched by users. If it's touched, show errors, otherwise, don't show errors. This is also what react-validation do.

To achieve the new target. We need to add this.props.form.getFieldsError(). And we to add field.touched=true flag to mark a field as touched in rc-form, if the value of a form component is changed, so that Form.Item can know whether to show errors.(Also need to expose isTouched)

But the problem is that, rc-form allows developers set initial errors with mapPropsToFields. If we import field.touched, previous codes haven't add this field in mapPropsToFields, then developers will found that errors won't show by Form.Item. This is a little breaking changes.

@benjycui
Copy link
Contributor

benjycui commented Jan 5, 2017

But I think that we can add this feature, thought there is a little breaking changes.

@benjycui
Copy link
Contributor

benjycui commented Jan 5, 2017

rc-form add new feature:

  • this.props.form.getFieldErrors(names?)
  • this.props.form.isFieldTouched(name)
  • this.props.form.isFieldsTouched(names)

@benjycui
Copy link
Contributor

benjycui commented Jan 9, 2017

You can do this thing in antd@2.7 which will be release at the end of this month.

f436b5c#diff-91732ba15efdab445f59d157a9e8ed84

@benjycui benjycui closed this as completed Jan 9, 2017
@Themandunord
Copy link
Author

Thanks @benjycui !
Awesome work 👍

@jch254
Copy link
Contributor

jch254 commented Jan 25, 2017

Thanks @benjycui !!

@neekey
Copy link
Contributor

neekey commented Sep 25, 2017

Hi @benjycui , instead of doing the stuff below manually:

// Only show error after a field is touched.
 +    const userNameError = isFieldTouched('userName') && getFieldError('userName');
 +    const passwordError = isFieldTouched('password') && getFieldError('password');

how about adding an extra prop for form item like showErrorOnlyTouched?

@benjycui
Copy link
Contributor

benjycui commented Sep 25, 2017

how about adding an extra prop for form item like showErrorOnlyTouched?

Nope, it's impossible to integrate all the UX logic in antd's components, so just customize with code.

@neekey
Copy link
Contributor

neekey commented Sep 25, 2017

fair enough.

Anyway, I created an HOC component to implement this, just in case anyone needs it:

import React from 'react';
import PropTypes from 'prop-types';
import { Form } from 'antd';
const FormItem = Form.Item;

export default function EnhancedFormItem(
  { fieldName, showErrorOnlyTouched, neverShowError, ...props }, { form }) {
  if (neverShowError) {
    return (<FormItem
      {...props}
      help=""
      validateStatus="" />);
  }

  if (showErrorOnlyTouched) {
    const { getFieldError, isFieldTouched } = form;
    const isTouched = isFieldTouched(fieldName);
    const fieldError = getFieldError(fieldName);
    const shouldShowError = isTouched && !!fieldError;
    return (<FormItem
      {...props}
      help={shouldShowError ? fieldError : ''}
      validateStatus={shouldShowError ? 'error' : ''} />);
  }
  return <FormItem {...props} />;
}

EnhancedFormItem.propTypes = {
  fieldName: PropTypes.string,
  showErrorOnlyTouched: PropTypes.bool,
  neverShowError: PropTypes.bool,
};

EnhancedFormItem.contextTypes = {
  form: PropTypes.object,
};

@Kamahl19
Copy link
Contributor

Hi @benjycui in the context, there is no form property after upgrading to antd3-rc3, is there any way to access form in the above solution (EnhancedFormItem) except passing it as a prop?

@benjycui
Copy link
Contributor

@Kamahl19
Please provide a re-producible demo: http://codepen.io/benjycui/pen/KgPZrE?editors=001

@ismarslomic
Copy link

ismarslomic commented Jul 4, 2018

@benjycui: Im using ant design with typescript, and demo code at line 47 in f436b5c fails in Typescript with following error message:

Types of property 'validateStatus' are incompatible.
  Type '"error" | ""' is not assignable to type '"error" | "success" | "warning" | "validating" | undefined'.
    Type '""' is not assignable to type '"error" | "success" | "warning" | "validating" | undefined'.

If I use undefined in stead of '' as default value for else-statement then the input fields are marked red when rendering for the first time, which is not wanted. See the behaviour here in CodePen: https://codepen.io/anon/pen/QxPRvM

@BenevidesLecontes
Copy link

Hi @benjycui why isFieldTouched doesn't work like in Angular, when i focus to input for the first time the field stays as untouched, only when i focus out it change to touched and stays as touched. But in ant design forms fields change to touched soon i focus to the field. See this Angular example https://stackblitz.com/angular/pxgvpvqkbymm

@agustif
Copy link

agustif commented Jan 18, 2020

This is somewhat old bbut I found an official example in the login form in the docs to get this

https://ant.design/components/form/#components-form-demo-normal-login

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants